diff --git a/app/models/comment.rb b/app/models/comment.rb index d4ceb9e3e..696b363ce 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,5 +1,5 @@ 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 validates :body, presence: true @@ -28,4 +28,19 @@ class Comment < ActiveRecord::Base user 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 diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb index 4e375c540..466752044 100644 --- a/app/views/comments/_comment.html.erb +++ b/app/views/comments/_comment.html.erb @@ -14,11 +14,12 @@

- númerototal respuestas - <% if user_signed_in? %> -  |  - <%= render 'comments/form', {parent: comment, toggeable: true} %>

- <% end %> + <%= t("debates.comment.responses", count: comment.children_count) %> + <% if user_signed_in? %> +  |  + <%= render 'comments/form', {parent: comment, toggeable: true} %> + <% end %> +

diff --git a/app/views/comments/_votes.html.erb b/app/views/comments/_votes.html.erb index 4763388b3..73efa56ba 100644 --- a/app/views/comments/_votes.html.erb +++ b/app/views/comments/_votes.html.erb @@ -1,5 +1,6 @@ - númerototal votos + + <%= t('debates.comment.votes', count: comment.total_votes) %>  |  @@ -16,4 +17,4 @@ <% end %> <%= comment.get_dislikes.size %> - \ No newline at end of file + diff --git a/app/views/debates/_debate.html.erb b/app/views/debates/_debate.html.erb index 4620e1232..f8343e8be 100644 --- a/app/views/debates/_debate.html.erb +++ b/app/views/debates/_debate.html.erb @@ -9,7 +9,7 @@

<%= link_to debate.title, debate %>

  - <%= 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") %>

<%= link_to debate.description, debate %> diff --git a/app/views/debates/_votes.html.erb b/app/views/debates/_votes.html.erb index a15a66a4d..4c252c8b5 100644 --- a/app/views/debates/_votes.html.erb +++ b/app/views/debates/_votes.html.erb @@ -18,7 +18,7 @@
- <%= pluralize(debate.total_votes, t("debates.debate.vote"), t("debates.debate.votes")) %> + <%= t("debates.debate.votes", count: debate.total_votes) %> <% unless user_signed_in? %> diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb index 28fefd085..63c2528cd 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -6,7 +6,13 @@
<%= image_tag('user_default.jpg', class: 'author-photo', size: '32x32') %> - <%= @debate.author.name %> •  <%= l @debate.created_at.to_date %>  •  <%= link_to pluralize(@debate.comment_threads.count, t("debates.show.comment"), t("debates.show.comments")), "#comments" %> + + <%= @debate.author.name %> + +  •  + <%= l @debate.created_at.to_date %> +  •  +  <%= link_to t("debates.show.comments", count: @debate.comment_threads.count), "#comments" %>
<%= @debate.description %> @@ -36,7 +42,7 @@
-

<%= t("debates.show.comments") %>

+

<%= t("debates.show.comments_title") %>

<% if user_signed_in? %>
<%= t("debates.show.leave_comment") %> diff --git a/app/views/welcome/_featured_debate.html.erb b/app/views/welcome/_featured_debate.html.erb index fc175fff8..93626b4c7 100644 --- a/app/views/welcome/_featured_debate.html.erb +++ b/app/views/welcome/_featured_debate.html.erb @@ -8,7 +8,7 @@

<%= link_to featured_debate.title, featured_debate %>

  - <%= 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") %>

<%= link_to featured_debate.description, featured_debate %> @@ -25,4 +25,4 @@
-
\ No newline at end of file +
diff --git a/config/locales/en.yml b/config/locales/en.yml index b036f8125..5a60019aa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,10 +19,24 @@ en: create_debate: Create a debate debate: debate: Debate - vote: vote - votes: votes - comment: Comment - comments: Comments + comments: + zero: No comments + one: 1 Comment + 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: error: error errors: errors @@ -36,8 +50,11 @@ en: accept_terms: I accept the privacy policy and the legal terms show: back_link: Back - comment: Comment - comments: Comments + comments_title: Comments + comments: + zero: No comments + one: 1 Comment + other: "%{count} Comments" leave_comment: Write a comment login_to_comment: Log in to participate edit_debate_link: Edit diff --git a/config/locales/es.yml b/config/locales/es.yml index 7995483d4..32fd051c3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -19,10 +19,24 @@ es: create_debate: Crea un debate debate: debate: Debate - vote: voto - votes: votos - comment: Comentario - comments: Comentarios + comments: + zero: Sin comentarios + one: 1 Comentario + 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: error: error errors: errores @@ -36,8 +50,11 @@ es: accept_terms: Acepto la política de privacidad y el aviso legal show: back_link: Volver - comment: Comentario - comments: Comentarios + comments_title: Comentarios + comments: + zero: Sin comentarios + one: 1 Comentario + other: "%{count} Comentarios" leave_comment: Deja tu comentario login_to_comment: Entra para participar edit_debate_link: Editar @@ -108,5 +125,3 @@ es: all: "No tienes permiso para borrar %{subject}" manage: all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}." - - diff --git a/db/migrate/20150811161459_add_children_count_to_comments.rb b/db/migrate/20150811161459_add_children_count_to_comments.rb new file mode 100644 index 000000000..ce233542d --- /dev/null +++ b/db/migrate/20150811161459_add_children_count_to_comments.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 7dd74d450..8fb58776c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # 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 enable_extension "plpgsql" @@ -28,12 +28,13 @@ ActiveRecord::Schema.define(version: 20150808141306) do t.string "title" t.text "body" t.string "subject" - t.integer "user_id", null: false + t.integer "user_id", null: false t.integer "parent_id" t.integer "lft" t.integer "rgt" t.datetime "created_at" t.datetime "updated_at" + t.integer "children_count", default: 0 end add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree diff --git a/spec/factories.rb b/spec/factories.rb index fc76685d0..6bbe3b68b 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -22,15 +22,11 @@ FactoryGirl.define do end factory :comment do - commentable + association :commentable, factory: :debate user body 'Comment body' end - factory :commentable do - debate - end - factory :administrator do user end diff --git a/spec/features/comments_spec.rb b/spec/features/comments_spec.rb index 0cc64bce1..5417bb48a 100644 --- a/spec/features/comments_spec.rb +++ b/spec/features/comments_spec.rb @@ -10,6 +10,7 @@ feature 'Comments' do visit debate_path(debate) expect(page).to have_css('.comment', count: 3) + expect(page).to have_content '3 Comments' comment = Comment.first within first('.comment') do @@ -84,6 +85,11 @@ feature 'Comments' do visit debate_path(debate) 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 diff --git a/spec/features/votes_spec.rb b/spec/features/votes_spec.rb index 8deb20c20..4e713b669 100644 --- a/spec/features/votes_spec.rb +++ b/spec/features/votes_spec.rb @@ -112,7 +112,7 @@ feature 'Votes' do scenario 'Show no votes' do visit debate_path(@debate) - expect(page).to have_content "0 votes" + expect(page).to have_content "No votes" within('.in-favor') do expect(page).to have_content "0%" @@ -236,12 +236,9 @@ feature 'Votes' do expect(page).to have_content "1 vote" end - end - feature 'Comments' do - background do @manuela = create(:user) @pablo = create(:user) @@ -266,6 +263,8 @@ feature 'Votes' do within(".against") do expect(page).to have_content "1" end + + expect(page).to have_content "2 votes" end end @@ -280,6 +279,8 @@ feature 'Votes' do within(".against") do expect(page).to have_content "0" end + + expect(page).to have_content "1 vote" end end @@ -295,6 +296,8 @@ feature 'Votes' do within('.against') do expect(page).to have_content "1" end + + expect(page).to have_content "1 vote" end end @@ -310,8 +313,10 @@ feature 'Votes' do within('.against') do expect(page).to have_content "0" end + + expect(page).to have_content "1 vote" end end end -end \ No newline at end of file +end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 000000000..5af7afc1c --- /dev/null +++ b/spec/models/comment_spec.rb @@ -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 diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index 00f6217bd..187bc0dc1 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -1,88 +1,80 @@ require 'rails_helper' describe Debate do - - before(:each) do - @debate = build(:debate) - end + let(:debate) { build(:debate) } it "should be valid" do - expect(@debate).to be_valid + expect(debate).to be_valid end it "should not be valid without an author" do - @debate.author = nil - expect(@debate).to_not be_valid + debate.author = nil + expect(debate).to_not be_valid end it "should not be valid without a title" do - @debate.title = nil - expect(@debate).to_not be_valid + debate.title = nil + expect(debate).to_not be_valid end describe "#description" do it "should be mandatory" do - @debate.description = nil - expect(@debate).to_not be_valid + debate.description = nil + expect(debate).to_not be_valid end it "should be sanitized" do - @debate.description = "" - @debate.valid? - expect(@debate.description).to eq("alert('danger');") + debate.description = "" + debate.valid? + expect(debate.description).to eq("alert('danger');") end it "should be html_safe" do - @debate.description = "" - expect(@debate.description).to be_html_safe + debate.description = "" + expect(debate.description).to be_html_safe end end it "should sanitize the tag list" do - @debate.tag_list = "user_id=1" - @debate.valid? - expect(@debate.tag_list).to eq(['user_id1']) + debate.tag_list = "user_id=1" + debate.valid? + expect(debate.tag_list).to eq(['user_id1']) end it "should not be valid without accepting terms of service" do - @debate.terms_of_service = nil - expect(@debate).to_not be_valid + debate.terms_of_service = nil + expect(debate).to_not be_valid end describe "#editable?" do - before(:each) do - @debate = create(:debate) - end + let(:debate) { create(:debate) } it "should be true if debate has no votes yet" do - expect(@debate.total_votes).to eq(0) - expect(@debate.editable?).to be true + expect(debate.total_votes).to eq(0) + expect(debate.editable?).to be true end it "should be false if debate has votes" do - create(:vote, votable: @debate) - expect(@debate.total_votes).to eq(1) - expect(@debate.editable?).to be false + create(:vote, votable: debate) + expect(debate.total_votes).to eq(1) + expect(debate.editable?).to be false end end describe "#editable_by?" do - before(:each) do - @debate = create(:debate) - end + let(:debate) { create(:debate) } 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 it "should be false if debate is not editable" do - create(:vote, votable: @debate) - expect(@debate.editable_by?(@debate.author)).to be false + create(:vote, votable: debate) + expect(debate.editable_by?(debate.author)).to be false end 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 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4a8fe8fd7..36444a9c5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -3,24 +3,22 @@ require 'rails_helper' describe User do describe "#votes_on_debates" do - before(:each) do - @user = create(:user) - end + let(:user) { create(:user) } 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([nil, nil])).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({}) end it "returns a hash of debates ids and votes" do debate1 = create(:debate) debate2 = create(:debate) debate3 = create(:debate) - create(:vote, voter: @user, votable: debate1, vote_flag: true) - create(:vote, voter: @user, votable: debate3, vote_flag: false) + create(:vote, voter: user, votable: debate1, vote_flag: true) + 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[debate2.id]).to eq(nil)