diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb index 62def069..0b61f2eb 100644 --- a/app/controllers/comment_controller.rb +++ b/app/controllers/comment_controller.rb @@ -3,8 +3,8 @@ class CommentController < ApplicationController def index answer = Answer.find(params[:id]) - comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + @comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) - render "index", locals: { a: answer, comments: } + render "index", locals: { a: answer } end end diff --git a/app/views/comment/index.html.haml b/app/views/comment/index.html.haml index d13a5cf0..52cad691 100644 --- a/app/views/comment/index.html.haml +++ b/app/views/comment/index.html.haml @@ -1,3 +1,3 @@ = turbo_frame_tag "ab-comments-list-#{a.id}" do %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: - %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: + %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: @comments diff --git a/spec/controllers/comment_controller_spec.rb b/spec/controllers/comment_controller_spec.rb new file mode 100644 index 00000000..ace2aad8 --- /dev/null +++ b/spec/controllers/comment_controller_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe CommentController, type: :controller do + describe "#index" do + shared_examples_for "succeeds" do + it "returns the correct response" do + subject + expect(response).to have_rendered("comment/index") + expect(response).to have_http_status(200) + expect(assigns(:comments)).to eq(comments) + expect(assigns(:comments)).to_not include(unrelated_comment) + end + end + + subject { get :index, params: { username: answer_author.screen_name, id: answer.id } } + + let(:answer_author) { FactoryBot.create(:user) } + let(:answer) { FactoryBot.create(:answer, user: answer_author) } + let(:commenter) { FactoryBot.create(:user) } + let!(:comments) { FactoryBot.create_list(:comment, num_comments, answer:, user: commenter) } + let!(:unrelated_comment) do + FactoryBot.create(:comment, + answer: FactoryBot.create(:answer, user: FactoryBot.create(:user)), + user: commenter,) + end + + [0, 1, 5, 30].each do |num_comments| + context "#{num_comments} comments" do + let(:num_comments) { num_comments } + + include_examples "succeeds" + end + end + end +end diff --git a/spec/views/answerbox/_comments.html.haml_spec.rb b/spec/views/answerbox/_comments.html.haml_spec.rb new file mode 100644 index 00000000..90090069 --- /dev/null +++ b/spec/views/answerbox/_comments.html.haml_spec.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe "answerbox/_comments.html.haml", type: :view do + subject(:rendered) do + render partial: "answerbox/comments", locals: { + comments:, a: + } + end + + let(:a) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) } + let(:comments) { Comment.all } + + context "no comments" do + it "shows an empty list" do + expect(rendered).to eq("There are no comments yet.\n") + end + end + + context "comments are present" do + let!(:expected_comments) { FactoryBot.create_list(:comment, 5, answer: a, user: FactoryBot.create(:user)) } + + it "shows a list of comments" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment .comment__content) + comment_elements = html.css(selector) + expect(comment_elements.size).to eq(5) + expect(comment_elements.map(&:text).map(&:strip)).to eq(expected_comments.map(&:content)) + end + end + + context "containing your own comment" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user:, answer: a) } + + before do + sign_in user + end + + it "shows the delete option" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] .btn-group a[data-action="ab-comment-destroy"]) + element = html.css(selector) + expect(element).to_not be_nil + expect(element.text.strip).to eq("Delete") + end + end + + context "containing someone else's comment" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user: FactoryBot.create(:user), answer: a) } + + before do + sign_in user + end + + it "does not show the delete option" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] .btn-group a[data-action="ab-comment-destroy"]) + expect(html.css(selector)).to be_empty + end + end + + context "containing a comment with smiles" do + let(:comment_author) { FactoryBot.create(:user) } + let(:comment) { FactoryBot.create(:comment, answer: a, user: comment_author) } + let(:other_comment) { FactoryBot.create(:comment, answer: a, user: comment_author) } + + before do + 5.times do + user = FactoryBot.create(:user) + user.smile comment + end + + User.last.smile other_comment + end + + it "shows the correct number of smiles" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] button[data-action="smile"]>span) + expect(html.css(selector).text).to eq("5") + end + end + + context "containing a comment you've smiled" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user: FactoryBot.create(:user), answer: a) } + + before do + sign_in user + user.smile comment + end + + it "displays the comment as smiled" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] button[data-action="unsmile"]) + expect(html.css(selector)).to_not be_empty + end + end +end