From 6c90f2f0dd80bc830bfd9f2b71323fa3594e2460 Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Thu, 19 Jan 2023 10:00:25 +0100 Subject: [PATCH] inbox: add some proper specs --- spec/controllers/inbox_controller_spec.rb | 245 +++++++++++++++++++++- 1 file changed, 244 insertions(+), 1 deletion(-) diff --git a/spec/controllers/inbox_controller_spec.rb b/spec/controllers/inbox_controller_spec.rb index b7426e7b..6cb2e128 100644 --- a/spec/controllers/inbox_controller_spec.rb +++ b/spec/controllers/inbox_controller_spec.rb @@ -6,21 +6,264 @@ describe InboxController, type: :controller do let(:user) { FactoryBot.create(:user) } describe "#show" do + shared_examples_for "sets the expected ivars" do + let(:expected_assigns) { {} } + + it "sets the expected ivars" do + subject + + expected_assigns.each do |name, value| + expect(assigns[name]).to eq(value) + end + end + end + subject { get :show } + it "redirects to the login page when not signed in" do + expect(subject).to redirect_to(new_user_session_path) + end + context "when user is signed in" do before(:each) { sign_in(user) } - it "shows the inbox" do + it "renders the correct template" do subject expect(response).to render_template("show") end + + context "when inbox is empty" do + include_examples "sets the expected ivars", + inbox: [], + inbox_last_id: nil, + more_data_available: false, + inbox_count: 0, + delete_id: "ib-delete-all", + disabled: true + end + + context "when inbox has an amount of questions less than page size" do + let!(:inbox_entry) { Inbox.create(user:, new: true, question: FactoryBot.create(:question)) } + + include_examples "sets the expected ivars" do + let(:expected_assigns) do + { + inbox: [inbox_entry], + inbox_last_id: inbox_entry.id, + more_data_available: false, + inbox_count: 1, + delete_id: "ib-delete-all", + disabled: nil + } + end + end + + context "when requested the turbo stream format" do + subject { get :show, format: :turbo_stream } + + it "updates the inbox entry status" do + expect { subject }.to change { inbox_entry.reload.new? }.from(true).to(false) + end + end + end + + context "when inbox has an amount of questions more than page size" do + let(:inbox_entry_fillers_page1) do + # 9 times => 1 entry less than default page size + 9.times.map { Inbox.create(user:, question: FactoryBot.create(:question)) } + end + let(:last_inbox_entry_page1) { Inbox.create(user:, question: FactoryBot.create(:question)) } + let(:inbox_entry_fillers_page2) do + 5.times.map { Inbox.create(user:, question: FactoryBot.create(:question)) } + end + let(:last_inbox_entry_page2) { Inbox.create(user:, question: FactoryBot.create(:question)) } + + before do + # create inbox entries in reverse so pagination works as expected + last_inbox_entry_page2 + inbox_entry_fillers_page2 + last_inbox_entry_page1 + inbox_entry_fillers_page1 + end + + include_examples "sets the expected ivars" do + let(:expected_assigns) do + { + inbox: [*inbox_entry_fillers_page1.reverse, last_inbox_entry_page1], + inbox_last_id: last_inbox_entry_page1.id, + more_data_available: true, + inbox_count: 16, + delete_id: "ib-delete-all", + disabled: nil + } + end + end + + context "when passed the last_id param" do + subject { get :show, params: { last_id: last_inbox_entry_page1.id } } + + include_examples "sets the expected ivars" do + let(:expected_assigns) do + { + inbox: [*inbox_entry_fillers_page2.reverse, last_inbox_entry_page2], + inbox_last_id: last_inbox_entry_page2.id, + more_data_available: false, + inbox_count: 16, + delete_id: "ib-delete-all", + disabled: nil + } + end + end + end + end + + context "when passed the author param" do + let!(:other_user) { FactoryBot.create(:user) } + let!(:unrelated_user) { FactoryBot.create(:user) } + + let!(:generic_inbox_entry1) do + Inbox.create( + user:, + question: FactoryBot.create( + :question, + user: unrelated_user, + author_is_anonymous: false + ) + ) + end + let!(:generic_inbox_entry2) { Inbox.create(user:, question: FactoryBot.create(:question)) } + + subject { get :show, params: { author: author_param } } + + context "with a nonexisting screen name" do + let(:author_param) { "xXx420MegaGamer2003xXx" } + + it "sets the error flash" do + subject + expect(flash[:error]).to eq "No user with the name @xXx420MegaGamer2003xXx found, showing entries from all users instead!" + end + + include_examples "sets the expected ivars" do + let(:expected_assigns) do + { + inbox: [generic_inbox_entry2, generic_inbox_entry1], + inbox_last_id: generic_inbox_entry1.id, + more_data_available: false, + inbox_count: 2, + delete_id: "ib-delete-all", + disabled: nil + } + end + end + end + + context "with an existing screen name" do + let(:author_param) { other_user.screen_name } + + context "with no questions from the other user in the inbox" do + it { is_expected.to redirect_to inbox_path } + + it "sets the info flash" do + subject + expect(flash[:info]).to eq "No questions from @#{other_user.screen_name} found, showing entries from all users instead!" + end + + include_examples "sets the expected ivars" do + # these are the ivars set before the redirect happened + let(:expected_assigns) do + { + inbox: [], + inbox_last_id: nil, + more_data_available: false, + inbox_count: 0, + delete_id: "ib-delete-all", + disabled: true + } + end + end + end + + context "with no non-anonymous questions from the other user in the inbox" do + let!(:anonymous_inbox_entry) do + Inbox.create( + user:, + question: FactoryBot.create( + :question, + user: other_user, + author_is_anonymous: true + ) + ) + end + + it { is_expected.to redirect_to inbox_path } + + it "sets the info flash" do + subject + expect(flash[:info]).to eq "No questions from @#{other_user.screen_name} found, showing entries from all users instead!" + end + + include_examples "sets the expected ivars" do + # these are the ivars set before the redirect happened + let(:expected_assigns) do + { + inbox: [], + inbox_last_id: nil, + more_data_available: false, + inbox_count: 0, + delete_id: "ib-delete-all", + disabled: true + } + end + end + end + + context "with both non-anonymous and anonymous questions from the other user in the inbox" do + let!(:non_anonymous_inbox_entry) do + Inbox.create( + user:, + question: FactoryBot.create( + :question, + user: other_user, + author_is_anonymous: false + ) + ) + end + let!(:anonymous_inbox_entry) do + Inbox.create( + user:, + question: FactoryBot.create( + :question, + user: other_user, + author_is_anonymous: true + ) + ) + end + + include_examples "sets the expected ivars" do + let(:expected_assigns) do + { + inbox: [non_anonymous_inbox_entry], + inbox_last_id: non_anonymous_inbox_entry.id, + more_data_available: false, + inbox_count: 1, + delete_id: "ib-delete-all-author", + disabled: nil + } + end + end + end + end + end end end describe "#create" do subject { post :create } + it "redirects to the login page when not signed in" do + expect(subject).to redirect_to(new_user_session_path) + end + context "when user is signed in" do before(:each) { sign_in(user) }