Merge pull request #148 from dgilperez/issue-143-new

Incluir número total de respuestas y votos en comentarios - Fix #143
This commit is contained in:
Raimond Garcia
2015-08-12 15:08:09 +02:00
17 changed files with 189 additions and 86 deletions

View File

@@ -1,5 +1,5 @@
class Comment < ActiveRecord::Base class Comment < ActiveRecord::Base
acts_as_nested_set scope: [:commentable_id, :commentable_type] acts_as_nested_set scope: [:commentable_id, :commentable_type], counter_cache: :children_count
acts_as_votable acts_as_votable
validates :body, presence: true validates :body, presence: true
@@ -28,4 +28,19 @@ class Comment < ActiveRecord::Base
user user
end end
def total_votes
votes_for.size
end
# TODO: faking counter cache since there is a bug with acts_as_nested_set :counter_cache
# Remove when https://github.com/collectiveidea/awesome_nested_set/issues/294 is fixed
# and reset counters using
# > Comment.find_each { |comment| Comment.reset_counters(comment.id, :children) }
def children_count
children.count
end
def descendants_count
descendants.count
end
end end

View File

@@ -14,11 +14,12 @@
</span> </span>
<p class="reply"> <p class="reply">
númerototal respuestas <%= t("debates.comment.responses", count: comment.children_count) %>
<% if user_signed_in? %> <% if user_signed_in? %>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<%= render 'comments/form', {parent: comment, toggeable: true} %></p> <%= render 'comments/form', {parent: comment, toggeable: true} %>
<% end %> <% end %>
</p>
</div> </div>
<div class="comment-children"> <div class="comment-children">

View File

@@ -1,5 +1,6 @@
<span> <span>
númerototal votos <!-- <%= t('debates.comment.votes_weighted_score', score: comment.weighted_score) %> -->
<%= t('debates.comment.votes', count: comment.total_votes) %>
</span> </span>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<span class="in_favor"> <span class="in_favor">

View File

@@ -9,7 +9,7 @@
<h3><%= link_to debate.title, debate %></h3> <h3><%= link_to debate.title, debate %></h3>
<p class="debate-info"> <p class="debate-info">
<i class="icon-chat-bubble-two"></i>&nbsp; <i class="icon-chat-bubble-two"></i>&nbsp;
<%= link_to pluralize(debate.comment_threads.count, t("debates.debate.comment"), t("debates.debate.comments")), debate_path(debate, anchor: "comments") %> <%= link_to t("debates.debate.comments", count: debate.comment_threads.count), debate_path(debate, anchor: "comments") %>
</p> </p>
<div class="debate-description"> <div class="debate-description">
<%= link_to debate.description, debate %> <%= link_to debate.description, debate %>

View File

@@ -18,7 +18,7 @@
</div> </div>
<span class="total-votes"> <span class="total-votes">
<%= pluralize(debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %> <%= t("debates.debate.votes", count: debate.total_votes) %>
</span> </span>
<% unless user_signed_in? %> <% unless user_signed_in? %>

View File

@@ -6,7 +6,13 @@
<div class="debate-info"> <div class="debate-info">
<%= image_tag('user_default.jpg', class: 'author-photo', size: '32x32') %> <%= image_tag('user_default.jpg', class: 'author-photo', size: '32x32') %>
<span class="author"><%= @debate.author.name %></span><span class="bullet">&nbsp;&bullet;&nbsp;</span> <%= l @debate.created_at.to_date %> <span class="bullet">&nbsp;&bullet;&nbsp;</span><i class="icon-chat-bubble-two"></i>&nbsp;<%= link_to pluralize(@debate.comment_threads.count, t("debates.show.comment"), t("debates.show.comments")), "#comments" %> <span class="author">
<%= @debate.author.name %>
</span>
<span class="bullet">&nbsp;&bullet;&nbsp;</span>
<%= l @debate.created_at.to_date %>
<span class="bullet">&nbsp;&bullet;&nbsp;</span>
<i class="icon-chat-bubble-two"></i>&nbsp;<%= link_to t("debates.show.comments", count: @debate.comment_threads.count), "#comments" %>
</div> </div>
<%= @debate.description %> <%= @debate.description %>
@@ -36,7 +42,7 @@
<section class="row-full comments"> <section class="row-full comments">
<div class="row"> <div class="row">
<div id="comments" class="small-12 column"> <div id="comments" class="small-12 column">
<h2><%= t("debates.show.comments") %></h2> <h2><%= t("debates.show.comments_title") %></h2>
<% if user_signed_in? %> <% if user_signed_in? %>
<div> <div>
<%= t("debates.show.leave_comment") %> <%= t("debates.show.leave_comment") %>

View File

@@ -8,7 +8,7 @@
<h3><%= link_to featured_debate.title, featured_debate %></h3> <h3><%= link_to featured_debate.title, featured_debate %></h3>
<p class="debate-info"> <p class="debate-info">
<i class="icon-chat-bubble-two"></i>&nbsp; <i class="icon-chat-bubble-two"></i>&nbsp;
<%= link_to pluralize(featured_debate.comment_threads.count, t("debates.show.comment"), t("debates.show.comments")), debate_path(featured_debate, anchor: "comments") %> <%= link_to t("debates.show.comments", count: featured_debate.comment_threads.count), debate_path(featured_debate, anchor: "comments") %>
</p> </p>
<div class="debate-description"> <div class="debate-description">
<%= link_to featured_debate.description, featured_debate %> <%= link_to featured_debate.description, featured_debate %>

View File

@@ -19,10 +19,24 @@ en:
create_debate: Create a debate create_debate: Create a debate
debate: debate:
debate: Debate debate: Debate
vote: vote comments:
votes: votes zero: No comments
comment: Comment one: 1 Comment
comments: Comments other: "%{count} Comments"
votes:
zero: No votes
one: 1 vote
other: "%{count} votes"
comment:
responses:
zero: No Responses
one: 1 Response
other: "%{count} Responses"
votes:
zero: No votes
one: 1 vote
other: "%{count} votes"
votes_weighted_score: "Total: %{score}"
form: form:
error: error error: error
errors: errors errors: errors
@@ -36,8 +50,11 @@ en:
accept_terms: I accept the privacy policy and the legal terms accept_terms: I accept the privacy policy and the legal terms
show: show:
back_link: Back back_link: Back
comment: Comment comments_title: Comments
comments: Comments comments:
zero: No comments
one: 1 Comment
other: "%{count} Comments"
leave_comment: Write a comment leave_comment: Write a comment
login_to_comment: Log in to participate login_to_comment: Log in to participate
edit_debate_link: Edit edit_debate_link: Edit

View File

@@ -19,10 +19,24 @@ es:
create_debate: Crea un debate create_debate: Crea un debate
debate: debate:
debate: Debate debate: Debate
vote: voto comments:
votes: votos zero: Sin comentarios
comment: Comentario one: 1 Comentario
comments: Comentarios other: "%{count} Comentarios"
votes:
zero: Sin votos
one: 1 voto
other: "%{count} votos"
comment:
responses:
zero: Sin respuestas
one: 1 Respuesta
other: "%{count} Respuestas"
votes:
zero: Sin votos
one: 1 voto
other: "%{count} votos"
votes_weighted_score: "Total: %{score}"
form: form:
error: error error: error
errors: errores errors: errores
@@ -36,8 +50,11 @@ es:
accept_terms: Acepto la política de privacidad y el aviso legal accept_terms: Acepto la política de privacidad y el aviso legal
show: show:
back_link: Volver back_link: Volver
comment: Comentario comments_title: Comentarios
comments: Comentarios comments:
zero: Sin comentarios
one: 1 Comentario
other: "%{count} Comentarios"
leave_comment: Deja tu comentario leave_comment: Deja tu comentario
login_to_comment: Entra para participar login_to_comment: Entra para participar
edit_debate_link: Editar edit_debate_link: Editar
@@ -108,5 +125,3 @@ es:
all: "No tienes permiso para borrar %{subject}" all: "No tienes permiso para borrar %{subject}"
manage: manage:
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}." all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."

View File

@@ -0,0 +1,9 @@
class AddChildrenCountToComments < ActiveRecord::Migration
def up
add_column :comments, :children_count, :integer, default: 0
end
def down
remove_column :comments, :children_count
end
end

View File

@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150808141306) do ActiveRecord::Schema.define(version: 20150811161459) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -28,12 +28,13 @@ ActiveRecord::Schema.define(version: 20150808141306) do
t.string "title" t.string "title"
t.text "body" t.text "body"
t.string "subject" t.string "subject"
t.integer "user_id", null: false t.integer "user_id", null: false
t.integer "parent_id" t.integer "parent_id"
t.integer "lft" t.integer "lft"
t.integer "rgt" t.integer "rgt"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "children_count", default: 0
end end
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree

View File

@@ -22,15 +22,11 @@ FactoryGirl.define do
end end
factory :comment do factory :comment do
commentable association :commentable, factory: :debate
user user
body 'Comment body' body 'Comment body'
end end
factory :commentable do
debate
end
factory :administrator do factory :administrator do
user user
end end

View File

@@ -10,6 +10,7 @@ feature 'Comments' do
visit debate_path(debate) visit debate_path(debate)
expect(page).to have_css('.comment', count: 3) expect(page).to have_css('.comment', count: 3)
expect(page).to have_content '3 Comments'
comment = Comment.first comment = Comment.first
within first('.comment') do within first('.comment') do
@@ -84,6 +85,11 @@ feature 'Comments' do
visit debate_path(debate) visit debate_path(debate)
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment") expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
expect(page).to have_content '8 Comments'
within first('.comment') do
expect(page).to have_content '1 Response'
end
end end
end end

View File

@@ -112,7 +112,7 @@ feature 'Votes' do
scenario 'Show no votes' do scenario 'Show no votes' do
visit debate_path(@debate) visit debate_path(@debate)
expect(page).to have_content "0 votes" expect(page).to have_content "No votes"
within('.in-favor') do within('.in-favor') do
expect(page).to have_content "0%" expect(page).to have_content "0%"
@@ -236,12 +236,9 @@ feature 'Votes' do
expect(page).to have_content "1 vote" expect(page).to have_content "1 vote"
end end
end end
feature 'Comments' do feature 'Comments' do
background do background do
@manuela = create(:user) @manuela = create(:user)
@pablo = create(:user) @pablo = create(:user)
@@ -266,6 +263,8 @@ feature 'Votes' do
within(".against") do within(".against") do
expect(page).to have_content "1" expect(page).to have_content "1"
end end
expect(page).to have_content "2 votes"
end end
end end
@@ -280,6 +279,8 @@ feature 'Votes' do
within(".against") do within(".against") do
expect(page).to have_content "0" expect(page).to have_content "0"
end end
expect(page).to have_content "1 vote"
end end
end end
@@ -295,6 +296,8 @@ feature 'Votes' do
within('.against') do within('.against') do
expect(page).to have_content "1" expect(page).to have_content "1"
end end
expect(page).to have_content "1 vote"
end end
end end
@@ -310,6 +313,8 @@ feature 'Votes' do
within('.against') do within('.against') do
expect(page).to have_content "0" expect(page).to have_content "0"
end end
expect(page).to have_content "1 vote"
end end
end end

View File

@@ -0,0 +1,41 @@
require 'rails_helper'
describe Comment do
let(:comment) { build(:comment) }
it "should be valid" do
expect(comment).to be_valid
end
describe "#children_count" do
let(:comment) { create(:comment) }
let(:debate) { comment.debate }
it "should count first level children" do
parent = comment
3.times do
create(:comment, commentable: debate).
move_to_child_of(parent)
parent = parent.children.first
end
expect(comment.children_count).to eq(1)
expect(debate.comment_threads.count).to eq(4)
end
it "should increase children count" do
expect do
create(:comment, commentable: debate).
move_to_child_of(comment)
end.to change { comment.children_count }.from(0).to(1)
end
it "should decrease children count" do
new_comment = create(:comment, commentable: debate).move_to_child_of(comment)
expect { new_comment.destroy }.to change { comment.children_count }.from(1).to(0)
end
end
end

View File

@@ -1,88 +1,80 @@
require 'rails_helper' require 'rails_helper'
describe Debate do describe Debate do
let(:debate) { build(:debate) }
before(:each) do
@debate = build(:debate)
end
it "should be valid" do it "should be valid" do
expect(@debate).to be_valid expect(debate).to be_valid
end end
it "should not be valid without an author" do it "should not be valid without an author" do
@debate.author = nil debate.author = nil
expect(@debate).to_not be_valid expect(debate).to_not be_valid
end end
it "should not be valid without a title" do it "should not be valid without a title" do
@debate.title = nil debate.title = nil
expect(@debate).to_not be_valid expect(debate).to_not be_valid
end end
describe "#description" do describe "#description" do
it "should be mandatory" do it "should be mandatory" do
@debate.description = nil debate.description = nil
expect(@debate).to_not be_valid expect(debate).to_not be_valid
end end
it "should be sanitized" do it "should be sanitized" do
@debate.description = "<script>alert('danger');</script>" debate.description = "<script>alert('danger');</script>"
@debate.valid? debate.valid?
expect(@debate.description).to eq("alert('danger');") expect(debate.description).to eq("alert('danger');")
end end
it "should be html_safe" do it "should be html_safe" do
@debate.description = "<script>alert('danger');</script>" debate.description = "<script>alert('danger');</script>"
expect(@debate.description).to be_html_safe expect(debate.description).to be_html_safe
end end
end end
it "should sanitize the tag list" do it "should sanitize the tag list" do
@debate.tag_list = "user_id=1" debate.tag_list = "user_id=1"
@debate.valid? debate.valid?
expect(@debate.tag_list).to eq(['user_id1']) expect(debate.tag_list).to eq(['user_id1'])
end end
it "should not be valid without accepting terms of service" do it "should not be valid without accepting terms of service" do
@debate.terms_of_service = nil debate.terms_of_service = nil
expect(@debate).to_not be_valid expect(debate).to_not be_valid
end end
describe "#editable?" do describe "#editable?" do
before(:each) do let(:debate) { create(:debate) }
@debate = create(:debate)
end
it "should be true if debate has no votes yet" do it "should be true if debate has no votes yet" do
expect(@debate.total_votes).to eq(0) expect(debate.total_votes).to eq(0)
expect(@debate.editable?).to be true expect(debate.editable?).to be true
end end
it "should be false if debate has votes" do it "should be false if debate has votes" do
create(:vote, votable: @debate) create(:vote, votable: debate)
expect(@debate.total_votes).to eq(1) expect(debate.total_votes).to eq(1)
expect(@debate.editable?).to be false expect(debate.editable?).to be false
end end
end end
describe "#editable_by?" do describe "#editable_by?" do
before(:each) do let(:debate) { create(:debate) }
@debate = create(:debate)
end
it "should be true if user is the author and debate is editable" do it "should be true if user is the author and debate is editable" do
expect(@debate.editable_by?(@debate.author)).to be true expect(debate.editable_by?(debate.author)).to be true
end end
it "should be false if debate is not editable" do it "should be false if debate is not editable" do
create(:vote, votable: @debate) create(:vote, votable: debate)
expect(@debate.editable_by?(@debate.author)).to be false expect(debate.editable_by?(debate.author)).to be false
end end
it "should be false if user is not the author" do it "should be false if user is not the author" do
expect(@debate.editable_by?(create(:user))).to be false expect(debate.editable_by?(create(:user))).to be false
end end
end end

View File

@@ -3,24 +3,22 @@ require 'rails_helper'
describe User do describe User do
describe "#votes_on_debates" do describe "#votes_on_debates" do
before(:each) do let(:user) { create(:user) }
@user = create(:user)
end
it "returns {} if no debate" do it "returns {} if no debate" do
expect(@user.votes_on_debates()).to eq({}) expect(user.votes_on_debates()).to eq({})
expect(@user.votes_on_debates([])).to eq({}) expect(user.votes_on_debates([])).to eq({})
expect(@user.votes_on_debates([nil, nil])).to eq({}) expect(user.votes_on_debates([nil, nil])).to eq({})
end end
it "returns a hash of debates ids and votes" do it "returns a hash of debates ids and votes" do
debate1 = create(:debate) debate1 = create(:debate)
debate2 = create(:debate) debate2 = create(:debate)
debate3 = create(:debate) debate3 = create(:debate)
create(:vote, voter: @user, votable: debate1, vote_flag: true) create(:vote, voter: user, votable: debate1, vote_flag: true)
create(:vote, voter: @user, votable: debate3, vote_flag: false) create(:vote, voter: user, votable: debate3, vote_flag: false)
voted = @user.votes_on_debates([debate1.id, debate2.id, debate3.id]) voted = user.votes_on_debates([debate1.id, debate2.id, debate3.id])
expect(voted[debate1.id]).to eq(true) expect(voted[debate1.id]).to eq(true)
expect(voted[debate2.id]).to eq(nil) expect(voted[debate2.id]).to eq(nil)