require "rails_helper" describe Comment do let(:comment) { build(:comment) } it_behaves_like "has_public_author" it_behaves_like "globalizable", :comment it_behaves_like "acts as paranoid", :comment it "is valid" do expect(comment).to be_valid end it "dynamically validates the commentable types" do stub_const("#{Comment}::COMMENTABLE_TYPES", %w[Debate]) expect(build(:comment, commentable: create(:debate))).to be_valid expect(build(:comment, commentable: create(:proposal))).not_to be_valid end it "updates cache_counter in debate after hide and restore" do debate = create(:debate) comment = create(:comment, commentable: debate) expect(debate.reload.comments_count).to eq(1) comment.hide expect(debate.reload.comments_count).to eq(0) comment.restore expect(debate.reload.comments_count).to eq(1) end describe "#as_administrator?" do it "is true if comment has administrator_id, false otherway" do expect(comment).not_to be_as_administrator comment.administrator_id = 33 expect(comment).to be_as_administrator end end describe "#as_moderator?" do it "is true if comment has moderator_id, false otherway" do expect(comment).not_to be_as_moderator comment.moderator_id = 21 expect(comment).to be_as_moderator end end describe "#confidence_score" do it "takes into account percentage of total votes and total_positive and total negative votes" do comment = create(:comment, :with_confidence_score, cached_votes_up: 100, cached_votes_total: 100) expect(comment.confidence_score).to eq(10000) comment = create(:comment, :with_confidence_score, cached_votes_up: 0, cached_votes_total: 100) expect(comment.confidence_score).to eq(0) comment = create(:comment, :with_confidence_score, cached_votes_up: 75, cached_votes_total: 100) expect(comment.confidence_score).to eq(3750) comment = create(:comment, :with_confidence_score, cached_votes_up: 750, cached_votes_total: 1000) expect(comment.confidence_score).to eq(37500) comment = create(:comment, :with_confidence_score, cached_votes_up: 10, cached_votes_total: 100) expect(comment.confidence_score).to eq(-800) comment = create(:comment, :with_confidence_score, cached_votes_up: 0, cached_votes_total: 0) expect(comment.confidence_score).to eq(1) end describe "actions which affect it" do let(:comment) { create(:comment, :with_confidence_score) } it "increases with like" do previous = comment.confidence_score 5.times { comment.vote_by(voter: create(:user), vote: true) } expect(previous).to be < comment.confidence_score end it "decreases with dislikes" do comment.vote_by(voter: create(:user), vote: true) previous = comment.confidence_score 3.times { comment.vote_by(voter: create(:user), vote: false) } expect(previous).to be > comment.confidence_score end end end describe "cache" do let(:comment) { create(:comment) } it "expires cache when it has a new vote" do expect { create(:vote, votable: comment) }.to change { comment.cache_version } end it "expires cache when hidden" do expect { comment.hide }.to change { comment.cache_version } end it "expires cache when the author is hidden" do expect { comment.user.hide } .to change { [comment.reload.cache_version, comment.author.cache_version] } end it "expires cache when the author is erased" do expect { comment.user.erase } .to change { [comment.reload.cache_version, comment.author.cache_version] } end it "expires cache when the author changes" do expect { comment.user.update(username: "Isabel") } .to change { [comment.reload.cache_version, comment.author.cache_version] } end it "expires cache when the author's organization get verified" do create(:organization, user: comment.user) expect { comment.user.organization.verify } .to change { [comment.reload.cache_version, comment.author.cache_version] } end end describe "#author_id?" do it "returns the user's id" do expect(comment.author_id).to eq(comment.user.id) end end describe "not_as_admin_or_moderator" do it "returns only comments posted as regular user" do comment1 = create(:comment) create(:comment, administrator_id: create(:administrator).id) create(:comment, moderator_id: create(:moderator).id) expect(Comment.not_as_admin_or_moderator).to eq [comment1] end end describe "public_for_api scope" do it "returns comments" do comment = create(:comment) expect(Comment.public_for_api).to eq [comment] end it "does not return hidden comments" do create(:comment, :hidden) expect(Comment.public_for_api).to be_empty end it "returns comments on debates" do comment = create(:comment, commentable: create(:debate)) expect(Comment.public_for_api).to eq [comment] end it "does not return comments on hidden debates" do create(:comment, commentable: create(:debate, :hidden)) expect(Comment.public_for_api).to be_empty end it "returns comments on proposals" do proposal = create(:proposal) comment = create(:comment, commentable: proposal) expect(Comment.public_for_api).to eq [comment] end it "does not return comments on hidden proposals" do create(:comment, commentable: create(:proposal, :hidden)) expect(Comment.public_for_api).to be_empty end it "returns comments on budget investments" do comment = create(:comment, commentable: create(:budget_investment)) expect(Comment.public_for_api).to eq [comment] end it "does not return comments on elements which are not debates, proposals or budget investments" do create(:comment, commentable: create(:topic)) expect(Comment.public_for_api).to be_empty end it "does not return comments with no commentable" do build(:comment, commentable: nil).save!(validate: false) expect(Comment.public_for_api).to be_empty end it "does not return internal valuation comments" do create(:comment, :valuation) expect(Comment.public_for_api).to be_empty end end describe ".search" do it "searches by body" do comment = create(:comment, body: "I agree") expect(Comment.search("agree")).to eq([comment]) end it "searches by commentable title" do proposal = create(:proposal, title: "More wood!") comment = create(:comment, body: "I agree", commentable: proposal) expect(Comment.search("wood")).to eq([comment]) end it "does not return non-matching records" do create(:comment, body: "I agree") expect(Comment.search("disagree")).to be_empty end end end