diff --git a/Gemfile.lock b/Gemfile.lock index 958bfb6056d..ed44c90dd22 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -191,6 +191,7 @@ GEM simpleidn (~> 0.2) jwt (2.7.1) kgio (2.11.4) + language_server-protocol (3.17.0.3) libv8-node (18.16.0.0) libv8-node (18.16.0.0-aarch64-linux) libv8-node (18.16.0.0-arm64-darwin) @@ -409,8 +410,9 @@ GEM rspec-core (>= 2.14) rtlcss (0.2.1) mini_racer (>= 0.6.3) - rubocop (1.52.1) + rubocop (1.53.0) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.2.2.3) rainbow (>= 2.2.2, < 4.0) @@ -423,7 +425,7 @@ GEM parser (>= 3.2.1.0) rubocop-capybara (2.18.0) rubocop (~> 1.41) - rubocop-discourse (3.2.0) + rubocop-discourse (3.3.0) rubocop (>= 1.1.0) rubocop-rspec (>= 2.0.0) rubocop-factory_bot (2.23.1) diff --git a/plugins/chat/spec/jobs/regular/chat/auto_join_channel_batch_spec.rb b/plugins/chat/spec/jobs/regular/chat/auto_join_channel_batch_spec.rb index 9ccb28332c8..b1ed2bdea9f 100644 --- a/plugins/chat/spec/jobs/regular/chat/auto_join_channel_batch_spec.rb +++ b/plugins/chat/spec/jobs/regular/chat/auto_join_channel_batch_spec.rb @@ -3,13 +3,15 @@ require "rails_helper" describe Jobs::Chat::AutoJoinChannelBatch do + subject(:job) { described_class.new } + describe "#execute" do fab!(:category) { Fabricate(:category) } let!(:user) { Fabricate(:user, last_seen_at: 15.minutes.ago) } let(:channel) { Fabricate(:chat_channel, auto_join_users: true, chatable: category) } it "joins all valid users in the batch" do - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_users_follows_channel(channel, [user]) end @@ -17,7 +19,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "doesn't join users outside the batch" do another_user = Fabricate(:user, last_seen_at: 15.minutes.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_users_follows_channel(channel, [user]) assert_user_skipped(channel, another_user) @@ -26,7 +28,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "doesn't join suspended users" do user.update!(suspended_till: 1.year.from_now) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_user_skipped(channel, user) end @@ -34,7 +36,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "doesn't join users last_seen more than 3 months ago" do user.update!(last_seen_at: 4.months.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_user_skipped(channel, user) end @@ -42,13 +44,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "joins users with last_seen set to null" do user.update!(last_seen_at: nil) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_users_follows_channel(channel, [user]) end it "does nothing if the channel is invalid" do - subject.execute(chat_channel_id: -1, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: -1, starts_at: user.id, ends_at: user.id) assert_user_skipped(channel, user) end @@ -57,13 +59,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do direct_message = Fabricate(:direct_message) channel.update!(chatable: direct_message) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_user_skipped(channel, user) end it "enqueues the user count update job and marks the channel user count as stale" do - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) expect_job_enqueued( job: Jobs::Chat::UpdateChannelUserCount, args: { @@ -81,7 +83,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do args: { chat_channel_id: channel.id, }, - ) { subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) } + ) { job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) } expect(channel.reload.user_count_stale).to eq(false) end @@ -89,13 +91,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "ignores users without chat_enabled" do user.user_option.update!(chat_enabled: false) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_user_skipped(channel, user) end it "sets the join reason to automatic" do - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) new_membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel) expect(new_membership.automatic?).to eq(true) @@ -104,7 +106,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "skips anonymous users" do user_2 = Fabricate(:anonymous) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) assert_users_follows_channel(channel, [user]) assert_user_skipped(channel, user_2) @@ -113,7 +115,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "skips non-active users" do user_2 = Fabricate(:user, active: false, last_seen_at: 15.minutes.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) assert_users_follows_channel(channel, [user]) assert_user_skipped(channel, user_2) @@ -122,7 +124,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "skips staged users" do user_2 = Fabricate(:user, staged: true, last_seen_at: 15.minutes.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) assert_users_follows_channel(channel, [user]) assert_user_skipped(channel, user_2) @@ -131,7 +133,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "adds every user in the batch" do user_2 = Fabricate(:user, last_seen_at: 15.minutes.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user_2.id) assert_users_follows_channel(channel, [user, user_2]) end @@ -139,7 +141,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "publishes a message only to joined users" do messages = MessageBus.track_publish("/chat/new-channel") do - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) end expect(messages.size).to eq(1) @@ -156,7 +158,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do it "only joins group members with access to the category" do another_user = Fabricate(:user, last_seen_at: 15.minutes.ago) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: another_user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: another_user.id) assert_users_follows_channel(channel, [user]) assert_user_skipped(channel, another_user) @@ -167,7 +169,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do Fabricate(:category_group, category: category, group: second_chatters_group) second_chatters_group.add(user) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: user.id) assert_users_follows_channel(channel, [user]) end @@ -176,7 +178,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do another_user = Fabricate(:user, last_seen_at: 15.minutes.ago) chatters_group.add(another_user) - subject.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: another_user.id) + job.execute(chat_channel_id: channel.id, starts_at: user.id, ends_at: another_user.id) assert_users_follows_channel(channel, [user, another_user]) end @@ -195,7 +197,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do ) non_chatters_group.add(another_user) - subject.execute( + job.execute( chat_channel_id: readonly_channel.id, starts_at: another_user.id, ends_at: another_user.id, @@ -227,7 +229,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do ) other_group.add(another_user) - subject.execute( + job.execute( chat_channel_id: private_channel.id, starts_at: another_user.id, ends_at: another_user.id, diff --git a/plugins/chat/spec/jobs/regular/chat/delete_user_messages_spec.rb b/plugins/chat/spec/jobs/regular/chat/delete_user_messages_spec.rb index 224d382a3c5..1cb3f1c8da3 100644 --- a/plugins/chat/spec/jobs/regular/chat/delete_user_messages_spec.rb +++ b/plugins/chat/spec/jobs/regular/chat/delete_user_messages_spec.rb @@ -2,12 +2,14 @@ RSpec.describe Jobs::Chat::DeleteUserMessages do describe "#execute" do + subject(:execute) { described_class.new.execute(user_id: user_1) } + fab!(:user_1) { Fabricate(:user) } fab!(:channel) { Fabricate(:chat_channel) } fab!(:chat_message) { Fabricate(:chat_message, chat_channel: channel, user: user_1) } it "deletes messages from the user" do - subject.execute(user_id: user_1) + execute expect { chat_message.reload }.to raise_error(ActiveRecord::RecordNotFound) end @@ -16,7 +18,7 @@ RSpec.describe Jobs::Chat::DeleteUserMessages do user_2 = Fabricate(:user) user_2_message = Fabricate(:chat_message, chat_channel: channel, user: user_2) - subject.execute(user_id: user_1) + execute expect(user_2_message.reload).to be_present end @@ -24,7 +26,7 @@ RSpec.describe Jobs::Chat::DeleteUserMessages do it "deletes trashed messages" do chat_message.trash! - subject.execute(user_id: user_1) + execute expect(Chat::Message.with_deleted.where(id: chat_message.id)).to be_empty end diff --git a/plugins/chat/spec/jobs/regular/chat/notify_mentioned_spec.rb b/plugins/chat/spec/jobs/regular/chat/notify_mentioned_spec.rb index 7ac9d674613..db432fbdcda 100644 --- a/plugins/chat/spec/jobs/regular/chat/notify_mentioned_spec.rb +++ b/plugins/chat/spec/jobs/regular/chat/notify_mentioned_spec.rb @@ -3,6 +3,8 @@ require "rails_helper" describe Jobs::Chat::NotifyMentioned do + subject(:job) { described_class.new } + fab!(:user_1) { Fabricate(:user) } fab!(:user_2) { Fabricate(:user) } fab!(:public_channel) { Fabricate(:category_channel) } @@ -47,7 +49,7 @@ describe Jobs::Chat::NotifyMentioned do ) MessageBus .track_publish("/chat/notification-alert/#{user.id}") do - subject.execute( + job.execute( chat_message_id: message.id, timestamp: message.created_at, to_notify_ids_map: to_notify_ids_map, @@ -58,7 +60,7 @@ describe Jobs::Chat::NotifyMentioned do end def track_core_notification(user: user_2, message:, to_notify_ids_map:) - subject.execute( + job.execute( chat_message_id: message.id, timestamp: message.created_at, to_notify_ids_map: to_notify_ids_map, @@ -175,7 +177,7 @@ describe Jobs::Chat::NotifyMentioned do PostAlerter.expects(:push_notification).never - subject.execute( + job.execute( chat_message_id: message.id, timestamp: message.created_at, to_notify_ids_map: to_notify_ids_map, @@ -204,7 +206,7 @@ describe Jobs::Chat::NotifyMentioned do PostAlerter.expects(:push_notification).never - subject.execute( + job.execute( chat_message_id: message.id, timestamp: message.created_at, to_notify_ids_map: to_notify_ids_map, @@ -248,7 +250,7 @@ describe Jobs::Chat::NotifyMentioned do }, ) - subject.execute( + job.execute( chat_message_id: message.id, timestamp: message.created_at, to_notify_ids_map: to_notify_ids_map, diff --git a/plugins/chat/spec/jobs/regular/chat/send_message_notifications_spec.rb b/plugins/chat/spec/jobs/regular/chat/send_message_notifications_spec.rb index 2739339fc35..93d395da9ac 100644 --- a/plugins/chat/spec/jobs/regular/chat/send_message_notifications_spec.rb +++ b/plugins/chat/spec/jobs/regular/chat/send_message_notifications_spec.rb @@ -1,13 +1,15 @@ # frozen_string_literal: true RSpec.describe Jobs::Chat::SendMessageNotifications do + subject(:job) { described_class.new } + describe "#execute" do context "when the message doesn't exist" do it "does nothing" do Chat::Notifier.any_instance.expects(:notify_new).never Chat::Notifier.any_instance.expects(:notify_edit).never - subject.execute(eason: "new", timestamp: 1.minute.ago) + job.execute(reason: "new", timestamp: 1.minute.ago) end end @@ -18,32 +20,28 @@ RSpec.describe Jobs::Chat::SendMessageNotifications do Chat::Notifier.expects(:notify_new).never Chat::Notifier.expects(:notify_edit).never - subject.execute( - chat_message_id: chat_message.id, - reason: "invalid", - timestamp: 1.minute.ago, - ) + job.execute(chat_message_id: chat_message.id, reason: "invalid", timestamp: 1.minute.ago) end it "does nothing if there is no timestamp" do Chat::Notifier.any_instance.expects(:notify_new).never Chat::Notifier.any_instance.expects(:notify_edit).never - subject.execute(chat_message_id: chat_message.id, reason: "new") + job.execute(chat_message_id: chat_message.id, reason: "new") end it "calls notify_new when the reason is 'new'" do Chat::Notifier.any_instance.expects(:notify_new).once Chat::Notifier.any_instance.expects(:notify_edit).never - subject.execute(chat_message_id: chat_message.id, reason: "new", timestamp: 1.minute.ago) + job.execute(chat_message_id: chat_message.id, reason: "new", timestamp: 1.minute.ago) end it "calls notify_edit when the reason is 'edit'" do Chat::Notifier.any_instance.expects(:notify_new).never Chat::Notifier.any_instance.expects(:notify_edit).once - subject.execute(chat_message_id: chat_message.id, reason: "edit", timestamp: 1.minute.ago) + job.execute(chat_message_id: chat_message.id, reason: "edit", timestamp: 1.minute.ago) end end end diff --git a/plugins/chat/spec/jobs/scheduled/auto_join_users_spec.rb b/plugins/chat/spec/jobs/scheduled/auto_join_users_spec.rb index 1807f0e74d5..4abbdc37405 100644 --- a/plugins/chat/spec/jobs/scheduled/auto_join_users_spec.rb +++ b/plugins/chat/spec/jobs/scheduled/auto_join_users_spec.rb @@ -3,6 +3,8 @@ require "rails_helper" describe Jobs::Chat::AutoJoinUsers do + subject(:job) { described_class.new } + it "works" do Jobs.run_immediately! channel = Fabricate(:category_channel, auto_join_users: true) @@ -11,7 +13,7 @@ describe Jobs::Chat::AutoJoinUsers do membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel) expect(membership).to be_nil - subject.execute({}) + job.execute({}) membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel) expect(membership.following).to eq(true) diff --git a/plugins/chat/spec/lib/chat/channel_archive_service_spec.rb b/plugins/chat/spec/lib/chat/channel_archive_service_spec.rb index 8db6a804fc3..1911e2fa3c6 100644 --- a/plugins/chat/spec/lib/chat/channel_archive_service_spec.rb +++ b/plugins/chat/spec/lib/chat/channel_archive_service_spec.rb @@ -9,8 +9,8 @@ describe Chat::ChannelArchiveService do fab!(:channel) { Fabricate(:category_channel) } fab!(:user) { Fabricate(:user, admin: true) } fab!(:category) { Fabricate(:category) } + let(:topic_params) { { topic_title: "This will be a new topic", category_id: category.id } } - subject { Chat::ChannelArchiveService } before { SiteSetting.chat_enabled = true } @@ -18,7 +18,7 @@ describe Chat::ChannelArchiveService do before { 3.times { Fabricate(:chat_message, chat_channel: channel) } } it "marks the channel as read_only" do - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -27,7 +27,7 @@ describe Chat::ChannelArchiveService do end it "creates the chat channel archive record to save progress and topic params" do - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -42,7 +42,7 @@ describe Chat::ChannelArchiveService do it "enqueues the archive job" do channel_archive = - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -58,13 +58,13 @@ describe Chat::ChannelArchiveService do end it "does nothing if there is already an archive record for the channel" do - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, ) expect { - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -76,7 +76,7 @@ describe Chat::ChannelArchiveService do new_message = Fabricate(:chat_message, chat_channel: channel) new_message.trash! channel_archive = - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -92,7 +92,7 @@ describe Chat::ChannelArchiveService do def start_archive @channel_archive = - subject.create_archive_process( + described_class.create_archive_process( chat_channel: channel, acting_user: user, topic_params: topic_params, @@ -113,7 +113,7 @@ describe Chat::ChannelArchiveService do emoji: "+1", ) stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute end @channel_archive.reload @@ -146,21 +146,21 @@ describe Chat::ChannelArchiveService do it "does not stop the process if the post length is too high (validations disabled)" do create_messages(50) && start_archive SiteSetting.max_post_length = 1 - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) end it "successfully links uploads from messages to the post" do create_messages(3) && start_archive UploadReference.create!(target: Chat::Message.last, upload: Fabricate(:upload)) - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) expect(@channel_archive.destination_topic.posts.last.upload_references.count).to eq(1) end it "successfully sends a private message to the archiving user" do create_messages(3) && start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) pm_topic = Topic.private_messages.last expect(pm_topic.topic_allowed_users.first.user).to eq(@channel_archive.archived_by) @@ -174,7 +174,7 @@ describe Chat::ChannelArchiveService do create_messages(3) && start_archive @channel_archive.update!(destination_topic_title: "Wow this is the new title :tada: :joy:") - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(false) expect(@channel_archive.reload.failed?).to eq(true) expect(@channel_archive.archive_error).to eq("Title can't have more than 1 emoji") @@ -191,7 +191,7 @@ describe Chat::ChannelArchiveService do it "uses the channel slug to autolink a hashtag for the channel in the PM" do create_messages(3) && start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) pm_topic = Topic.private_messages.last expect(pm_topic.first_post.cooked).to have_tag( @@ -231,7 +231,7 @@ describe Chat::ChannelArchiveService do Chat::UserChatChannelMembership.where(chat_channel: channel, following: true).count, ).to eq(3) start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) expect( Chat::UserChatChannelMembership.where(chat_channel: channel, following: true).count, @@ -243,7 +243,7 @@ describe Chat::ChannelArchiveService do last_read_message_id: channel.chat_messages.first.id, ) start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute expect(@channel_archive.reload.complete?).to eq(true) expect(Chat::UserChatChannelMembership.last.last_read_message_id).to eq( channel.chat_messages.last.id, @@ -257,7 +257,7 @@ describe Chat::ChannelArchiveService do it "archives the topic" do create_messages(3) && start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute topic = @channel_archive.destination_topic topic.reload expect(topic.archived).to eq(true) @@ -269,7 +269,7 @@ describe Chat::ChannelArchiveService do it "leaves the topic open" do create_messages(3) && start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute topic = @channel_archive.destination_topic topic.reload expect(topic.archived).to eq(false) @@ -282,7 +282,7 @@ describe Chat::ChannelArchiveService do it "closes the topic" do create_messages(3) && start_archive - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute topic = @channel_archive.destination_topic topic.reload expect(topic.archived).to eq(false) @@ -297,7 +297,7 @@ describe Chat::ChannelArchiveService do destination_topic_title: nil, destination_topic_id: Fabricate(:topic).id, ) - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute topic = @channel_archive.destination_topic topic.reload expect(topic.archived).to eq(false) @@ -322,7 +322,7 @@ describe Chat::ChannelArchiveService do emoji: "+1", ) stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute end @channel_archive.reload @@ -363,7 +363,7 @@ describe Chat::ChannelArchiveService do .raises(FakeArchiveError.new("this is a test error")) stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do - expect { subject.new(@channel_archive).execute }.to raise_error(FakeArchiveError) + expect { described_class.new(@channel_archive).execute }.to raise_error(FakeArchiveError) end expect(@channel_archive.reload.archive_error).to eq("this is a test error") @@ -376,7 +376,7 @@ describe Chat::ChannelArchiveService do Chat::ChannelArchiveService.any_instance.unstub(:create_post) stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do - subject.new(@channel_archive).execute + described_class.new(@channel_archive).execute end @channel_archive.reload diff --git a/plugins/chat/spec/lib/chat/message_bookmarkable_spec.rb b/plugins/chat/spec/lib/chat/message_bookmarkable_spec.rb index d6c97f1eb59..492ecce8755 100644 --- a/plugins/chat/spec/lib/chat/message_bookmarkable_spec.rb +++ b/plugins/chat/spec/lib/chat/message_bookmarkable_spec.rb @@ -3,6 +3,8 @@ require "rails_helper" describe Chat::MessageBookmarkable do + subject(:registered_bookmarkable) { RegisteredBookmarkable.new(described_class) } + fab!(:user) { Fabricate(:user) } fab!(:guardian) { Guardian.new(user) } fab!(:other_category) { Fabricate(:private_category, group: Fabricate(:group)) } @@ -25,23 +27,21 @@ describe Chat::MessageBookmarkable do let!(:bookmark2) { Fabricate(:bookmark, user: user, bookmarkable: message2) } let!(:bookmark3) { Fabricate(:bookmark) } - subject { RegisteredBookmarkable.new(described_class) } - describe "#perform_list_query" do it "returns all the user's bookmarks" do - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array( + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( [bookmark1.id, bookmark2.id], ) end it "does not return bookmarks for messages inside category chat channels the user cannot access" do channel.update(chatable: other_category) - expect(subject.perform_list_query(user, guardian)).to eq(nil) + expect(registered_bookmarkable.perform_list_query(user, guardian)).to eq(nil) other_category.groups.last.add(user) bookmark1.reload user.reload guardian = Guardian.new(user) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array( + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( [bookmark1.id, bookmark2.id], ) end @@ -49,12 +49,12 @@ describe Chat::MessageBookmarkable do it "does not return bookmarks for messages inside direct message chat channels the user cannot access" do direct_message = Fabricate(:direct_message) channel.update(chatable: direct_message) - expect(subject.perform_list_query(user, guardian)).to eq(nil) + expect(registered_bookmarkable.perform_list_query(user, guardian)).to eq(nil) Chat::DirectMessageUser.create(user: user, direct_message: direct_message) bookmark1.reload user.reload guardian = Guardian.new(user) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array( + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( [bookmark1.id, bookmark2.id], ) end @@ -62,7 +62,9 @@ describe Chat::MessageBookmarkable do it "does not return bookmarks for deleted messages" do message1.trash! guardian = Guardian.new(user) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array([bookmark2.id]) + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( + [bookmark2.id], + ) end end @@ -72,8 +74,8 @@ describe Chat::MessageBookmarkable do it "returns bookmarks that match by name" do ts_query = Search.ts_query(term: "gotta", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%gotta%", ts_query, ).map(&:id), @@ -85,8 +87,8 @@ describe Chat::MessageBookmarkable do ts_query = Search.ts_query(term: "good soup", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%good soup%", ts_query, ).map(&:id), @@ -94,8 +96,8 @@ describe Chat::MessageBookmarkable do ts_query = Search.ts_query(term: "blah", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%blah%", ts_query, ).map(&:id), @@ -105,23 +107,23 @@ describe Chat::MessageBookmarkable do describe "#can_send_reminder?" do it "cannot send the reminder if the message or channel is deleted" do - expect(subject.can_send_reminder?(bookmark1)).to eq(true) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(true) bookmark1.bookmarkable.trash! bookmark1.reload - expect(subject.can_send_reminder?(bookmark1)).to eq(false) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false) Chat::Message.with_deleted.find_by(id: bookmark1.bookmarkable_id).recover! bookmark1.reload bookmark1.bookmarkable.chat_channel.trash! bookmark1.reload - expect(subject.can_send_reminder?(bookmark1)).to eq(false) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false) end end describe "#reminder_handler" do it "creates a notification for the user with the correct details" do - expect { subject.send_reminder_notification(bookmark1) }.to change { Notification.count }.by( - 1, - ) + expect { registered_bookmarkable.send_reminder_notification(bookmark1) }.to change { + Notification.count + }.by(1) notification = user.notifications.last expect(notification.notification_type).to eq(Notification.types[:bookmark_reminder]) expect(notification.data).to eq( @@ -142,38 +144,44 @@ describe Chat::MessageBookmarkable do describe "#can_see?" do it "returns false if the chat message is in a channel the user cannot see" do - expect(subject.can_see?(guardian, bookmark1)).to eq(true) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(true) bookmark1.bookmarkable.chat_channel.update!(chatable: private_category) - expect(subject.can_see?(guardian, bookmark1)).to eq(false) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false) private_category.groups.last.add(user) bookmark1.reload user.reload guardian = Guardian.new(user) - expect(subject.can_see?(guardian, bookmark1)).to eq(true) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(true) end end describe "#validate_before_create" do it "raises InvalidAccess if the user cannot see the chat channel" do - expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.not_to raise_error + expect { + registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable) + }.not_to raise_error bookmark1.bookmarkable.chat_channel.update!(chatable: private_category) - expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.to raise_error( - Discourse::InvalidAccess, - ) + expect { + registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable) + }.to raise_error(Discourse::InvalidAccess) private_category.groups.last.add(user) bookmark1.reload user.reload guardian = Guardian.new(user) - expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.not_to raise_error + expect { + registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable) + }.not_to raise_error end it "raises InvalidAccess if the chat message is deleted" do - expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.not_to raise_error + expect { + registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable) + }.not_to raise_error bookmark1.bookmarkable.trash! bookmark1.reload - expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.to raise_error( - Discourse::InvalidAccess, - ) + expect { + registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable) + }.to raise_error(Discourse::InvalidAccess) end end @@ -182,7 +190,7 @@ describe Chat::MessageBookmarkable do bookmark_post = Fabricate(:bookmark, bookmarkable: Fabricate(:post)) bookmark1.bookmarkable.trash! bookmark1.bookmarkable.update!(deleted_at: 4.days.ago) - subject.cleanup_deleted + registered_bookmarkable.cleanup_deleted expect(Bookmark.exists?(id: bookmark1.id)).to eq(false) expect(Bookmark.exists?(id: bookmark2.id)).to eq(true) expect(Bookmark.exists?(id: bookmark_post.id)).to eq(true) diff --git a/plugins/chat/spec/lib/chat/message_reactor_spec.rb b/plugins/chat/spec/lib/chat/message_reactor_spec.rb index c6715c3ad16..2a6d3cb06ef 100644 --- a/plugins/chat/spec/lib/chat/message_reactor_spec.rb +++ b/plugins/chat/spec/lib/chat/message_reactor_spec.rb @@ -3,39 +3,40 @@ require "rails_helper" describe Chat::MessageReactor do + subject(:message_reactor) { described_class.new(reacting_user, channel) } + fab!(:reacting_user) { Fabricate(:user) } fab!(:channel) { Fabricate(:category_channel) } fab!(:reactor) { described_class.new(reacting_user, channel) } fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel, user: reacting_user) } - let(:subject) { described_class.new(reacting_user, channel) } it "calls guardian ensure_can_join_chat_channel!" do Guardian.any_instance.expects(:ensure_can_join_chat_channel!).once - subject.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") + message_reactor.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") end it "raises an error if the user cannot see the channel" do channel.update!(chatable: Fabricate(:private_category, group: Group[:staff])) expect { - subject.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") + message_reactor.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") }.to raise_error(Discourse::InvalidAccess) end it "raises an error if the user cannot react" do SpamRule::AutoSilence.new(reacting_user).silence_user expect { - subject.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") + message_reactor.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") }.to raise_error(Discourse::InvalidAccess) end it "raises an error if the channel status is not open" do channel.update!(status: Chat::Channel.statuses[:archived]) expect { - subject.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") + message_reactor.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") }.to raise_error(Discourse::InvalidAccess) channel.update!(status: Chat::Channel.statuses[:open]) expect { - subject.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") + message_reactor.react!(message_id: message_1.id, react_action: :add, emoji: ":+1:") }.to change(Chat::MessageReaction, :count).by(1) end diff --git a/plugins/chat/spec/lib/chat/post_notification_handler_spec.rb b/plugins/chat/spec/lib/chat/post_notification_handler_spec.rb index 4d7488bc4b7..47705958594 100644 --- a/plugins/chat/spec/lib/chat/post_notification_handler_spec.rb +++ b/plugins/chat/spec/lib/chat/post_notification_handler_spec.rb @@ -3,10 +3,11 @@ require "rails_helper" describe Chat::PostNotificationHandler do + subject(:handler) { described_class.new(post, notified_users) } + let(:acting_user) { Fabricate(:user) } let(:post) { Fabricate(:post) } let(:notified_users) { [] } - let(:subject) { described_class.new(post, notified_users) } fab!(:channel) { Fabricate(:category_channel) } fab!(:message1) do @@ -24,7 +25,7 @@ describe Chat::PostNotificationHandler do def expect_no_notification return_val = nil - expect { return_val = subject.handle }.not_to change { Notification.count } + expect { return_val = handler.handle }.not_to change { Notification.count } expect(return_val).to eq(false) end @@ -51,7 +52,7 @@ describe Chat::PostNotificationHandler do it "sends notifications to all of the quoted users" do update_post_with_chat_quote([message1, message2]) - subject.handle + handler.handle expect( Notification.where( user: message1.user, @@ -68,8 +69,8 @@ describe Chat::PostNotificationHandler do it "does not send the same chat_quoted notification twice to the same post and user" do update_post_with_chat_quote([message1, message2]) - subject.handle - subject.handle + handler.handle + handler.handle expect( Notification.where( user: message1.user, @@ -87,7 +88,7 @@ describe Chat::PostNotificationHandler do topic: post.topic, user: message1.user, ) - subject.handle + handler.handle expect( Notification.where( user: message1.user, @@ -101,7 +102,7 @@ describe Chat::PostNotificationHandler do it "does not send notifications to those users" do update_post_with_chat_quote([message1, message2]) - subject.handle + handler.handle expect( Notification.where( user: message1.user, diff --git a/plugins/chat/spec/lib/chat/review_queue_spec.rb b/plugins/chat/spec/lib/chat/review_queue_spec.rb index fb147e7df2e..01b560ac6dd 100644 --- a/plugins/chat/spec/lib/chat/review_queue_spec.rb +++ b/plugins/chat/spec/lib/chat/review_queue_spec.rb @@ -3,17 +3,17 @@ require "rails_helper" describe Chat::ReviewQueue do + subject(:queue) { described_class.new } + fab!(:message_poster) { Fabricate(:user) } fab!(:flagger) { Fabricate(:user) } fab!(:chat_channel) { Fabricate(:category_channel) } fab!(:message) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) } - fab!(:admin) { Fabricate(:admin) } + let(:guardian) { Guardian.new(flagger) } let(:admin_guardian) { Guardian.new(admin) } - subject(:queue) { described_class.new } - before do chat_channel.add(message_poster) chat_channel.add(flagger) diff --git a/plugins/chat/spec/models/chat/deleted_chat_user_spec.rb b/plugins/chat/spec/models/chat/deleted_chat_user_spec.rb index 3d3284728e9..9a1beeaf757 100644 --- a/plugins/chat/spec/models/chat/deleted_chat_user_spec.rb +++ b/plugins/chat/spec/models/chat/deleted_chat_user_spec.rb @@ -3,15 +3,19 @@ require "rails_helper" describe Chat::DeletedUser do + subject(:deleted_user) { described_class.new } + describe "#username" do it "returns a default username" do - expect(subject.username).to eq(I18n.t("chat.deleted_chat_username")) + expect(deleted_user.username).to eq(I18n.t("chat.deleted_chat_username")) end end describe "#avatar_template" do it "returns a default path" do - expect(subject.avatar_template).to eq("/plugins/chat/images/deleted-chat-user-avatar.png") + expect(deleted_user.avatar_template).to eq( + "/plugins/chat/images/deleted-chat-user-avatar.png", + ) end end end diff --git a/plugins/chat/spec/queries/chat/channel_unreads_query_spec.rb b/plugins/chat/spec/queries/chat/channel_unreads_query_spec.rb index 10131b31c8e..112b255c3b7 100644 --- a/plugins/chat/spec/queries/chat/channel_unreads_query_spec.rb +++ b/plugins/chat/spec/queries/chat/channel_unreads_query_spec.rb @@ -3,6 +3,15 @@ require "rails_helper" describe Chat::ChannelUnreadsQuery do + subject(:query) do + described_class.call( + channel_ids: channel_ids, + user_id: current_user.id, + include_missing_memberships: include_missing_memberships, + include_read: include_read, + ).map(&:to_h) + end + fab!(:channel_1) { Fabricate(:category_channel) } fab!(:current_user) { Fabricate(:user) } let(:include_missing_memberships) { false } @@ -15,20 +24,11 @@ describe Chat::ChannelUnreadsQuery do channel_1.add(current_user) end - let(:subject) do - described_class.call( - channel_ids: channel_ids, - user_id: current_user.id, - include_missing_memberships: include_missing_memberships, - include_read: include_read, - ).map(&:to_h) - end - context "with unread message" do before { Fabricate(:chat_message, chat_channel: channel_1) } it "returns a correct unread count" do - expect(subject.first).to eq({ mention_count: 0, unread_count: 1, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 1, channel_id: channel_1.id }) end context "when the membership has been muted" do @@ -40,7 +40,7 @@ describe Chat::ChannelUnreadsQuery do end it "returns a zeroed unread count" do - expect(subject.first).to eq({ mention_count: 0, unread_count: 0, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 0, channel_id: channel_1.id }) end end @@ -49,13 +49,13 @@ describe Chat::ChannelUnreadsQuery do fab!(:thread) { Fabricate(:chat_thread, channel: channel_1, original_message: thread_om) } it "does include the original message in the unread count" do - expect(subject.first).to eq({ mention_count: 0, unread_count: 2, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 2, channel_id: channel_1.id }) end it "does not include other thread messages in the unread count" do Fabricate(:chat_message, chat_channel: channel_1, thread: thread) Fabricate(:chat_message, chat_channel: channel_1, thread: thread) - expect(subject.first).to eq({ mention_count: 0, unread_count: 2, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 2, channel_id: channel_1.id }) end end @@ -70,7 +70,7 @@ describe Chat::ChannelUnreadsQuery do end it "returns accurate counts" do - expect(subject).to match_array( + expect(query).to match_array( [ { mention_count: 0, unread_count: 1, channel_id: channel_1.id }, { mention_count: 0, unread_count: 2, channel_id: channel_2.id }, @@ -87,7 +87,7 @@ describe Chat::ChannelUnreadsQuery do end it "does not return counts for the channels" do - expect(subject).to match_array( + expect(query).to match_array( [{ mention_count: 0, unread_count: 1, channel_id: channel_1.id }], ) end @@ -96,7 +96,7 @@ describe Chat::ChannelUnreadsQuery do let(:include_missing_memberships) { true } it "does return zeroed counts for the channels" do - expect(subject).to match_array( + expect(query).to match_array( [ { mention_count: 0, unread_count: 1, channel_id: channel_1.id }, { mention_count: 0, unread_count: 0, channel_id: channel_2.id }, @@ -108,7 +108,7 @@ describe Chat::ChannelUnreadsQuery do let(:include_read) { false } it "does not return counts for the channels" do - expect(subject).to match_array( + expect(query).to match_array( [{ mention_count: 0, unread_count: 1, channel_id: channel_1.id }], ) end @@ -135,7 +135,7 @@ describe Chat::ChannelUnreadsQuery do message = Fabricate(:chat_message, chat_channel: channel_1) create_mention(message, channel_1) - expect(subject.first).to eq({ mention_count: 1, unread_count: 1, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 1, unread_count: 1, channel_id: channel_1.id }) end context "for unread mentions in a thread" do @@ -144,7 +144,7 @@ describe Chat::ChannelUnreadsQuery do it "does include the original message in the mention count" do create_mention(thread_om, channel_1) - expect(subject.first).to eq({ mention_count: 1, unread_count: 1, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 1, unread_count: 1, channel_id: channel_1.id }) end it "does not include other thread messages in the mention count" do @@ -152,7 +152,7 @@ describe Chat::ChannelUnreadsQuery do thread_message_2 = Fabricate(:chat_message, chat_channel: channel_1, thread: thread) create_mention(thread_message_1, channel_1) create_mention(thread_message_2, channel_1) - expect(subject.first).to eq({ mention_count: 0, unread_count: 1, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 1, channel_id: channel_1.id }) end end @@ -169,7 +169,7 @@ describe Chat::ChannelUnreadsQuery do message_2 = Fabricate(:chat_message, chat_channel: channel_2) create_mention(message_2, channel_2) - expect(subject).to match_array( + expect(query).to match_array( [ { mention_count: 1, unread_count: 1, channel_id: channel_1.id }, { mention_count: 1, unread_count: 2, channel_id: channel_2.id }, @@ -181,14 +181,14 @@ describe Chat::ChannelUnreadsQuery do context "with nothing unread" do it "returns a correct state" do - expect(subject.first).to eq({ mention_count: 0, unread_count: 0, channel_id: channel_1.id }) + expect(query.first).to eq({ mention_count: 0, unread_count: 0, channel_id: channel_1.id }) end context "when include_read is false" do let(:include_read) { false } it "returns nothing" do - expect(subject).to eq([]) + expect(query).to eq([]) end end end diff --git a/plugins/chat/spec/queries/chat/messages_query_spec.rb b/plugins/chat/spec/queries/chat/messages_query_spec.rb index be46468822e..be6f9a7406b 100644 --- a/plugins/chat/spec/queries/chat/messages_query_spec.rb +++ b/plugins/chat/spec/queries/chat/messages_query_spec.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true RSpec.describe Chat::MessagesQuery do + subject(:query) do + described_class.call(guardian: current_user.guardian, channel: channel, **options) + end + fab!(:channel) { Fabricate(:category_channel) } fab!(:current_user) { Fabricate(:user) } @@ -21,10 +25,6 @@ RSpec.describe Chat::MessagesQuery do } end - let(:subject) do - described_class.call(guardian: current_user.guardian, channel: channel, **options) - end - fab!(:message_1) do message = Fabricate(:chat_message, chat_channel: channel) message.update!(created_at: 2.days.ago) @@ -42,7 +42,7 @@ RSpec.describe Chat::MessagesQuery do let(:target_message_id) { target_message.id } it "queries messages in the channel and finds the past and future messages" do - expect(subject).to eq( + expect(query).to eq( past_messages: [message_1], future_messages: [message_3], target_message: target_message, @@ -53,29 +53,29 @@ RSpec.describe Chat::MessagesQuery do it "does not include deleted messages" do message_3.trash! - expect(subject[:future_messages]).to eq([]) + expect(query[:future_messages]).to eq([]) end it "still includes the target message if it is deleted" do target_message.trash! - expect(subject[:target_message]).to eq(target_message) + expect(query[:target_message]).to eq(target_message) end it "can_load_more_past is true when the past messages reach the limit" do stub_const(described_class, "PAST_MESSAGE_LIMIT", 1) do - expect(subject[:can_load_more_past]).to be_truthy + expect(query[:can_load_more_past]).to be_truthy end end it "can_load_more_future is true when the future messages reach the limit" do stub_const(described_class, "FUTURE_MESSAGE_LIMIT", 1) do - expect(subject[:can_load_more_future]).to be_truthy + expect(query[:can_load_more_future]).to be_truthy end end it "limits results of paginated query when page_size is not set" do options[:target_message_id] = nil - stub_const(described_class, "MAX_PAGE_SIZE", 1) { expect(subject[:messages].length).to eq(1) } + stub_const(described_class, "MAX_PAGE_SIZE", 1) { expect(query[:messages].length).to eq(1) } end describe "when some messages are in threads" do @@ -83,7 +83,7 @@ RSpec.describe Chat::MessagesQuery do it "does not include messages which are thread replies but does include thread original messages" do message_3.update!(thread: thread) - expect(subject[:future_messages]).to eq([thread.original_message]) + expect(query[:future_messages]).to eq([thread.original_message]) end context "when include_thread_messages is true" do @@ -94,7 +94,7 @@ RSpec.describe Chat::MessagesQuery do thread: thread, created_at: thread.original_message.created_at + 1.minute, ) - expect(subject[:future_messages]).to eq([thread.original_message, message_3]) + expect(query[:future_messages]).to eq([thread.original_message, message_3]) end end @@ -105,7 +105,7 @@ RSpec.describe Chat::MessagesQuery do thread: thread, created_at: thread.original_message.created_at + 1.minute, ) - expect(subject[:future_messages]).to eq([thread.original_message, message_3]) + expect(query[:future_messages]).to eq([thread.original_message, message_3]) end end end @@ -115,7 +115,7 @@ RSpec.describe Chat::MessagesQuery do it "does include deleted messages" do message_3.trash! - expect(subject[:future_messages]).to eq([message_3]) + expect(query[:future_messages]).to eq([message_3]) end end end @@ -124,7 +124,7 @@ RSpec.describe Chat::MessagesQuery do let(:target_date) { 1.day.ago } it "queries messages in the channel and finds the past and future messages" do - expect(subject).to eq( + expect(query).to eq( past_messages: [message_1], future_messages: [message_2, message_3], target_date: target_date, @@ -136,7 +136,7 @@ RSpec.describe Chat::MessagesQuery do context "when target_message_id not provided" do it "queries messages in the channel" do - expect(subject).to eq( + expect(query).to eq( messages: [message_1, message_2, message_3], can_load_more_past: false, can_load_more_future: false, @@ -147,7 +147,7 @@ RSpec.describe Chat::MessagesQuery do let(:page_size) { 3 } it "can_load_more_past is true" do - expect(subject[:can_load_more_past]).to be_truthy + expect(query[:can_load_more_past]).to be_truthy end end @@ -155,14 +155,14 @@ RSpec.describe Chat::MessagesQuery do let(:direction) { described_class::FUTURE } it "returns messages in ascending order by created_at" do - expect(subject[:messages]).to eq([message_1, message_2, message_3]) + expect(query[:messages]).to eq([message_1, message_2, message_3]) end context "when the messages length is equal to the page_size" do let(:page_size) { 3 } it "can_load_more_future is true" do - expect(subject[:can_load_more_future]).to be_truthy + expect(query[:can_load_more_future]).to be_truthy end end end @@ -171,14 +171,14 @@ RSpec.describe Chat::MessagesQuery do let(:direction) { described_class::PAST } it "returns messages in ascending order by created_at" do - expect(subject[:messages]).to eq([message_1, message_2, message_3]) + expect(query[:messages]).to eq([message_1, message_2, message_3]) end context "when the messages length is equal to the page_size" do let(:page_size) { 3 } it "can_load_more_past is true" do - expect(subject[:can_load_more_past]).to be_truthy + expect(query[:can_load_more_past]).to be_truthy end end end diff --git a/plugins/chat/spec/queries/chat/thread_unreads_query_spec.rb b/plugins/chat/spec/queries/chat/thread_unreads_query_spec.rb index 6b4e83e3f16..2999eef5108 100644 --- a/plugins/chat/spec/queries/chat/thread_unreads_query_spec.rb +++ b/plugins/chat/spec/queries/chat/thread_unreads_query_spec.rb @@ -3,6 +3,16 @@ require "rails_helper" describe Chat::ThreadUnreadsQuery do + subject(:query) do + described_class.call( + channel_ids: channel_ids, + thread_ids: thread_ids, + user_id: current_user.id, + include_missing_memberships: include_missing_memberships, + include_read: include_read, + ) + end + fab!(:channel_1) { Fabricate(:category_channel, threading_enabled: true) } fab!(:channel_2) { Fabricate(:category_channel, threading_enabled: true) } fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1) } @@ -16,15 +26,6 @@ describe Chat::ThreadUnreadsQuery do let(:include_read) { true } let(:channel_ids) { [] } let(:thread_ids) { [] } - let(:subject) do - described_class.call( - channel_ids: channel_ids, - thread_ids: thread_ids, - user_id: current_user.id, - include_missing_memberships: include_missing_memberships, - include_read: include_read, - ) - end before do SiteSetting.chat_enabled = true @@ -47,7 +48,7 @@ describe Chat::ThreadUnreadsQuery do let(:channel_ids) { [channel_1.id, channel_2.id] } it "gets a count of all the thread unreads across the channels" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 1 }, { channel_id: channel_1.id, mention_count: 0, thread_id: thread_2.id, unread_count: 0 }, @@ -59,17 +60,17 @@ describe Chat::ThreadUnreadsQuery do it "does not count deleted messages" do message_1.trash! - expect(subject.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( + expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) end it "does not messages in threads where threading_enabled is false on the channel" do channel_1.update!(threading_enabled: false) - expect(subject.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( + expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) - expect(subject.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_2.id }).to eq( + expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_2.id }).to eq( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_2.id, unread_count: 0 }, ) end @@ -79,7 +80,7 @@ describe Chat::ThreadUnreadsQuery do .user_chat_thread_memberships .find_by(user: current_user) .update!(last_read_message_id: message_1.id) - expect(subject.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( + expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) end @@ -87,7 +88,7 @@ describe Chat::ThreadUnreadsQuery do it "does not count the original message ID as unread" do thread_1.original_message.destroy thread_1.update!(original_message: message_1) - expect(subject.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( + expect(query.map(&:to_h).find { |tracking| tracking[:thread_id] == thread_1.id }).to eq( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) end @@ -96,7 +97,7 @@ describe Chat::ThreadUnreadsQuery do let(:include_read) { false } it "does not get threads with no unread messages" do - expect(subject.map(&:to_h)).not_to include( + expect(query.map(&:to_h)).not_to include( [ { channel_id: channel_1.id, @@ -114,7 +115,7 @@ describe Chat::ThreadUnreadsQuery do let(:thread_ids) { [thread_1.id, thread_3.id] } it "gets a count of all the thread unreads for the specified threads" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 1 }, { channel_id: channel_2.id, mention_count: 0, thread_id: thread_3.id, unread_count: 1 }, @@ -131,7 +132,7 @@ describe Chat::ThreadUnreadsQuery do end it "gets a zeroed out count for the thread" do - expect(subject.map(&:to_h)).to include( + expect(query.map(&:to_h)).to include( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) end @@ -146,7 +147,7 @@ describe Chat::ThreadUnreadsQuery do end it "gets a zeroed out count for the thread" do - expect(subject.map(&:to_h)).to include( + expect(query.map(&:to_h)).to include( { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 }, ) end @@ -156,7 +157,7 @@ describe Chat::ThreadUnreadsQuery do before { thread_1.user_chat_thread_memberships.find_by(user: current_user).destroy! } it "does not get that thread unread count by default" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_2.id, @@ -172,7 +173,7 @@ describe Chat::ThreadUnreadsQuery do let(:include_missing_memberships) { true } it "includes the thread that the user is not a member of with zeroed out counts" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_1.id, @@ -194,7 +195,7 @@ describe Chat::ThreadUnreadsQuery do let(:include_read) { false } it "does not include the thread that the user is not a member of with zeroed out counts" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_2.id, @@ -215,7 +216,7 @@ describe Chat::ThreadUnreadsQuery do let(:thread_ids) { [thread_1.id, thread_3.id] } it "gets a count of all the thread unreads across the channels filtered by thread id" do - expect(subject.map(&:to_h)).to match_array( + expect(query.map(&:to_h)).to match_array( [ { channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 1 }, { channel_id: channel_2.id, mention_count: 0, thread_id: thread_3.id, unread_count: 1 }, diff --git a/plugins/chat/spec/queries/chat/tracking_state_report_query_spec.rb b/plugins/chat/spec/queries/chat/tracking_state_report_query_spec.rb index 76d7146616c..5a8ad346cef 100644 --- a/plugins/chat/spec/queries/chat/tracking_state_report_query_spec.rb +++ b/plugins/chat/spec/queries/chat/tracking_state_report_query_spec.rb @@ -1,15 +1,7 @@ # frozen_string_literal: true RSpec.describe Chat::TrackingStateReportQuery do - fab!(:current_user) { Fabricate(:user) } - let(:guardian) { current_user.guardian } - - let(:channel_ids) { [] } - let(:thread_ids) { [] } - let(:include_missing_memberships) { false } - let(:include_threads) { false } - let(:include_read) { true } - let(:subject) do + subject(:query) do described_class.call( guardian: guardian, channel_ids: channel_ids, @@ -20,9 +12,17 @@ RSpec.describe Chat::TrackingStateReportQuery do ) end + fab!(:current_user) { Fabricate(:user) } + let(:guardian) { current_user.guardian } + + let(:channel_ids) { [] } + let(:thread_ids) { [] } + let(:include_missing_memberships) { false } + let(:include_threads) { false } + let(:include_read) { true } context "when channel_ids empty" do it "returns empty object for channel_tracking" do - expect(subject.channel_tracking).to eq({}) + expect(query.channel_tracking).to eq({}) end end @@ -41,7 +41,7 @@ RSpec.describe Chat::TrackingStateReportQuery do include_read: include_read, ) .returns([]) - subject + query end it "generates a correct unread report for the channels the user is a member of" do @@ -50,7 +50,7 @@ RSpec.describe Chat::TrackingStateReportQuery do Fabricate(:chat_message, chat_channel: channel_1) Fabricate(:chat_message, chat_channel: channel_2) - expect(subject.channel_tracking).to eq( + expect(query.channel_tracking).to eq( { channel_1.id => { unread_count: 1, @@ -66,7 +66,7 @@ RSpec.describe Chat::TrackingStateReportQuery do it "does not include threads by default" do Chat::ThreadUnreadsQuery.expects(:call).never - expect(subject.thread_tracking).to eq({}) + expect(query.thread_tracking).to eq({}) end context "when include_threads is true" do @@ -90,7 +90,7 @@ RSpec.describe Chat::TrackingStateReportQuery do include_read: include_read, ) .returns([]) - subject + query end it "generates a correct unread for the threads the user is a member of in the channels" do @@ -101,7 +101,7 @@ RSpec.describe Chat::TrackingStateReportQuery do Fabricate(:chat_message, chat_channel: channel_1, thread: thread_1) Fabricate(:chat_message, chat_channel: channel_2, thread: thread_2) - expect(subject.channel_tracking).to eq( + expect(query.channel_tracking).to eq( { channel_1.id => { unread_count: 1, @@ -113,7 +113,7 @@ RSpec.describe Chat::TrackingStateReportQuery do }, }, ) - expect(subject.thread_tracking).to eq( + expect(query.thread_tracking).to eq( { thread_1.id => { unread_count: 1, @@ -135,7 +135,7 @@ RSpec.describe Chat::TrackingStateReportQuery do it "does not query threads" do Chat::ThreadUnreadsQuery.expects(:call).never - expect(subject.thread_tracking).to eq({}) + expect(query.thread_tracking).to eq({}) end end end diff --git a/plugins/chat/spec/serializer/chat/channel_serializer_spec.rb b/plugins/chat/spec/serializer/chat/channel_serializer_spec.rb index b8c4e9c52b8..8a4160ff9cd 100644 --- a/plugins/chat/spec/serializer/chat/channel_serializer_spec.rb +++ b/plugins/chat/spec/serializer/chat/channel_serializer_spec.rb @@ -3,23 +3,25 @@ require "rails_helper" describe Chat::ChannelSerializer do + subject(:serializer) { described_class.new(chat_channel, scope: guardian, root: nil) } + fab!(:user) { Fabricate(:user) } fab!(:admin) { Fabricate(:admin) } fab!(:chat_channel) { Fabricate(:chat_channel) } + let(:guardian_user) { user } let(:guardian) { Guardian.new(guardian_user) } - subject { described_class.new(chat_channel, scope: guardian, root: nil) } describe "archive status" do context "when user is not staff" do let(:guardian_user) { user } it "does not return any sort of archive status" do - expect(subject.as_json.key?(:archive_completed)).to eq(false) + expect(serializer.as_json.key?(:archive_completed)).to eq(false) end it "includes allow_channel_wide_mentions" do - expect(subject.as_json.key?(:allow_channel_wide_mentions)).to eq(true) + expect(serializer.as_json.key?(:allow_channel_wide_mentions)).to eq(true) end end @@ -27,10 +29,10 @@ describe Chat::ChannelSerializer do let(:guardian_user) { admin } it "includes the archive status if the channel is archived and the archive record exists" do - expect(subject.as_json.key?(:archive_completed)).to eq(false) + expect(serializer.as_json.key?(:archive_completed)).to eq(false) chat_channel.update!(status: Chat::Channel.statuses[:archived]) - expect(subject.as_json.key?(:archive_completed)).to eq(false) + expect(serializer.as_json.key?(:archive_completed)).to eq(false) Chat::ChannelArchive.create!( chat_channel: chat_channel, @@ -39,11 +41,11 @@ describe Chat::ChannelSerializer do total_messages: 10, ) chat_channel.reload - expect(subject.as_json.key?(:archive_completed)).to eq(true) + expect(serializer.as_json.key?(:archive_completed)).to eq(true) end it "includes allow_channel_wide_mentions" do - expect(subject.as_json.key?(:allow_channel_wide_mentions)).to eq(true) + expect(serializer.as_json.key?(:allow_channel_wide_mentions)).to eq(true) end end end @@ -63,7 +65,7 @@ describe Chat::ChannelSerializer do MessageBus.expects(:last_id).with( Chat::Publisher.kick_users_message_bus_channel(chat_channel.id), ) - expect(subject.as_json.dig(:meta, :message_bus_last_ids).keys).to eq( + expect(serializer.as_json.dig(:meta, :message_bus_last_ids).keys).to eq( %i[channel_message_bus_last_id new_messages new_mentions kick], ) end @@ -73,7 +75,7 @@ describe Chat::ChannelSerializer do MessageBus.expects(:last_id).with( Chat::Publisher.kick_users_message_bus_channel(chat_channel.id), ) - expect(subject.as_json[:meta][:message_bus_last_ids].key?(:kick)).to eq(true) + expect(serializer.as_json[:meta][:message_bus_last_ids].key?(:kick)).to eq(true) end it "does not call MessageBus for last_id if all the last IDs are already passed in" do @@ -101,7 +103,7 @@ describe Chat::ChannelSerializer do MessageBus.expects(:last_id).with( Chat::Publisher.new_mentions_message_bus_channel(chat_channel.id), ) - expect(subject.as_json.dig(:meta, :message_bus_last_ids).keys).to eq( + expect(serializer.as_json.dig(:meta, :message_bus_last_ids).keys).to eq( %i[channel_message_bus_last_id new_messages new_mentions], ) end @@ -109,7 +111,7 @@ describe Chat::ChannelSerializer do it "does not get the kick_message_bus_last_id" do MessageBus.expects(:last_id).at_least_once MessageBus.expects(:last_id).never - expect(subject.as_json[:meta][:message_bus_last_ids].key?(:kick)).to eq(false) + expect(serializer.as_json[:meta][:message_bus_last_ids].key?(:kick)).to eq(false) end end end diff --git a/plugins/chat/spec/serializer/chat/chat_message_serializer_spec.rb b/plugins/chat/spec/serializer/chat/chat_message_serializer_spec.rb index 9f1218b0618..89abcb42bc9 100644 --- a/plugins/chat/spec/serializer/chat/chat_message_serializer_spec.rb +++ b/plugins/chat/spec/serializer/chat/chat_message_serializer_spec.rb @@ -3,13 +3,14 @@ require "rails_helper" describe Chat::MessageSerializer do + subject(:serializer) { described_class.new(message_1, scope: guardian, root: nil) } + fab!(:chat_channel) { Fabricate(:category_channel) } fab!(:message_poster) { Fabricate(:user) } fab!(:message_1) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) } fab!(:guardian_user) { Fabricate(:user) } - let(:guardian) { Guardian.new(guardian_user) } - subject { described_class.new(message_1, scope: guardian, root: nil) } + let(:guardian) { Guardian.new(guardian_user) } describe "#reactions" do fab!(:custom_emoji) { CustomEmoji.create!(name: "trout", upload: Fabricate(:upload)) } @@ -21,13 +22,13 @@ describe Chat::MessageSerializer do it "doesn’t return the reaction" do Emoji.clear_cache - trout_reaction = subject.as_json[:reactions].find { |r| r[:emoji] == "trout" } + trout_reaction = serializer.as_json[:reactions].find { |r| r[:emoji] == "trout" } expect(trout_reaction).to be_present custom_emoji.destroy! Emoji.clear_cache - trout_reaction = subject.as_json[:reactions].find { |r| r[:emoji] == "trout" } + trout_reaction = serializer.as_json[:reactions].find { |r| r[:emoji] == "trout" } expect(trout_reaction).to_not be_present end end @@ -49,7 +50,7 @@ describe Chat::MessageSerializer do message_1.user.destroy! message_1.reload - expect(subject.as_json[:user][:username]).to eq(I18n.t("chat.deleted_chat_username")) + expect(serializer.as_json[:user][:username]).to eq(I18n.t("chat.deleted_chat_username")) end end end @@ -60,14 +61,14 @@ describe Chat::MessageSerializer do message_1.user.destroy! message_1.reload - expect(subject.as_json[:deleted_at]).to(be_within(1.second).of(Time.zone.now)) + expect(serializer.as_json[:deleted_at]).to(be_within(1.second).of(Time.zone.now)) end it "is marked as deleted by system user" do message_1.user.destroy! message_1.reload - expect(subject.as_json[:deleted_by_id]).to eq(Discourse.system_user.id) + expect(serializer.as_json[:deleted_by_id]).to eq(Discourse.system_user.id) end end end diff --git a/plugins/chat/spec/serializer/chat/chat_message_user_serializer_spec.rb b/plugins/chat/spec/serializer/chat/chat_message_user_serializer_spec.rb index 94c63dceca6..fa12515bc2b 100644 --- a/plugins/chat/spec/serializer/chat/chat_message_user_serializer_spec.rb +++ b/plugins/chat/spec/serializer/chat/chat_message_user_serializer_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe Chat::MessageUserSerializer do - subject do + subject(:serializer) do user = Fabricate(:user, **params) guardian = Guardian.new(user) described_class.new(user, scope: guardian, root: nil).as_json @@ -15,11 +15,11 @@ RSpec.describe Chat::MessageUserSerializer do context "with default user" do it "displays user as regular" do - expect(subject[:new_user]).to eq(false) - expect(subject[:staff]).to eq(false) - expect(subject[:admin]).to eq(false) - expect(subject[:moderator]).to eq(false) - expect(subject[:primary_group_name]).to be_blank + expect(serializer[:new_user]).to eq(false) + expect(serializer[:staff]).to eq(false) + expect(serializer[:admin]).to eq(false) + expect(serializer[:moderator]).to eq(false) + expect(serializer[:primary_group_name]).to be_blank end end @@ -27,7 +27,7 @@ RSpec.describe Chat::MessageUserSerializer do before { params[:trust_level] = TrustLevel[0] } it "displays user as new" do - expect(subject[:new_user]).to eq(true) + expect(serializer[:new_user]).to eq(true) end end @@ -35,7 +35,7 @@ RSpec.describe Chat::MessageUserSerializer do before { params[:admin] = true } it "displays user as staff" do - expect(subject[:staff]).to eq(true) + expect(serializer[:staff]).to eq(true) end end @@ -43,7 +43,7 @@ RSpec.describe Chat::MessageUserSerializer do before { params[:admin] = true } it "displays user as admin" do - expect(subject[:admin]).to eq(true) + expect(serializer[:admin]).to eq(true) end end @@ -51,7 +51,7 @@ RSpec.describe Chat::MessageUserSerializer do before { params[:moderator] = true } it "displays user as moderator" do - expect(subject[:moderator]).to eq(true) + expect(serializer[:moderator]).to eq(true) end end @@ -61,7 +61,7 @@ RSpec.describe Chat::MessageUserSerializer do before { params[:primary_group_id] = group.id } it "displays user as moderator" do - expect(subject[:primary_group_name]).to eq(group.name) + expect(serializer[:primary_group_name]).to eq(group.name) end end end diff --git a/plugins/chat/spec/services/chat/channel_view_builder_spec.rb b/plugins/chat/spec/services/chat/channel_view_builder_spec.rb index 99a9eb9e917..9717346cd94 100644 --- a/plugins/chat/spec/services/chat/channel_view_builder_spec.rb +++ b/plugins/chat/spec/services/chat/channel_view_builder_spec.rb @@ -11,6 +11,8 @@ RSpec.describe Chat::ChannelViewBuilder do end describe ".call" do + subject(:result) { described_class.call(params) } + fab!(:current_user) { Fabricate(:user) } fab!(:channel) { Fabricate(:category_channel) } @@ -35,14 +37,12 @@ RSpec.describe Chat::ChannelViewBuilder do } end - subject(:result) { described_class.call(params) } - it "threads_enabled is false by default" do - expect(subject.threads_enabled).to eq(false) + expect(result.threads_enabled).to eq(false) end it "include_thread_messages is true by default" do - expect(subject.include_thread_messages).to eq(true) + expect(result.include_thread_messages).to eq(true) end it "queries messages" do @@ -59,7 +59,7 @@ RSpec.describe Chat::ChannelViewBuilder do target_date: target_date, ) .returns({ messages: [] }) - subject + result end it "returns channel messages and thread replies" do @@ -71,23 +71,23 @@ RSpec.describe Chat::ChannelViewBuilder do chat_channel: channel, thread: Fabricate(:chat_thread, channel: channel), ) - expect(subject.view.chat_messages).to eq( + expect(result.view.chat_messages).to eq( [message_1, message_2, message_3.thread.original_message, message_3], ) end it "does not query thread tracking overview or state by default" do Chat::TrackingStateReportQuery.expects(:call).never - subject + result end it "does not query threads by default" do Chat::Thread.expects(:where).never - subject + result end it "returns a Chat::View" do - expect(subject.view).to be_a(Chat::View) + expect(result.view).to be_a(Chat::View) end context "when page_size is null" do @@ -109,11 +109,11 @@ RSpec.describe Chat::ChannelViewBuilder do end it "threads_enabled is true" do - expect(subject.threads_enabled).to eq(true) + expect(result.threads_enabled).to eq(true) end it "include_thread_messages is false" do - expect(subject.include_thread_messages).to eq(false) + expect(result.include_thread_messages).to eq(false) end it "returns channel messages but not thread replies" do @@ -125,7 +125,7 @@ RSpec.describe Chat::ChannelViewBuilder do chat_channel: channel, thread: Fabricate(:chat_thread, channel: channel), ) - expect(subject.view.chat_messages).to eq( + expect(result.view.chat_messages).to eq( [message_1, message_2, message_3.thread.original_message], ) end @@ -137,7 +137,7 @@ RSpec.describe Chat::ChannelViewBuilder do chat_channel: channel, thread: Fabricate(:chat_thread, channel: channel), ) - expect(subject.view.threads).to eq([message_1.thread]) + expect(result.view.threads).to eq([message_1.thread]) end it "fetches thread memberships for the current user for fetched threads" do @@ -148,7 +148,7 @@ RSpec.describe Chat::ChannelViewBuilder do thread: Fabricate(:chat_thread, channel: channel), ) message_1.thread.add(current_user) - expect(subject.view.thread_memberships).to eq( + expect(result.view.thread_memberships).to eq( [message_1.thread.membership_for(current_user)], ) end @@ -171,21 +171,21 @@ RSpec.describe Chat::ChannelViewBuilder do .with(guardian: guardian, thread_ids: [thread.id], include_threads: true) .returns(Chat::TrackingStateReport.new) .once - subject + result end it "fetches an overview of threads with unread messages in the channel" do thread = Fabricate(:chat_thread, channel: channel) thread.add(current_user) message_1 = Fabricate(:chat_message, chat_channel: channel, thread: thread) - expect(subject.view.unread_thread_ids).to eq([message_1.thread.id]) + expect(result.view.unread_thread_ids).to eq([message_1.thread.id]) end it "fetches the tracking state of threads in the channel" do thread = Fabricate(:chat_thread, channel: channel) thread.add(current_user) Fabricate(:chat_message, chat_channel: channel, thread: thread) - expect(subject.view.tracking.thread_tracking).to eq( + expect(result.view.tracking.thread_tracking).to eq( { thread.id => { channel_id: channel.id, unread_count: 1, mention_count: 0 } }, ) end @@ -194,7 +194,7 @@ RSpec.describe Chat::ChannelViewBuilder do let(:thread_id) { Fabricate(:chat_thread, channel: channel).id } it "include_thread_messages is true" do - expect(subject.include_thread_messages).to eq(true) + expect(result.include_thread_messages).to eq(true) end end end @@ -233,7 +233,7 @@ RSpec.describe Chat::ChannelViewBuilder do context "if the user is not a member of the channel" do it "does not error and still returns messages" do - expect(subject.view.chat_messages).to eq([past_message_2, past_message_1, message]) + expect(result.view.chat_messages).to eq([past_message_2, past_message_1, message]) end end @@ -246,7 +246,7 @@ RSpec.describe Chat::ChannelViewBuilder do before { membership.update!(last_read_message_id: past_message_1.id) } it "uses the last_read_message_id of the user's membership as the target_message_id" do - expect(subject.view.chat_messages).to eq([past_message_2, past_message_1, message]) + expect(result.view.chat_messages).to eq([past_message_2, past_message_1, message]) end end @@ -254,7 +254,7 @@ RSpec.describe Chat::ChannelViewBuilder do before { membership.update!(last_read_message_id: nil) } it "does not error and still returns messages" do - expect(subject.view.chat_messages).to eq([past_message_2, past_message_1, message]) + expect(result.view.chat_messages).to eq([past_message_2, past_message_1, message]) end context "if page_size is nil" do @@ -266,7 +266,7 @@ RSpec.describe Chat::ChannelViewBuilder do .with(has_entries(page_size: Chat::MessagesQuery::MAX_PAGE_SIZE)) .once .returns({ messages: [] }) - subject + result end end end @@ -288,7 +288,7 @@ RSpec.describe Chat::ChannelViewBuilder do let(:target_message_id) { message.id } it "includes the target message as well as past and future messages" do - expect(subject.view.chat_messages).to eq([past_message, message, future_message]) + expect(result.view.chat_messages).to eq([past_message, message, future_message]) end context "when page_size is null" do @@ -303,7 +303,7 @@ RSpec.describe Chat::ChannelViewBuilder do before { message.update!(thread: thread) } it "includes it by default" do - expect(subject.view.chat_messages).to eq( + expect(result.view.chat_messages).to eq( [past_message, message, thread.original_message, future_message], ) end @@ -315,7 +315,7 @@ RSpec.describe Chat::ChannelViewBuilder do end it "does not include the target message" do - expect(subject.view.chat_messages).to eq( + expect(result.view.chat_messages).to eq( [past_message, thread.original_message, future_message], ) end @@ -356,7 +356,7 @@ RSpec.describe Chat::ChannelViewBuilder do let(:target_date) { 2.days.ago } it "includes past and future messages" do - expect(subject.view.chat_messages).to eq([past_message, future_message]) + expect(result.view.chat_messages).to eq([past_message, future_message]) end end end diff --git a/plugins/poll/spec/lib/polls_validator_spec.rb b/plugins/poll/spec/lib/polls_validator_spec.rb index 583a96c80e7..e337db78003 100644 --- a/plugins/poll/spec/lib/polls_validator_spec.rb +++ b/plugins/poll/spec/lib/polls_validator_spec.rb @@ -3,8 +3,9 @@ require "rails_helper" RSpec.describe ::DiscoursePoll::PollsValidator do + subject(:validator) { described_class.new(post) } + let(:post) { Fabricate(:post) } - subject { described_class.new(post) } describe "#validate_polls" do it "ensures that polls have valid arguments" do diff --git a/spec/integration/email_style_spec.rb b/spec/integration/email_style_spec.rb index 1b6aa37a7da..645ed98a70e 100644 --- a/spec/integration/email_style_spec.rb +++ b/spec/integration/email_style_spec.rb @@ -23,11 +23,12 @@ RSpec.describe EmailStyle do end context "with invite" do - fab!(:invite) { Fabricate(:invite) } - let(:invite_mail) { InviteMailer.send_invite(invite) } - subject(:mail_html) { Email::Renderer.new(invite_mail).html } + fab!(:invite) { Fabricate(:invite) } + + let(:invite_mail) { InviteMailer.send_invite(invite) } + it "applies customizations" do expect(mail_html.scan('

FOR YOU

').count).to eq(1) expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}") @@ -48,6 +49,8 @@ RSpec.describe EmailStyle do end context "when user_replied" do + subject(:mail_html) { Email::Renderer.new(mail).html } + let(:response_by_user) { Fabricate(:user, name: "John Doe") } let(:category) { Fabricate(:category, name: "India") } let(:topic) { Fabricate(:topic, category: category, title: "Super cool topic") } @@ -65,8 +68,6 @@ RSpec.describe EmailStyle do ) end - subject(:mail_html) { Email::Renderer.new(mail).html } - it "customizations are applied to html part of emails" do SiteSetting.default_email_in_reply_to = true @@ -80,9 +81,10 @@ RSpec.describe EmailStyle do end context "with signup" do - let(:signup_mail) { UserNotifications.signup(Fabricate(:user)) } subject(:mail_html) { Email::Renderer.new(signup_mail).html } + let(:signup_mail) { UserNotifications.signup(Fabricate(:user)) } + it "customizations are applied to html part of emails" do expect(mail_html.scan('

FOR YOU

').count).to eq(1) expect(mail_html).to include("activate-account") @@ -124,11 +126,13 @@ RSpec.describe EmailStyle do end context "with digest" do + subject(:mail_html) { Email::Renderer.new(summary_email).html } + fab!(:popular_topic) do Fabricate(:topic, user: Fabricate(:coding_horror), created_at: 1.hour.ago) end + let(:summary_email) { UserNotifications.digest(Fabricate(:user)) } - subject(:mail_html) { Email::Renderer.new(summary_email).html } it "customizations are applied to html part of emails" do expect(mail_html.scan('

FOR YOU

').count).to eq(1) diff --git a/spec/jobs/auto_queue_handler_spec.rb b/spec/jobs/auto_queue_handler_spec.rb index f4d1ada3afc..718234c9435 100644 --- a/spec/jobs/auto_queue_handler_spec.rb +++ b/spec/jobs/auto_queue_handler_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe Jobs::AutoQueueHandler do - subject { Jobs::AutoQueueHandler.new.execute({}) } + subject(:job) { Jobs::AutoQueueHandler.new.execute({}) } describe "old flagged post" do fab!(:spam_result) do @@ -23,7 +23,7 @@ RSpec.describe Jobs::AutoQueueHandler do it "defers the old flag if auto_handle_queued_age is 60" do SiteSetting.auto_handle_queued_age = 60 - subject + job expect(not_old.reload).to be_pending expect(old.reload).not_to be_pending expect(post_action.related_post.topic.posts_count).to eq(1) @@ -31,7 +31,7 @@ RSpec.describe Jobs::AutoQueueHandler do it "doesn't defer the old flag if auto_handle_queued_age is 0" do SiteSetting.auto_handle_queued_age = 0 - subject + job expect(not_old.reload).to be_pending expect(old.reload).to be_pending end @@ -45,7 +45,7 @@ RSpec.describe Jobs::AutoQueueHandler do it "rejects the post when auto_handle_queued_age is 60" do SiteSetting.auto_handle_queued_age = 60 - subject + job expect(new_post.reload.pending?).to eq(true) expect(old_post.reload.rejected?).to eq(true) expect(new_user.reload.pending?).to eq(true) @@ -54,7 +54,7 @@ RSpec.describe Jobs::AutoQueueHandler do it "leaves reviewables as pending auto_handle_queued_age is 0" do SiteSetting.auto_handle_queued_age = 0 - subject + job expect(new_post.reload.pending?).to eq(true) expect(new_user.reload.pending?).to eq(true) expect(old_post.reload.pending?).to eq(true) diff --git a/spec/jobs/bookmark_reminder_notifications_spec.rb b/spec/jobs/bookmark_reminder_notifications_spec.rb index 22a9a17f83b..eb6b256da97 100644 --- a/spec/jobs/bookmark_reminder_notifications_spec.rb +++ b/spec/jobs/bookmark_reminder_notifications_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe Jobs::BookmarkReminderNotifications do - subject { described_class.new } + subject(:job) { described_class.new } fab!(:user) { Fabricate(:user) } let(:five_minutes_ago) { Time.zone.now - 5.minutes } @@ -19,7 +19,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do end it "sends every reminder and sets the reminder_last_sent_at" do - subject.execute + job.execute bookmark1.reload bookmark2.reload bookmark3.reload @@ -31,7 +31,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do it "will not send a reminder for a bookmark in the future" do freeze_time bookmark4 = Fabricate(:bookmark, reminder_at: Time.zone.now + 1.day) - expect { subject.execute }.to change { Notification.where(user: user).count }.by(3) + expect { job.execute }.to change { Notification.where(user: user).count }.by(3) expect(bookmark1.reload.reminder_last_sent_at).to eq_time(Time.zone.now) expect(bookmark2.reload.reminder_last_sent_at).to eq_time(Time.zone.now) expect(bookmark3.reload.reminder_last_sent_at).to eq_time(Time.zone.now) @@ -44,7 +44,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do other_bookmark = Fabricate(:bookmark, user: bookmark1.user) other_bookmark.update_column(:reminder_at, five_minutes_ago) SiteSetting.max_bookmarks_per_user = 2 - expect { subject.execute }.not_to raise_error + expect { job.execute }.not_to raise_error end end @@ -52,7 +52,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do it "does not send them in the current run, but will send them in the next" do begin Jobs::BookmarkReminderNotifications.max_reminder_notifications_per_run = 2 - subject.execute + job.execute expect(bookmark1.reload.reminder_last_sent_at).not_to eq(nil) expect(bookmark2.reload.reminder_last_sent_at).not_to eq(nil) expect(bookmark3.reload.reminder_last_sent_at).to eq(nil) @@ -64,7 +64,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do bookmark1.bookmarkable.topic.destroy bookmark2.bookmarkable.topic.destroy bookmark3.bookmarkable.topic.destroy - expect { subject.execute }.not_to change { + expect { job.execute }.not_to change { Notification.where(notification_type: Notification.types[:bookmark_reminder]).count } end diff --git a/spec/jobs/clean_up_associated_accounts_spec.rb b/spec/jobs/clean_up_associated_accounts_spec.rb index cefcac82bde..b9ecb71e837 100644 --- a/spec/jobs/clean_up_associated_accounts_spec.rb +++ b/spec/jobs/clean_up_associated_accounts_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe Jobs::CleanUpAssociatedAccounts do - subject { Jobs::CleanUpAssociatedAccounts.new.execute({}) } + subject(:job) { Jobs::CleanUpAssociatedAccounts.new.execute({}) } it "deletes the correct records" do freeze_time @@ -26,7 +26,7 @@ RSpec.describe Jobs::CleanUpAssociatedAccounts do updated_at: 12.hours.ago, ) - expect { subject }.to change { UserAssociatedAccount.count }.by(-1) + expect { job }.to change { UserAssociatedAccount.count }.by(-1) expect(UserAssociatedAccount.all).to contain_exactly(today, connected) end end diff --git a/spec/jobs/clean_up_crawler_stats_spec.rb b/spec/jobs/clean_up_crawler_stats_spec.rb index 8f954b4334d..0b51f1683ed 100644 --- a/spec/jobs/clean_up_crawler_stats_spec.rb +++ b/spec/jobs/clean_up_crawler_stats_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe Jobs::CleanUpCrawlerStats do - subject { Jobs::CleanUpCrawlerStats.new.execute({}) } + subject(:job) { Jobs::CleanUpCrawlerStats.new.execute({}) } it "deletes records older than 30 days old" do freeze_time @@ -10,7 +10,7 @@ RSpec.describe Jobs::CleanUpCrawlerStats do yesterday = Fabricate(:web_crawler_request, date: 1.day.ago.to_date) too_old = Fabricate(:web_crawler_request, date: 31.days.ago.to_date) - expect { subject }.to change { WebCrawlerRequest.count }.by(-1) + expect { job }.to change { WebCrawlerRequest.count }.by(-1) expect(WebCrawlerRequest.where(id: too_old.id)).to_not exist end @@ -25,7 +25,7 @@ RSpec.describe Jobs::CleanUpCrawlerStats do req2 = Fabricate(:web_crawler_request, date: 1.day.ago.to_date, count: 50) req5 = Fabricate(:web_crawler_request, date: 1.day.ago.to_date, count: 1) - expect { subject }.to change { WebCrawlerRequest.count }.by(-2) + expect { job }.to change { WebCrawlerRequest.count }.by(-2) expect(WebCrawlerRequest.all).to contain_exactly(req1, req2, req3) end end diff --git a/spec/jobs/create_recent_post_search_indexes_spec.rb b/spec/jobs/create_recent_post_search_indexes_spec.rb index 5c5f85dfda3..67a4de9fcc2 100644 --- a/spec/jobs/create_recent_post_search_indexes_spec.rb +++ b/spec/jobs/create_recent_post_search_indexes_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe Jobs::CreateRecentPostSearchIndexes do - subject { described_class.new } + subject(:job) { described_class.new } fab!(:post) { with_search_indexer_enabled { Fabricate(:post) } } fab!(:post_2) { with_search_indexer_enabled { Fabricate(:post) } } @@ -13,7 +13,7 @@ RSpec.describe Jobs::CreateRecentPostSearchIndexes do SiteSetting.search_recent_posts_size = 1 SiteSetting.search_enable_recent_regular_posts_offset_size = 3 - expect do subject.execute({}) end.to_not change { + expect { job.execute({}) }.to_not change { SiteSetting.search_recent_regular_posts_offset_post_id } end @@ -22,7 +22,7 @@ RSpec.describe Jobs::CreateRecentPostSearchIndexes do SiteSetting.search_recent_posts_size = 1 SiteSetting.search_enable_recent_regular_posts_offset_size = 1 - subject.execute({}) + job.execute({}) expect(SiteSetting.search_recent_regular_posts_offset_post_id).to eq(post_2.id) diff --git a/spec/jobs/emit_web_hook_event_spec.rb b/spec/jobs/emit_web_hook_event_spec.rb index efddb33a040..38d024ba94b 100644 --- a/spec/jobs/emit_web_hook_event_spec.rb +++ b/spec/jobs/emit_web_hook_event_spec.rb @@ -3,25 +3,27 @@ require "excon" RSpec.describe Jobs::EmitWebHookEvent do + subject(:job) { described_class.new } + fab!(:post_hook) { Fabricate(:web_hook) } fab!(:inactive_hook) { Fabricate(:inactive_web_hook) } fab!(:post) { Fabricate(:post) } fab!(:user) { Fabricate(:user) } it "raises an error when there is no web hook record" do - expect do subject.execute(event_type: "post", payload: {}) end.to raise_error( + expect { job.execute(event_type: "post", payload: {}) }.to raise_error( Discourse::InvalidParameters, ) end it "raises an error when there is no event type" do - expect do subject.execute(web_hook_id: post_hook.id, payload: {}) end.to raise_error( + expect { job.execute(web_hook_id: post_hook.id, payload: {}) }.to raise_error( Discourse::InvalidParameters, ) end it "raises an error when there is no payload" do - expect do subject.execute(web_hook_id: post_hook.id, event_type: "post") end.to raise_error( + expect { job.execute(web_hook_id: post_hook.id, event_type: "post") }.to raise_error( Discourse::InvalidParameters, ) end @@ -29,7 +31,7 @@ RSpec.describe Jobs::EmitWebHookEvent do it "should not destroy webhook event in case of error" do stub_request(:post, post_hook.payload_url).to_return(status: 500) - subject.execute( + job.execute( web_hook_id: post_hook.id, payload: { id: post.id }.to_json, event_type: WebHookEventType::POST, @@ -53,7 +55,7 @@ RSpec.describe Jobs::EmitWebHookEvent do it "disables the webhook" do expect do - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: described_class::PING_EVENT, retry_count: described_class::MAX_RETRY_COUNT, @@ -62,7 +64,7 @@ RSpec.describe Jobs::EmitWebHookEvent do end it "logs webhook deactivation reason" do - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: described_class::PING_EVENT, retry_count: described_class::MAX_RETRY_COUNT, @@ -86,7 +88,7 @@ RSpec.describe Jobs::EmitWebHookEvent do it "retry if site setting is enabled" do expect do - subject.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) + job.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) end.to change { Jobs::EmitWebHookEvent.jobs.size }.by(1) end @@ -96,13 +98,13 @@ RSpec.describe Jobs::EmitWebHookEvent do expect(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1).to eq(5) expect do - subject.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) + job.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) end.to change { WebHookEvent.count }.by(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1) end it "does not retry for more than maximum allowed times" do expect do - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: described_class::PING_EVENT, retry_count: described_class::MAX_RETRY_COUNT, @@ -114,13 +116,13 @@ RSpec.describe Jobs::EmitWebHookEvent do SiteSetting.retry_web_hook_events = false expect do - subject.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) + job.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) end.not_to change { Jobs::EmitWebHookEvent.jobs.size } end it "properly logs error on rescue" do stub_request(:post, post_hook.payload_url).to_raise("connection error") - subject.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) + job.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) event = WebHookEvent.last expect(event.payload).to eq(MultiJson.dump(ping: "OK")) @@ -133,11 +135,11 @@ RSpec.describe Jobs::EmitWebHookEvent do it "does not raise an error for a ping event without payload" do stub_request(:post, post_hook.payload_url).to_return(body: "OK", status: 200) - subject.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) + job.execute(web_hook_id: post_hook.id, event_type: described_class::PING_EVENT) end it "doesn't emit when the hook is inactive" do - subject.execute( + job.execute( web_hook_id: inactive_hook.id, event_type: "post", payload: { test: "some payload" }.to_json, @@ -149,7 +151,7 @@ RSpec.describe Jobs::EmitWebHookEvent do body: "{\"post\":{\"test\":\"some payload\"}}", ).to_return(body: "OK", status: 200) - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: "post", payload: { test: "some payload" }.to_json, @@ -158,7 +160,7 @@ RSpec.describe Jobs::EmitWebHookEvent do it "doesn't emit if the payload URL resolves to a disallowed IP" do FinalDestination::TestHelper.stub_to_fail do - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: "post", payload: { test: "some payload" }.to_json, @@ -179,7 +181,7 @@ RSpec.describe Jobs::EmitWebHookEvent do fab!(:topic_hook) { Fabricate(:topic_web_hook, categories: [category]) } it "doesn't emit when event is not related with defined categories" do - subject.execute( + job.execute( web_hook_id: topic_hook.id, event_type: "topic", category_id: topic.category.id, @@ -192,7 +194,7 @@ RSpec.describe Jobs::EmitWebHookEvent do body: "{\"topic\":{\"test\":\"some payload\"}}", ).to_return(body: "OK", status: 200) - subject.execute( + job.execute( web_hook_id: topic_hook.id, event_type: "topic", category_id: topic_with_category.category.id, @@ -207,7 +209,7 @@ RSpec.describe Jobs::EmitWebHookEvent do fab!(:topic_hook) { Fabricate(:topic_web_hook, tags: [tag]) } it "doesn't emit when event is not included any tags" do - subject.execute( + job.execute( web_hook_id: topic_hook.id, event_type: "topic", payload: { test: "some payload" }.to_json, @@ -215,7 +217,7 @@ RSpec.describe Jobs::EmitWebHookEvent do end it "doesn't emit when event is not related with defined tags" do - subject.execute( + job.execute( web_hook_id: topic_hook.id, event_type: "topic", tag_ids: [Fabricate(:tag).id], @@ -228,7 +230,7 @@ RSpec.describe Jobs::EmitWebHookEvent do body: "{\"topic\":{\"test\":\"some payload\"}}", ).to_return(body: "OK", status: 200) - subject.execute( + job.execute( web_hook_id: topic_hook.id, event_type: "topic", tag_ids: topic.tags.pluck(:id), @@ -243,7 +245,7 @@ RSpec.describe Jobs::EmitWebHookEvent do fab!(:like_hook) { Fabricate(:like_web_hook, groups: [group]) } it "doesn't emit when event is not included any groups" do - subject.execute( + job.execute( web_hook_id: like_hook.id, event_type: "like", payload: { test: "some payload" }.to_json, @@ -251,7 +253,7 @@ RSpec.describe Jobs::EmitWebHookEvent do end it "doesn't emit when event is not related with defined groups" do - subject.execute( + job.execute( web_hook_id: like_hook.id, event_type: "like", group_ids: [Fabricate(:group).id], @@ -264,7 +266,7 @@ RSpec.describe Jobs::EmitWebHookEvent do body: "{\"like\":{\"test\":\"some payload\"}}", ).to_return(body: "OK", status: 200) - subject.execute( + job.execute( web_hook_id: like_hook.id, event_type: "like", group_ids: user.groups.pluck(:id), @@ -281,7 +283,7 @@ RSpec.describe Jobs::EmitWebHookEvent do web_hook_id = Fabricate("#{topic_event_type.name}_web_hook").id expect do - subject.execute( + job.execute( web_hook_id: web_hook_id, event_type: topic_event_type.name, payload: { test: "some payload" }.to_json, @@ -298,7 +300,7 @@ RSpec.describe Jobs::EmitWebHookEvent do status: 200, ) - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: described_class::PING_EVENT, event_name: described_class::PING_EVENT, @@ -324,7 +326,7 @@ RSpec.describe Jobs::EmitWebHookEvent do it "sets up proper request headers when an error raised" do stub_request(:post, post_hook.payload_url).to_raise("error") - subject.execute( + job.execute( web_hook_id: post_hook.id, event_type: described_class::PING_EVENT, event_name: described_class::PING_EVENT, diff --git a/spec/jobs/enqueue_suspect_users_spec.rb b/spec/jobs/enqueue_suspect_users_spec.rb index 125e2e0de4c..7ddaada92ea 100644 --- a/spec/jobs/enqueue_suspect_users_spec.rb +++ b/spec/jobs/enqueue_suspect_users_spec.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true RSpec.describe Jobs::EnqueueSuspectUsers do + subject(:job) { described_class.new } + before { SiteSetting.approve_suspect_users = true } it "does nothing when there are no suspect users" do - subject.execute({}) + job.execute({}) expect(ReviewableUser.count).to be_zero end @@ -13,7 +15,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do let!(:suspect_user) { Fabricate(:active_user, created_at: 1.day.ago) } it "creates a reviewable when there is a suspect user" do - subject.execute({}) + job.execute({}) expect(ReviewableUser.count).to eq(1) end @@ -26,14 +28,14 @@ RSpec.describe Jobs::EnqueueSuspectUsers do reviewable_by_moderator: true, ) - subject.execute({}) + job.execute({}) expect(ReviewableUser.count).to eq(1) expect(ReviewableUser.last).to eq(review_user) end it "adds a score" do - subject.execute({}) + job.execute({}) score = ReviewableScore.last expect(score.reason).to eq("suspect_user") @@ -42,7 +44,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do it "only enqueues non-approved users" do suspect_user.update!(approved: true) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false) end @@ -51,7 +53,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do SiteSetting.must_approve_users = true suspect_user.update!(approved: false) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false) end @@ -59,7 +61,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do it "ignores users created more than six months ago" do suspect_user.update!(created_at: 1.year.ago) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false) end @@ -67,7 +69,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do it "ignores users that were imported from another site" do suspect_user.upsert_custom_fields({ import_id: "fake_id" }) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false) end @@ -75,7 +77,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do it "enqueues a suspect users with custom fields" do suspect_user.upsert_custom_fields({ field_a: "value", field_b: "value" }) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(true) end @@ -85,7 +87,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do { field_a: "value", field_b: "value", import_id: "fake_id" }, ) - subject.execute({}) + job.execute({}) expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false) end @@ -97,7 +99,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do time_read: 30.seconds.to_i, ) - subject.execute({}) + job.execute({}) expect(ReviewableUser.count).to eq(1) end @@ -109,7 +111,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do time_read: 2.minutes.to_i, ) - subject.execute({}) + job.execute({}) expect(ReviewableUser.count).to eq(0) end diff --git a/spec/jobs/ensure_s3_uploads_existence_spec.rb b/spec/jobs/ensure_s3_uploads_existence_spec.rb index 84d6e6c812a..846f58b5a5b 100644 --- a/spec/jobs/ensure_s3_uploads_existence_spec.rb +++ b/spec/jobs/ensure_s3_uploads_existence_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.describe Jobs::EnsureS3UploadsExistence do + subject(:job) { described_class.new } + context "with S3 inventory enabled" do before do setup_s3 @@ -9,21 +11,21 @@ RSpec.describe Jobs::EnsureS3UploadsExistence do it "works" do S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once - subject.execute({}) + job.execute({}) end it "doesn't execute when the site was restored within the last 48 hours" do S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).never BackupMetadata.update_last_restore_date(47.hours.ago) - subject.execute({}) + job.execute({}) end it "executes when the site was restored more than 48 hours ago" do S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once BackupMetadata.update_last_restore_date(49.hours.ago) - subject.execute({}) + job.execute({}) end end @@ -32,7 +34,7 @@ RSpec.describe Jobs::EnsureS3UploadsExistence do it "doesn't execute" do S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).never - subject.execute({}) + job.execute({}) end end end diff --git a/spec/jobs/ignored_users_summary_spec.rb b/spec/jobs/ignored_users_summary_spec.rb index 461d94081a2..465ed1b3b0f 100644 --- a/spec/jobs/ignored_users_summary_spec.rb +++ b/spec/jobs/ignored_users_summary_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true RSpec.describe Jobs::IgnoredUsersSummary do + subject(:job) { Jobs::IgnoredUsersSummary.new.execute({}) } + before do SiteSetting.ignored_users_count_message_threshold = 1 SiteSetting.ignored_users_message_gap_days = 365 end - subject { Jobs::IgnoredUsersSummary.new.execute({}) } - context "with no ignored users" do it "does nothing" do - subject - expect { subject }.to_not change { Post.count } + job + expect { job }.to_not change { Post.count } end end @@ -30,14 +30,14 @@ RSpec.describe Jobs::IgnoredUsersSummary do before { SiteSetting.ignored_users_count_message_threshold = 5 } it "does nothing" do - subject - expect { subject }.to_not change { Post.count } + job + expect { job }.to_not change { Post.count } end end context "when threshold is hit" do it "creates a system message" do - subject + job posts = Post.joins(:topic).where( topics: { @@ -57,15 +57,15 @@ RSpec.describe Jobs::IgnoredUsersSummary do before { SiteSetting.ignored_users_count_message_threshold = 5 } it "does nothing" do - subject - expect { subject }.to_not change { Post.count } + job + expect { job }.to_not change { Post.count } end end context "when threshold is hit" do it "does nothing" do - subject - expect { subject }.to_not change { Post.count } + job + expect { job }.to_not change { Post.count } end end end diff --git a/spec/jobs/invalidate_inactive_admins_spec.rb b/spec/jobs/invalidate_inactive_admins_spec.rb index 7c070aa5c1d..03707dfed90 100644 --- a/spec/jobs/invalidate_inactive_admins_spec.rb +++ b/spec/jobs/invalidate_inactive_admins_spec.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true RSpec.describe Jobs::InvalidateInactiveAdmins do - fab!(:active_admin) { Fabricate(:admin, last_seen_at: 1.hour.ago) } - before { active_admin.email_tokens.update_all(confirmed: true) } + subject(:job) { Jobs::InvalidateInactiveAdmins.new.execute({}) } - subject { Jobs::InvalidateInactiveAdmins.new.execute({}) } + fab!(:active_admin) { Fabricate(:admin, last_seen_at: 1.hour.ago) } + + before { active_admin.email_tokens.update_all(confirmed: true) } it "does nothing when all admins have been seen recently" do SiteSetting.invalidate_inactive_admin_email_after_days = 365 - subject + job expect(active_admin.reload.active).to eq(true) expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true) end @@ -21,12 +22,12 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do before { SiteSetting.invalidate_inactive_admin_email_after_days = 365 } it "marks email tokens as unconfirmed" do - subject + job expect(not_seen_admin.reload.email_tokens.where(confirmed: true).exists?).to eq(false) end it "makes the user as not active and logs the action" do - subject + job expect(not_seen_admin.reload.active).to eq(false) log = UserHistory.last @@ -35,7 +36,7 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do end it "adds a staff log" do - subject + job expect(not_seen_admin.reload.active).to eq(false) end @@ -52,20 +53,20 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do end it "removes the social logins" do - subject + job expect(UserAssociatedAccount.where(user_id: not_seen_admin.id).exists?).to eq(false) end end it "doesn't deactivate admins with recent posts" do Fabricate(:post, user: not_seen_admin) - subject + job expect(not_seen_admin.reload.active).to eq(true) end it "doesn't deactivate admins with recently used api keys" do Fabricate(:api_key, user: not_seen_admin, last_used_at: 1.day.ago) - subject + job expect(not_seen_admin.reload.active).to eq(true) end end @@ -74,7 +75,7 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do before { SiteSetting.invalidate_inactive_admin_email_after_days = 0 } it "does nothing" do - subject + job expect(active_admin.reload.active).to eq(true) expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true) expect(not_seen_admin.reload.active).to eq(true) diff --git a/spec/jobs/post_update_topic_tracking_state_spec.rb b/spec/jobs/post_update_topic_tracking_state_spec.rb index 442f5574018..144887a9ddb 100644 --- a/spec/jobs/post_update_topic_tracking_state_spec.rb +++ b/spec/jobs/post_update_topic_tracking_state_spec.rb @@ -1,16 +1,18 @@ # frozen_string_literal: true RSpec.describe Jobs::PostUpdateTopicTrackingState do + subject(:job) { described_class.new } + fab!(:post) { Fabricate(:post) } it "should publish messages" do - messages = MessageBus.track_publish { subject.execute({ post_id: post.id }) } + messages = MessageBus.track_publish { job.execute({ post_id: post.id }) } expect(messages.size).not_to eq(0) end it "should not publish messages for deleted topics" do post.topic.trash! - messages = MessageBus.track_publish { subject.execute({ post_id: post.id }) } + messages = MessageBus.track_publish { job.execute({ post_id: post.id }) } expect(messages.size).to eq(0) end end diff --git a/spec/jobs/process_shelved_notifications_spec.rb b/spec/jobs/process_shelved_notifications_spec.rb index f0e419f733c..44146c57147 100644 --- a/spec/jobs/process_shelved_notifications_spec.rb +++ b/spec/jobs/process_shelved_notifications_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.describe Jobs::ProcessShelvedNotifications do + subject(:job) { described_class.new } + fab!(:user) { Fabricate(:user) } let(:post) { Fabricate(:post) } @@ -8,7 +10,7 @@ RSpec.describe Jobs::ProcessShelvedNotifications do future = Fabricate(:do_not_disturb_timing, ends_at: 1.day.from_now) past = Fabricate(:do_not_disturb_timing, starts_at: 2.day.ago, ends_at: 1.minute.ago) - expect { subject.execute({}) }.to change { DoNotDisturbTiming.count }.by (-1) + expect { job.execute({}) }.to change { DoNotDisturbTiming.count }.by (-1) expect(DoNotDisturbTiming.find_by(id: future.id)).to eq(future) expect(DoNotDisturbTiming.find_by(id: past.id)).to eq(nil) end @@ -25,7 +27,7 @@ RSpec.describe Jobs::ProcessShelvedNotifications do notification_type: 1, ) expect(notification.shelved_notification).to be_present - subject.execute({}) + job.execute({}) expect(notification.shelved_notification).to be_present end @@ -43,7 +45,7 @@ RSpec.describe Jobs::ProcessShelvedNotifications do user.do_not_disturb_timings.last.update(ends_at: 1.days.ago) expect(notification.shelved_notification).to be_present - subject.execute({}) + job.execute({}) expect { notification.shelved_notification.reload }.to raise_error(ActiveRecord::RecordNotFound) end end diff --git a/spec/jobs/pull_hotlinked_images_spec.rb b/spec/jobs/pull_hotlinked_images_spec.rb index 3f842c275c1..e722cd35e99 100644 --- a/spec/jobs/pull_hotlinked_images_spec.rb +++ b/spec/jobs/pull_hotlinked_images_spec.rb @@ -472,25 +472,25 @@ RSpec.describe Jobs::PullHotlinkedImages do end describe "#should_download_image?" do - subject { described_class.new } + subject(:job) { described_class.new } describe "when url is invalid" do it "should return false" do - expect(subject.should_download_image?("null")).to eq(false) - expect(subject.should_download_image?("meta.discourse.org")).to eq(false) + expect(job.should_download_image?("null")).to eq(false) + expect(job.should_download_image?("meta.discourse.org")).to eq(false) end end describe "when url is valid" do it "should return true" do - expect(subject.should_download_image?("http://meta.discourse.org")).to eq(true) - expect(subject.should_download_image?("//meta.discourse.org")).to eq(true) + expect(job.should_download_image?("http://meta.discourse.org")).to eq(true) + expect(job.should_download_image?("//meta.discourse.org")).to eq(true) end end describe "when url is an upload" do it "should return false for original" do - expect(subject.should_download_image?(Fabricate(:upload).url)).to eq(false) + expect(job.should_download_image?(Fabricate(:upload).url)).to eq(false) end context "when secure uploads enabled" do @@ -501,19 +501,19 @@ RSpec.describe Jobs::PullHotlinkedImages do upload = Fabricate(:upload_s3, secure: true) stub_s3(upload) url = Upload.secure_uploads_url_from_upload_url(upload.url) - expect(subject.should_download_image?(url)).to eq(false) + expect(job.should_download_image?(url)).to eq(false) end end it "should return true for optimized" do src = Discourse.store.get_path_for_optimized_image(Fabricate(:optimized_image)) - expect(subject.should_download_image?(src)).to eq(true) + expect(job.should_download_image?(src)).to eq(true) end end it "returns false for emoji" do src = Emoji.url_for("testemoji.png") - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end it "returns false for emoji when app and S3 CDNs configured" do @@ -522,14 +522,14 @@ RSpec.describe Jobs::PullHotlinkedImages do set_cdn_url "https://mydomain.cdn/test" src = UrlHelper.cook_url(Emoji.url_for("testemoji.png")) - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end it "returns false for emoji when emoji CDN configured" do SiteSetting.external_emoji_url = "https://emoji.cdn.com" src = UrlHelper.cook_url(Emoji.url_for("testemoji.png")) - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end it "returns false for emoji when app, S3 *and* emoji CDNs configured" do @@ -539,17 +539,17 @@ RSpec.describe Jobs::PullHotlinkedImages do set_cdn_url "https://mydomain.cdn/test" src = UrlHelper.cook_url(Emoji.url_for("testemoji.png")) - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end it "returns false for plugin assets" do src = UrlHelper.cook_url("/plugins/discourse-amazing-plugin/myasset.png") - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end it "returns false for local non-uploaded files" do src = UrlHelper.cook_url("/mycustomroute.png") - expect(subject.should_download_image?(src)).to eq(false) + expect(job.should_download_image?(src)).to eq(false) end context "when download_remote_images_to_local? is false" do @@ -557,11 +557,11 @@ RSpec.describe Jobs::PullHotlinkedImages do it "still returns true for optimized" do src = Discourse.store.get_path_for_optimized_image(Fabricate(:optimized_image)) - expect(subject.should_download_image?(src)).to eq(true) + expect(job.should_download_image?(src)).to eq(true) end it "returns false for valid remote URLs" do - expect(subject.should_download_image?("http://meta.discourse.org")).to eq(false) + expect(job.should_download_image?("http://meta.discourse.org")).to eq(false) end end end diff --git a/spec/jobs/purge_expired_ignored_users_spec.rb b/spec/jobs/purge_expired_ignored_users_spec.rb index 67f74e53310..90e4c6e86c4 100644 --- a/spec/jobs/purge_expired_ignored_users_spec.rb +++ b/spec/jobs/purge_expired_ignored_users_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true RSpec.describe Jobs::PurgeExpiredIgnoredUsers do - subject { Jobs::PurgeExpiredIgnoredUsers.new.execute({}) } + subject(:job) { Jobs::PurgeExpiredIgnoredUsers.new.execute({}) } context "with no ignored users" do it "does nothing" do - expect { subject }.to_not change { IgnoredUser.count } + expect { job }.to_not change { IgnoredUser.count } end end @@ -21,7 +21,7 @@ RSpec.describe Jobs::PurgeExpiredIgnoredUsers do context "when no expired ignored users" do it "does nothing" do - expect { subject }.to_not change { IgnoredUser.count } + expect { job }.to_not change { IgnoredUser.count } end end @@ -32,7 +32,7 @@ RSpec.describe Jobs::PurgeExpiredIgnoredUsers do Fabricate(:ignored_user, user: tarek, ignored_user: fred, expiring_at: 1.month.from_now) freeze_time(2.months.from_now) do - subject + job expect(IgnoredUser.find_by(ignored_user: fred)).to be_nil end end diff --git a/spec/jobs/regular/group_smtp_email_spec.rb b/spec/jobs/regular/group_smtp_email_spec.rb index 475e939d9b1..25108a6d2a1 100644 --- a/spec/jobs/regular/group_smtp_email_spec.rb +++ b/spec/jobs/regular/group_smtp_email_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.describe Jobs::GroupSmtpEmail do + subject(:job) { described_class.new } + fab!(:topic) { Fabricate(:private_message_topic, title: "Help I need support") } fab!(:post) do Fabricate(:post, topic: topic, raw: "some first post content") @@ -46,11 +48,11 @@ RSpec.describe Jobs::GroupSmtpEmail do bcc_addresses: [], ) .returns(message) - subject.execute(args) + job.execute(args) end it "includes a 'reply above this line' message" do - subject.execute(args) + job.execute(args) email_log = EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id) expect(email_log.as_mail_message.html_part.to_s).to include( @@ -59,7 +61,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "does not include context posts" do - subject.execute(args) + job.execute(args) email_log = EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id) expect(email_log.as_mail_message.text_part.to_s).not_to include( @@ -72,7 +74,7 @@ RSpec.describe Jobs::GroupSmtpEmail do second_post = topic.posts.find_by(post_number: 2) post.update!(reply_to_post_number: 1, reply_to_user: second_post.user) PostReply.create(post: second_post, reply: post) - subject.execute(args) + job.execute(args) email_log = EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id) expect(email_log.raw_headers).to include( @@ -84,7 +86,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "includes the participants in the correct format (but not the recipient user), and does not have links for the staged users" do - subject.execute(args) + job.execute(args) email_log = EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id) email_text = email_log.as_mail_message.text_part.to_s @@ -98,7 +100,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "creates an EmailLog record with the correct details" do - subject.execute(args) + job.execute(args) email_log = EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id) expect(email_log).not_to eq(nil) @@ -106,7 +108,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "creates an IncomingEmail record with the correct details to avoid double processing IMAP" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") incoming_email = @@ -120,7 +122,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "does not create a post reply key, it always replies to the group email_username" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") email_log = @@ -132,7 +134,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "creates an EmailLog record with the correct details" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") email_log = @@ -142,7 +144,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "creates an IncomingEmail record with the correct details to avoid double processing IMAP" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") incoming_email = @@ -156,7 +158,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "does not create a post reply key, it always replies to the group email_username" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") email_log = @@ -169,7 +171,7 @@ RSpec.describe Jobs::GroupSmtpEmail do it "falls back to the group name if full name is blank" do group.update(full_name: "") - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") email_log = @@ -178,7 +180,7 @@ RSpec.describe Jobs::GroupSmtpEmail do end it "has the group_smtp_id and the to_address filled in correctly" do - subject.execute(args) + job.execute(args) expect(ActionMailer::Base.deliveries.count).to eq(1) expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support") email_log = @@ -190,7 +192,7 @@ RSpec.describe Jobs::GroupSmtpEmail do it "drops malformed cc addresses when sending the email" do args2 = args.clone args2[:cc_emails] << "somebadccemail@test.com"]) end it "generates an outbound_message_id in the correct format if it's blank for the post" do post.update!(outbound_message_id: nil) - result = subject.generate_or_use_existing(post.id) + result = described_class.generate_or_use_existing(post.id) expect(result).to eq([""]) end @@ -39,7 +37,7 @@ RSpec.describe Email::MessageIdService do ) post_bulk4 = Fabricate(:post, topic: topic, created_at: 3.days.ago, outbound_message_id: nil) result = - subject.generate_or_use_existing( + described_class.generate_or_use_existing( [post_bulk1.id, post_bulk2.id, post_bulk3.id, post_bulk4.id], ) expect(result).to eq( @@ -63,36 +61,43 @@ RSpec.describe Email::MessageIdService do end it "finds a post based only on a post-format message id" do - expect(subject.find_post_from_message_ids([post_format_message_id])).to eq(post) + expect(described_class.find_post_from_message_ids([post_format_message_id])).to eq(post) end it "finds a post based only on a topic-format message id" do - expect(subject.find_post_from_message_ids([topic_format_message_id])).to eq(post) + expect(described_class.find_post_from_message_ids([topic_format_message_id])).to eq(post) end it "finds a post based only on a discourse-format message id" do - expect(subject.find_post_from_message_ids([discourse_format_message_id])).to eq(post) + expect(described_class.find_post_from_message_ids([discourse_format_message_id])).to eq(post) end it "finds a post from the post's outbound_message_id" do - post.update!(outbound_message_id: subject.message_id_clean(discourse_format_message_id)) - expect(subject.find_post_from_message_ids([discourse_format_message_id])).to eq(post) + post.update!( + outbound_message_id: described_class.message_id_clean(discourse_format_message_id), + ) + expect(described_class.find_post_from_message_ids([discourse_format_message_id])).to eq(post) end it "finds a post from the email log" do email_log = - Fabricate(:email_log, message_id: subject.message_id_clean(default_format_message_id)) - expect(subject.find_post_from_message_ids([default_format_message_id])).to eq(email_log.post) + Fabricate( + :email_log, + message_id: described_class.message_id_clean(default_format_message_id), + ) + expect(described_class.find_post_from_message_ids([default_format_message_id])).to eq( + email_log.post, + ) end it "finds a post from the incoming email log" do incoming_email = Fabricate( :incoming_email, - message_id: subject.message_id_clean(gmail_format_message_id), + message_id: described_class.message_id_clean(gmail_format_message_id), post: Fabricate(:post), ) - expect(subject.find_post_from_message_ids([gmail_format_message_id])).to eq( + expect(described_class.find_post_from_message_ids([gmail_format_message_id])).to eq( incoming_email.post, ) end @@ -101,16 +106,16 @@ RSpec.describe Email::MessageIdService do incoming_email = Fabricate( :incoming_email, - message_id: subject.message_id_clean(post_format_message_id), + message_id: described_class.message_id_clean(post_format_message_id), post: Fabricate(:post, created_at: 10.days.ago), ) - expect(subject.find_post_from_message_ids([post_format_message_id])).to eq(post) + expect(described_class.find_post_from_message_ids([post_format_message_id])).to eq(post) end end describe "#discourse_generated_message_id?" do def check_format(message_id) - subject.discourse_generated_message_id?(message_id) + described_class.discourse_generated_message_id?(message_id) end it "works correctly for the different possible formats" do diff --git a/spec/lib/onebox/engine/google_maps_onebox_spec.rb b/spec/lib/onebox/engine/google_maps_onebox_spec.rb index 4ccecf62ef5..fab528a6799 100644 --- a/spec/lib/onebox/engine/google_maps_onebox_spec.rb +++ b/spec/lib/onebox/engine/google_maps_onebox_spec.rb @@ -53,6 +53,16 @@ RSpec.describe Onebox::Engine::GoogleMapsOnebox do } # Register URL redirects + # Prevent sleep from wasting our time when we test with strange redirects + subject(:onebox) do + described_class + .send(:allocate) + .tap do |obj| + obj.stubs(:sleep) + obj.send(:initialize, link) + end + end + before do URLS.values.each do |t| status, location = *t[:redirect] @@ -62,27 +72,17 @@ RSpec.describe Onebox::Engine::GoogleMapsOnebox do end end - # Prevent sleep from wasting our time when we test with strange redirects - subject do - described_class - .send(:allocate) - .tap do |obj| - obj.stubs(:sleep) - obj.send(:initialize, link) - end - end - - let(:data) { Onebox::Helpers.symbolize_keys(subject.send(:data)) } + let(:data) { Onebox::Helpers.symbolize_keys(onebox.send(:data)) } let(:link) { |example| URLS[example.metadata[:urltype] || :short][:test] } include_context "an engine", urltype: :short URLS.each do |kind, t| it "processes #{kind.to_s} url correctly", urltype: kind do - expect(subject.url).to eq t[:expect] - expect(subject.streetview?).to t[:streetview] ? be_truthy : be_falsey - expect(subject.to_html).to include("") - subject.revise!(changed_by, raw: "So, post them here!\n#{url}") + post_revisor.revise!(changed_by, raw: "So, post them here!\n#{url}") end it "allows an admin to insert images into a new user's post" do @@ -856,7 +866,7 @@ RSpec.describe PostRevisor do SiteSetting.newuser_max_embedded_media = 0 url = "http://i.imgur.com/FGg7Vzu.gif" Oneboxer.stubs(:cached_onebox).with(url, anything).returns("") - subject.revise!(post.user, raw: "So, post them here!\n#{url}") + post_revisor.revise!(post.user, raw: "So, post them here!\n#{url}") end it "doesn't allow images to be inserted" do @@ -868,7 +878,7 @@ RSpec.describe PostRevisor do before { SiteSetting.editing_grace_period_max_diff = 1000 } fab!(:changed_by) { coding_horror } - let!(:result) { subject.revise!(changed_by, raw: "lets update the body. Здравствуйте") } + let!(:result) { post_revisor.revise!(changed_by, raw: "lets update the body. Здравствуйте") } it "correctly updates raw" do expect(result).to eq(true) @@ -886,7 +896,7 @@ RSpec.describe PostRevisor do end it "increases the post_edits stat count" do - expect do subject.revise!(post.user, { raw: "This is a new revision" }) end.to change { + expect do post_revisor.revise!(post.user, { raw: "This is a new revision" }) end.to change { post.user.user_stat.post_edits_count.to_i }.by(1) end @@ -894,7 +904,7 @@ RSpec.describe PostRevisor do context "when second poster posts again quickly" do it "is a grace period edit, because the second poster posted again quickly" do SiteSetting.editing_grace_period = 1.minute - subject.revise!( + post_revisor.revise!( changed_by, { raw: "yet another updated body" }, revised_at: post.updated_at + 10.seconds, @@ -909,7 +919,7 @@ RSpec.describe PostRevisor do context "when passing skip_revision as true" do before do SiteSetting.editing_grace_period = 1.minute - subject.revise!( + post_revisor.revise!( changed_by, { raw: "yet another updated body" }, revised_at: post.updated_at + 10.hours, @@ -928,7 +938,7 @@ RSpec.describe PostRevisor do context "when editing the before_edit_post event signature" do it "contains post and params" do params = { raw: "body (edited)" } - events = DiscourseEvent.track_events { subject.revise!(user, params) } + events = DiscourseEvent.track_events { post_revisor.revise!(user, params) } expect(events).to include(event_name: :before_edit_post, params: [post, params]) end end @@ -955,7 +965,7 @@ RSpec.describe PostRevisor do end it "doesn't strip starting whitespaces" do - subject.revise!(post.user, raw: " <-- whitespaces --> ") + post_revisor.revise!(post.user, raw: " <-- whitespaces --> ") post.reload expect(post.raw).to eq(" <-- whitespaces -->") end @@ -963,20 +973,24 @@ RSpec.describe PostRevisor do it "revises and tracks changes of topic titles" do new_title = "New topic title" result = - subject.revise!(post.user, { title: new_title }, revised_at: post.updated_at + 10.minutes) + post_revisor.revise!( + post.user, + { title: new_title }, + revised_at: post.updated_at + 10.minutes, + ) expect(result).to eq(true) post.reload expect(post.topic.title).to eq(new_title) expect(post.revisions.first.modifications["title"][1]).to eq(new_title) - expect(subject.topic_title_changed?).to eq(true) - expect(subject.raw_changed?).to eq(false) + expect(post_revisor.topic_title_changed?).to eq(true) + expect(post_revisor.raw_changed?).to eq(false) end it "revises and tracks changes of topic archetypes" do new_archetype = Archetype.banner result = - subject.revise!( + post_revisor.revise!( post.user, { archetype: new_archetype }, revised_at: post.updated_at + 10.minutes, @@ -986,21 +1000,21 @@ RSpec.describe PostRevisor do post.reload expect(post.topic.archetype).to eq(new_archetype) expect(post.revisions.first.modifications["archetype"][1]).to eq(new_archetype) - expect(subject.raw_changed?).to eq(false) + expect(post_revisor.raw_changed?).to eq(false) end it "revises and tracks changes of topic tags" do - subject.revise!(admin, tags: ["new-tag"]) + post_revisor.revise!(admin, tags: ["new-tag"]) expect(post.post_revisions.last.modifications).to eq("tags" => [[], ["new-tag"]]) - expect(subject.raw_changed?).to eq(false) + expect(post_revisor.raw_changed?).to eq(false) - subject.revise!(admin, tags: %w[new-tag new-tag-2]) + post_revisor.revise!(admin, tags: %w[new-tag new-tag-2]) expect(post.post_revisions.last.modifications).to eq("tags" => [[], %w[new-tag new-tag-2]]) - expect(subject.raw_changed?).to eq(false) + expect(post_revisor.raw_changed?).to eq(false) - subject.revise!(admin, tags: ["new-tag-3"]) + post_revisor.revise!(admin, tags: ["new-tag-3"]) expect(post.post_revisions.last.modifications).to eq("tags" => [[], ["new-tag-3"]]) - expect(subject.raw_changed?).to eq(false) + expect(post_revisor.raw_changed?).to eq(false) end describe "#publish_changes" do @@ -1023,14 +1037,14 @@ RSpec.describe PostRevisor do context "when logging staff edits" do it "doesn't log when a regular user revises a post" do - subject.revise!(post.user, raw: "lets totally update the body") + post_revisor.revise!(post.user, raw: "lets totally update the body") log = UserHistory.where(acting_user_id: post.user.id, action: UserHistory.actions[:post_edit]) expect(log).to be_blank end it "logs an edit when a staff member revises a post" do - subject.revise!(moderator, raw: "lets totally update the body") + post_revisor.revise!(moderator, raw: "lets totally update the body") log = UserHistory.where( acting_user_id: moderator.id, @@ -1041,7 +1055,11 @@ RSpec.describe PostRevisor do end it "doesn't log an edit when skip_staff_log is true" do - subject.revise!(moderator, { raw: "lets totally update the body" }, skip_staff_log: true) + post_revisor.revise!( + moderator, + { raw: "lets totally update the body" }, + skip_staff_log: true, + ) log = UserHistory.where( acting_user_id: moderator.id, @@ -1095,7 +1113,7 @@ RSpec.describe PostRevisor do before { SiteSetting.staff_edit_locks_post = false } it "does not lock the post when revised" do - result = subject.revise!(moderator, raw: "lets totally update the body") + result = post_revisor.revise!(moderator, raw: "lets totally update the body") expect(result).to eq(true) post.reload expect(post).not_to be_locked @@ -1106,7 +1124,7 @@ RSpec.describe PostRevisor do before { SiteSetting.staff_edit_locks_post = true } it "locks the post when revised by staff" do - result = subject.revise!(moderator, raw: "lets totally update the body") + result = post_revisor.revise!(moderator, raw: "lets totally update the body") expect(result).to eq(true) post.reload expect(post).to be_locked @@ -1114,14 +1132,14 @@ RSpec.describe PostRevisor do it "doesn't lock the wiki posts" do post.wiki = true - result = subject.revise!(moderator, raw: "some new raw content") + result = post_revisor.revise!(moderator, raw: "some new raw content") expect(result).to eq(true) post.reload expect(post).not_to be_locked end it "doesn't lock the post when the raw did not change" do - result = subject.revise!(moderator, title: "New topic title, cool!") + result = post_revisor.revise!(moderator, title: "New topic title, cool!") expect(result).to eq(true) post.reload expect(post.topic.title).to eq("New topic title, cool!") @@ -1129,14 +1147,15 @@ RSpec.describe PostRevisor do end it "doesn't lock the post when revised by a regular user" do - result = subject.revise!(user, raw: "lets totally update the body") + result = post_revisor.revise!(user, raw: "lets totally update the body") expect(result).to eq(true) post.reload expect(post).not_to be_locked end it "doesn't lock the post when revised by system user" do - result = subject.revise!(Discourse.system_user, raw: "I usually replace hotlinked images") + result = + post_revisor.revise!(Discourse.system_user, raw: "I usually replace hotlinked images") expect(result).to eq(true) post.reload expect(post).not_to be_locked @@ -1161,13 +1180,16 @@ RSpec.describe PostRevisor do it "generates a notification for a mention" do expect { - subject.revise!(user, raw: "Random user is mentioning @#{mentioned_user.username_lower}") + post_revisor.revise!( + user, + raw: "Random user is mentioning @#{mentioned_user.username_lower}", + ) }.to change { Notification.where(notification_type: Notification.types[:mentioned]).count } end it "never generates a notification for a mention when the System user revise a post" do expect { - subject.revise!( + post_revisor.revise!( Discourse.system_user, raw: "System user is mentioning @#{mentioned_user.username_lower}", ) @@ -1183,7 +1205,11 @@ RSpec.describe PostRevisor do it "doesn't add the tags" do result = - subject.revise!(user, raw: "lets totally update the body", tags: %w[totally update]) + post_revisor.revise!( + user, + raw: "lets totally update the body", + tags: %w[totally update], + ) expect(result).to eq(true) post.reload expect(post.topic.tags.size).to eq(0) @@ -1202,7 +1228,11 @@ RSpec.describe PostRevisor do it "can create all tags if none exist" do expect { @result = - subject.revise!(user, raw: "lets totally update the body", tags: %w[totally update]) + post_revisor.revise!( + user, + raw: "lets totally update the body", + tags: %w[totally update], + ) }.to change { Tag.count }.by(2) expect(@result).to eq(true) post.reload @@ -1213,7 +1243,11 @@ RSpec.describe PostRevisor do Fabricate(:tag, name: "totally") expect { @result = - subject.revise!(user, raw: "lets totally update the body", tags: %w[totally update]) + post_revisor.revise!( + user, + raw: "lets totally update the body", + tags: %w[totally update], + ) }.to change { Tag.count }.by(1) expect(@result).to eq(true) post.reload @@ -1222,7 +1256,7 @@ RSpec.describe PostRevisor do it "can remove all tags" do topic.tags = [Fabricate(:tag, name: "super"), Fabricate(:tag, name: "stuff")] - result = subject.revise!(user, raw: "lets totally update the body", tags: []) + result = post_revisor.revise!(user, raw: "lets totally update the body", tags: []) expect(result).to eq(true) post.reload expect(post.topic.tags.size).to eq(0) @@ -1231,7 +1265,11 @@ RSpec.describe PostRevisor do it "can't add staff-only tags" do create_staff_only_tags(["important"]) result = - subject.revise!(user, raw: "lets totally update the body", tags: %w[important stuff]) + post_revisor.revise!( + user, + raw: "lets totally update the body", + tags: %w[important stuff], + ) expect(result).to eq(false) expect(post.topic.errors.present?).to eq(true) end @@ -1239,7 +1277,11 @@ RSpec.describe PostRevisor do it "staff can add staff-only tags" do create_staff_only_tags(["important"]) result = - subject.revise!(admin, raw: "lets totally update the body", tags: %w[important stuff]) + post_revisor.revise!( + admin, + raw: "lets totally update the body", + tags: %w[important stuff], + ) expect(result).to eq(true) post.reload expect(post.topic.tags.map(&:name).sort).to eq(%w[important stuff]) @@ -1250,7 +1292,7 @@ RSpec.describe PostRevisor do events = DiscourseEvent.track_events do - subject.revise!(user, raw: "lets totally update the body", tags: []) + post_revisor.revise!(user, raw: "lets totally update the body", tags: []) end event = events.find { |e| e[:event_name] == :post_edited } @@ -1273,7 +1315,8 @@ RSpec.describe PostRevisor do end it "staff-only tags can't be removed" do - result = subject.revise!(user, raw: "lets totally update the body", tags: ["stuff"]) + result = + post_revisor.revise!(user, raw: "lets totally update the body", tags: ["stuff"]) expect(result).to eq(false) expect(post.topic.errors.present?).to eq(true) post.reload @@ -1281,7 +1324,7 @@ RSpec.describe PostRevisor do end it "can't remove all tags if some are staff-only" do - result = subject.revise!(user, raw: "lets totally update the body", tags: []) + result = post_revisor.revise!(user, raw: "lets totally update the body", tags: []) expect(result).to eq(false) expect(post.topic.errors.present?).to eq(true) post.reload @@ -1289,14 +1332,15 @@ RSpec.describe PostRevisor do end it "staff-only tags can be removed by staff" do - result = subject.revise!(admin, raw: "lets totally update the body", tags: ["stuff"]) + result = + post_revisor.revise!(admin, raw: "lets totally update the body", tags: ["stuff"]) expect(result).to eq(true) post.reload expect(post.topic.tags.map(&:name)).to eq(["stuff"]) end it "staff can remove all tags" do - result = subject.revise!(admin, raw: "lets totally update the body", tags: []) + result = post_revisor.revise!(admin, raw: "lets totally update the body", tags: []) expect(result).to eq(true) post.reload expect(post.topic.tags.size).to eq(0) @@ -1320,7 +1364,7 @@ RSpec.describe PostRevisor do it "doesn't bump topic if only staff-only tags are added" do expect { result = - subject.revise!( + post_revisor.revise!( Fabricate(:admin), raw: post.raw, tags: topic.tags.map(&:name) + ["secret"], @@ -1332,7 +1376,7 @@ RSpec.describe PostRevisor do it "doesn't bump topic if only staff-only tags are removed" do expect { result = - subject.revise!( + post_revisor.revise!( Fabricate(:admin), raw: post.raw, tags: topic.tags.map(&:name) - %w[important secret], @@ -1344,7 +1388,7 @@ RSpec.describe PostRevisor do it "doesn't bump topic if only staff-only tags are removed and there are no tags left" do topic.tags = Tag.where(name: %w[important secret]).to_a expect { - result = subject.revise!(Fabricate(:admin), raw: post.raw, tags: []) + result = post_revisor.revise!(Fabricate(:admin), raw: post.raw, tags: []) expect(result).to eq(true) }.to_not change { topic.reload.bumped_at } end @@ -1352,7 +1396,7 @@ RSpec.describe PostRevisor do it "doesn't bump topic if empty string is given" do topic.tags = Tag.where(name: %w[important secret]).to_a expect { - result = subject.revise!(Fabricate(:admin), raw: post.raw, tags: [""]) + result = post_revisor.revise!(Fabricate(:admin), raw: post.raw, tags: [""]) expect(result).to eq(true) }.to_not change { topic.reload.bumped_at } end @@ -1360,7 +1404,7 @@ RSpec.describe PostRevisor do it "should bump topic if non staff-only tags are added" do expect { result = - subject.revise!( + post_revisor.revise!( Fabricate(:admin), raw: post.raw, tags: topic.tags.map(&:name) + [Fabricate(:tag).name], @@ -1370,7 +1414,7 @@ RSpec.describe PostRevisor do end it "creates a hidden revision" do - subject.revise!( + post_revisor.revise!( Fabricate(:admin), raw: post.raw, tags: topic.tags.map(&:name) + ["secret"], @@ -1382,7 +1426,7 @@ RSpec.describe PostRevisor do PostActionNotifier.enable Jobs.run_immediately! expect { - subject.revise!( + post_revisor.revise!( Fabricate(:admin), raw: post.raw, tags: topic.tags.map(&:name) + ["secret"], @@ -1412,20 +1456,21 @@ RSpec.describe PostRevisor do it "doesn't allow removing all tags from the group" do post.topic.tags = [tag1, tag2] - result = subject.revise!(user, raw: "lets totally update the body", tags: []) + result = post_revisor.revise!(user, raw: "lets totally update the body", tags: []) expect(result).to eq(false) end it "allows removing some tags" do post.topic.tags = [tag1, tag2, tag3] - result = subject.revise!(user, raw: "lets totally update the body", tags: [tag1.name]) + result = + post_revisor.revise!(user, raw: "lets totally update the body", tags: [tag1.name]) expect(result).to eq(true) expect(post.reload.topic.tags.map(&:name)).to eq([tag1.name]) end it "allows admins to remove the tags" do post.topic.tags = [tag1, tag2, tag3] - result = subject.revise!(admin, raw: "lets totally update the body", tags: []) + result = post_revisor.revise!(admin, raw: "lets totally update the body", tags: []) expect(result).to eq(true) expect(post.reload.topic.tags.size).to eq(0) end @@ -1442,7 +1487,11 @@ RSpec.describe PostRevisor do Fabricate(:tag, name: "totally") expect { @result = - subject.revise!(user, raw: "lets totally update the body", tags: %w[totally update]) + post_revisor.revise!( + user, + raw: "lets totally update the body", + tags: %w[totally update], + ) }.to_not change { Tag.count } expect(@result).to eq(true) post.reload @@ -1467,7 +1516,7 @@ RSpec.describe PostRevisor do post.link_post_uploads expect(post.upload_references.pluck(:upload_id)).to contain_exactly(image1.id, image2.id) - subject.revise!(user, raw: <<~RAW) + post_revisor.revise!(user, raw: <<~RAW) This is a post with multiple uploads ![image2](#{image2.short_url}) ![image3](#{image3.short_url}) @@ -1493,7 +1542,7 @@ RSpec.describe PostRevisor do it "updates the upload secure status, which is secure by default from the composer. set to false for a public topic" do stub_image_size - subject.revise!(user, raw: <<~RAW) + post_revisor.revise!(user, raw: <<~RAW) This is a post with a secure upload ![image5](#{image5.short_url}) RAW @@ -1507,7 +1556,7 @@ RSpec.describe PostRevisor do it "does not update the upload secure status, which is secure by default from the composer for a private" do post.topic.update(category: Fabricate(:private_category, group: Fabricate(:group))) stub_image_size - subject.revise!(user, raw: <<~RAW) + post_revisor.revise!(user, raw: <<~RAW) This is a post with a secure upload ![image5](#{image5.short_url}) RAW @@ -1554,12 +1603,12 @@ RSpec.describe PostRevisor do fab!(:post) { Fabricate(:post, raw: "aaa", skip_validation: true) } it "can revise multiple times and remove unnecessary revisions" do - subject.revise!(admin, { raw: "bbb" }, skip_validations: true) + post_revisor.revise!(admin, { raw: "bbb" }, skip_validations: true) expect(post.errors).to be_empty # Revert to old version which was invalid to destroy previously created # post revision and trigger another post save. - subject.revise!(admin, { raw: "aaa" }, skip_validations: true) + post_revisor.revise!(admin, { raw: "aaa" }, skip_validations: true) expect(post.errors).to be_empty end end diff --git a/spec/lib/retrieve_title_spec.rb b/spec/lib/retrieve_title_spec.rb index 5afc01a0d7a..685696efb50 100644 --- a/spec/lib/retrieve_title_spec.rb +++ b/spec/lib/retrieve_title_spec.rb @@ -203,7 +203,7 @@ RSpec.describe RetrieveTitle do end it "ignores SSRF lookup errors" do - subject.stubs(:fetch_title).raises(FinalDestination::SSRFDetector::LookupFailedError) + described_class.stubs(:fetch_title).raises(FinalDestination::SSRFDetector::LookupFailedError) expect(RetrieveTitle.crawl("https://example.com")).to eq(nil) end diff --git a/spec/lib/seed_data/categories_spec.rb b/spec/lib/seed_data/categories_spec.rb index a9fccb9605c..fa92fbe12a3 100644 --- a/spec/lib/seed_data/categories_spec.rb +++ b/spec/lib/seed_data/categories_spec.rb @@ -3,10 +3,10 @@ require "seed_data/categories" RSpec.describe SeedData::Categories do - subject { SeedData::Categories.with_default_locale } + subject(:seeder) { SeedData::Categories.with_default_locale } def create_category(name = "staff_category_id") - subject.create(site_setting_names: [name]) + seeder.create(site_setting_names: [name]) end def description_post(category) @@ -152,7 +152,7 @@ RSpec.describe SeedData::Categories do describe "#update" do def update_category(name = "staff_category_id", skip_changed: false) - subject.update(site_setting_names: [name], skip_changed: skip_changed) + seeder.update(site_setting_names: [name], skip_changed: skip_changed) end before do @@ -211,7 +211,7 @@ RSpec.describe SeedData::Categories do { id: "general_category_id", name: I18n.t("general_category_name"), selected: false }, ] - expect(subject.reseed_options).to eq(expected_options) + expect(seeder.reseed_options).to eq(expected_options) end end end diff --git a/spec/lib/seed_data/topics_spec.rb b/spec/lib/seed_data/topics_spec.rb index 67361eb5c5f..afea102617b 100644 --- a/spec/lib/seed_data/topics_spec.rb +++ b/spec/lib/seed_data/topics_spec.rb @@ -3,7 +3,7 @@ require "seed_data/topics" RSpec.describe SeedData::Topics do - subject { SeedData::Topics.with_default_locale } + subject(:seeder) { SeedData::Topics.with_default_locale } before do general_category = Fabricate(:category, name: "General") @@ -11,7 +11,7 @@ RSpec.describe SeedData::Topics do end def create_topic(name = "welcome_topic_id") - subject.create(site_setting_names: [name], include_legal_topics: true) + seeder.create(site_setting_names: [name], include_legal_topics: true) end describe "#create" do @@ -74,7 +74,7 @@ RSpec.describe SeedData::Topics do end it "does not create a legal topic if company_name is not set" do - subject.create(site_setting_names: ["tos_topic_id"]) + seeder.create(site_setting_names: ["tos_topic_id"]) expect(SiteSetting.tos_topic_id).to eq(-1) end @@ -102,7 +102,7 @@ RSpec.describe SeedData::Topics do it "creates a legal topic if company_name is set" do SiteSetting.company_name = "Company Name" - subject.create(site_setting_names: ["tos_topic_id"]) + seeder.create(site_setting_names: ["tos_topic_id"]) expect(SiteSetting.tos_topic_id).to_not eq(-1) end @@ -110,7 +110,7 @@ RSpec.describe SeedData::Topics do describe "#update" do def update_topic(name = "welcome_topic_id", skip_changed: false) - subject.update(site_setting_names: [name], skip_changed: skip_changed) + seeder.update(site_setting_names: [name], skip_changed: skip_changed) end it "updates the changed topic" do @@ -167,7 +167,7 @@ RSpec.describe SeedData::Topics do describe "#delete" do def delete_topic(name = "welcome_topic_id", skip_changed: false) - subject.delete(site_setting_names: [name], skip_changed: skip_changed) + seeder.delete(site_setting_names: [name], skip_changed: skip_changed) end it "deletes the topic" do @@ -199,7 +199,7 @@ RSpec.describe SeedData::Topics do { id: "welcome_topic_id", name: "Changed Topic Title", selected: false }, ] - expect(subject.reseed_options).to eq(expected_options) + expect(seeder.reseed_options).to eq(expected_options) end end end diff --git a/spec/lib/site_settings/type_supervisor_spec.rb b/spec/lib/site_settings/type_supervisor_spec.rb index 45bd084d93f..b1d416c18d6 100644 --- a/spec/lib/site_settings/type_supervisor_spec.rb +++ b/spec/lib/site_settings/type_supervisor_spec.rb @@ -9,8 +9,6 @@ RSpec.describe SiteSettings::TypeSupervisor do new_settings(provider_local) end - subject { SiteSettings::TypeSupervisor } - describe "constants" do it "validator opts are the subset of consumed opts" do expect( @@ -103,33 +101,33 @@ RSpec.describe SiteSettings::TypeSupervisor do describe "#parse_value_type" do it "returns :null type when the value is nil" do - expect(subject.parse_value_type(nil)).to eq(SiteSetting.types[:null]) + expect(described_class.parse_value_type(nil)).to eq(SiteSetting.types[:null]) end it "returns :integer type when the value is int" do - expect(subject.parse_value_type(2)).to eq(SiteSetting.types[:integer]) + expect(described_class.parse_value_type(2)).to eq(SiteSetting.types[:integer]) end it "returns :integer type when the value is large int" do - expect(subject.parse_value_type(99_999_999_999_999_999_999_999_999_999_999_999)).to eq( - SiteSetting.types[:integer], - ) + expect( + described_class.parse_value_type(99_999_999_999_999_999_999_999_999_999_999_999), + ).to eq(SiteSetting.types[:integer]) end it "returns :float type when the value is float" do - expect(subject.parse_value_type(1.23)).to eq(SiteSetting.types[:float]) + expect(described_class.parse_value_type(1.23)).to eq(SiteSetting.types[:float]) end it "returns :bool type when the value is true" do - expect(subject.parse_value_type(true)).to eq(SiteSetting.types[:bool]) + expect(described_class.parse_value_type(true)).to eq(SiteSetting.types[:bool]) end it "returns :bool type when the value is false" do - expect(subject.parse_value_type(false)).to eq(SiteSetting.types[:bool]) + expect(described_class.parse_value_type(false)).to eq(SiteSetting.types[:bool]) end it "raises when the value is not listed" do - expect { subject.parse_value_type(Object.new) }.to raise_error ArgumentError + expect { described_class.parse_value_type(Object.new) }.to raise_error ArgumentError end end diff --git a/spec/lib/site_settings/validations_spec.rb b/spec/lib/site_settings/validations_spec.rb index 82064f35932..2b6e392c547 100644 --- a/spec/lib/site_settings/validations_spec.rb +++ b/spec/lib/site_settings/validations_spec.rb @@ -3,22 +3,24 @@ require "site_settings/validations" RSpec.describe SiteSettings::Validations do - subject { Class.new.include(described_class).new } + subject(:validations) { Class.new.include(described_class).new } describe "default_categories" do fab!(:category) { Fabricate(:category) } it "supports valid categories" do - expect { subject.validate_default_categories_watching("#{category.id}") }.not_to raise_error + expect { + validations.validate_default_categories_watching("#{category.id}") + }.not_to raise_error end it "won't allow you to input junk categories" do - expect { subject.validate_default_categories_watching("junk") }.to raise_error( + expect { validations.validate_default_categories_watching("junk") }.to raise_error( Discourse::InvalidParameters, ) expect { - subject.validate_default_categories_watching("#{category.id}|12312323") + validations.validate_default_categories_watching("#{category.id}|12312323") }.to raise_error(Discourse::InvalidParameters) end @@ -85,7 +87,7 @@ RSpec.describe SiteSettings::Validations do let(:other_setting_name) { "s3_upload_bucket" } def validate(new_value) - subject.validate_s3_backup_bucket(new_value) + validations.validate_s3_backup_bucket(new_value) end it_behaves_like "s3 bucket validation" @@ -103,7 +105,7 @@ RSpec.describe SiteSettings::Validations do let(:other_setting_name) { "s3_backup_bucket" } def validate(new_value) - subject.validate_s3_upload_bucket(new_value) + validations.validate_s3_upload_bucket(new_value) end it_behaves_like "s3 bucket validation" @@ -142,7 +144,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enable_local_logins = false } it "should raise an error" do - expect { subject.validate_enforce_second_factor("t") }.to raise_error( + expect { validations.validate_enforce_second_factor("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -153,7 +155,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enable_local_logins = true } it "should be ok" do - expect { subject.validate_enforce_second_factor("t") }.not_to raise_error + expect { validations.validate_enforce_second_factor("t") }.not_to raise_error end end @@ -170,7 +172,7 @@ RSpec.describe SiteSettings::Validations do end it "raises and error, and specifies the auth providers" do - expect { subject.validate_enforce_second_factor("all") }.to raise_error( + expect { validations.validate_enforce_second_factor("all") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -189,7 +191,7 @@ RSpec.describe SiteSettings::Validations do end it "should raise an error" do - expect { subject.validate_enforce_second_factor("t") }.to raise_error( + expect { validations.validate_enforce_second_factor("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -207,7 +209,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enforce_second_factor = "all" } it "should raise an error" do - expect { subject.validate_enable_local_logins("f") }.to raise_error( + expect { validations.validate_enable_local_logins("f") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -218,14 +220,14 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enforce_second_factor = "no" } it "should be ok" do - expect { subject.validate_enable_local_logins("f") }.not_to raise_error + expect { validations.validate_enable_local_logins("f") }.not_to raise_error end end end context "when the new value is true" do it "should be ok" do - expect { subject.validate_enable_local_logins("t") }.not_to raise_error + expect { validations.validate_enable_local_logins("t") }.not_to raise_error end end end @@ -237,7 +239,7 @@ RSpec.describe SiteSettings::Validations do context "when the new value has trailing slash" do it "should raise an error" do - expect { subject.validate_cors_origins("https://www.rainbows.com/") }.to raise_error( + expect { validations.validate_cors_origins("https://www.rainbows.com/") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -248,7 +250,7 @@ RSpec.describe SiteSettings::Validations do describe "#validate_enable_page_publishing" do context "when the new value is true" do it "is ok" do - expect { subject.validate_enable_page_publishing("t") }.not_to raise_error + expect { validations.validate_enable_page_publishing("t") }.not_to raise_error end context "if secure uploads is enabled" do @@ -256,7 +258,7 @@ RSpec.describe SiteSettings::Validations do before { enable_secure_uploads } it "is not ok" do - expect { subject.validate_enable_page_publishing("t") }.to raise_error( + expect { validations.validate_enable_page_publishing("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -268,13 +270,13 @@ RSpec.describe SiteSettings::Validations do describe "#validate_s3_use_acls" do context "when the new value is true" do it "is ok" do - expect { subject.validate_s3_use_acls("t") }.not_to raise_error + expect { validations.validate_s3_use_acls("t") }.not_to raise_error end end context "when the new value is false" do it "is ok" do - expect { subject.validate_s3_use_acls("f") }.not_to raise_error + expect { validations.validate_s3_use_acls("f") }.not_to raise_error end context "if secure uploads is enabled" do @@ -282,7 +284,7 @@ RSpec.describe SiteSettings::Validations do before { enable_secure_uploads } it "is not ok" do - expect { subject.validate_s3_use_acls("f") }.to raise_error( + expect { validations.validate_s3_use_acls("f") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -299,7 +301,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enable_s3_uploads = true } it "should be ok" do - expect { subject.validate_secure_uploads("t") }.not_to raise_error + expect { validations.validate_secure_uploads("t") }.not_to raise_error end end @@ -307,7 +309,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.enable_s3_uploads = false } it "is not ok" do - expect { subject.validate_secure_uploads("t") }.to raise_error( + expect { validations.validate_secure_uploads("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -317,7 +319,7 @@ RSpec.describe SiteSettings::Validations do before { GlobalSetting.stubs(:use_s3?).returns(true) } it "should be ok" do - expect { subject.validate_secure_uploads("t") }.not_to raise_error + expect { validations.validate_secure_uploads("t") }.not_to raise_error end end end @@ -326,7 +328,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.s3_use_acls = false } it "is not ok" do - expect { subject.validate_secure_uploads("t") }.to raise_error( + expect { validations.validate_secure_uploads("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -345,7 +347,7 @@ RSpec.describe SiteSettings::Validations do before { GlobalSetting.stubs(:use_s3?).returns(true) } it "is not ok" do - expect { subject.validate_enable_s3_uploads("t") }.to raise_error( + expect { validations.validate_enable_s3_uploads("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -356,7 +358,7 @@ RSpec.describe SiteSettings::Validations do before { GlobalSetting.stubs(:use_s3?).returns(false) } it "should be ok" do - expect { subject.validate_enable_s3_uploads("t") }.not_to raise_error + expect { validations.validate_enable_s3_uploads("t") }.not_to raise_error end end @@ -366,7 +368,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.s3_upload_bucket = nil } it "is not ok" do - expect { subject.validate_enable_s3_uploads("t") }.to raise_error( + expect { validations.validate_enable_s3_uploads("t") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -377,7 +379,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.s3_upload_bucket = "some-bucket" } it "should be ok" do - expect { subject.validate_enable_s3_uploads("t") }.not_to raise_error + expect { validations.validate_enable_s3_uploads("t") }.not_to raise_error end end end @@ -399,49 +401,47 @@ RSpec.describe SiteSettings::Validations do end it "cannot contain a user agent that's shorter than 3 characters" do - expect { subject.validate_slow_down_crawler_user_agents("ao|acsw") }.to raise_error( + expect { validations.validate_slow_down_crawler_user_agents("ao|acsw") }.to raise_error( Discourse::InvalidParameters, too_short_message, ) - expect { subject.validate_slow_down_crawler_user_agents("up") }.to raise_error( + expect { validations.validate_slow_down_crawler_user_agents("up") }.to raise_error( Discourse::InvalidParameters, too_short_message, ) - expect { subject.validate_slow_down_crawler_user_agents("a|") }.to raise_error( + expect { validations.validate_slow_down_crawler_user_agents("a|") }.to raise_error( Discourse::InvalidParameters, too_short_message, ) - expect { subject.validate_slow_down_crawler_user_agents("|a") }.to raise_error( + expect { validations.validate_slow_down_crawler_user_agents("|a") }.to raise_error( Discourse::InvalidParameters, too_short_message, ) end it "allows user agents that are 3 characters or longer" do - expect { subject.validate_slow_down_crawler_user_agents("aoc") }.not_to raise_error - expect { subject.validate_slow_down_crawler_user_agents("anuq") }.not_to raise_error - expect { subject.validate_slow_down_crawler_user_agents("pupsc|kcx") }.not_to raise_error + expect { validations.validate_slow_down_crawler_user_agents("aoc") }.not_to raise_error + expect { validations.validate_slow_down_crawler_user_agents("anuq") }.not_to raise_error + expect { validations.validate_slow_down_crawler_user_agents("pupsc|kcx") }.not_to raise_error end it "allows the setting to be empty" do - expect { subject.validate_slow_down_crawler_user_agents("") }.not_to raise_error + expect { validations.validate_slow_down_crawler_user_agents("") }.not_to raise_error end it "cannot contain a token of a popular browser user agent" do - expect { subject.validate_slow_down_crawler_user_agents("mOzilla") }.to raise_error( + expect { validations.validate_slow_down_crawler_user_agents("mOzilla") }.to raise_error( Discourse::InvalidParameters, popular_browser_message, ) - expect { subject.validate_slow_down_crawler_user_agents("chRome|badcrawler") }.to raise_error( - Discourse::InvalidParameters, - popular_browser_message, - ) + expect { + validations.validate_slow_down_crawler_user_agents("chRome|badcrawler") + }.to raise_error(Discourse::InvalidParameters, popular_browser_message) - expect { subject.validate_slow_down_crawler_user_agents("html|badcrawler") }.to raise_error( - Discourse::InvalidParameters, - popular_browser_message, - ) + expect { + validations.validate_slow_down_crawler_user_agents("html|badcrawler") + }.to raise_error(Discourse::InvalidParameters, popular_browser_message) end end @@ -458,7 +458,7 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.composer_media_optimization_image_enabled = true } it "should raise an error" do - expect { subject.validate_strip_image_metadata("f") }.to raise_error( + expect { validations.validate_strip_image_metadata("f") }.to raise_error( Discourse::InvalidParameters, error_message, ) @@ -469,14 +469,14 @@ RSpec.describe SiteSettings::Validations do before { SiteSetting.composer_media_optimization_image_enabled = false } it "should be ok" do - expect { subject.validate_strip_image_metadata("f") }.not_to raise_error + expect { validations.validate_strip_image_metadata("f") }.not_to raise_error end end end context "when the new value is true" do it "should be ok" do - expect { subject.validate_strip_image_metadata("t") }.not_to raise_error + expect { validations.validate_strip_image_metadata("t") }.not_to raise_error end end end @@ -485,13 +485,13 @@ RSpec.describe SiteSettings::Validations do describe "#twitter_summary_large_image" do it "does not allow SVG image files" do upload = Fabricate(:upload, url: "/images/logo-dark.svg", extension: "svg") - expect { subject.validate_twitter_summary_large_image(upload.id) }.to raise_error( + expect { validations.validate_twitter_summary_large_image(upload.id) }.to raise_error( Discourse::InvalidParameters, I18n.t("errors.site_settings.twitter_summary_large_image_no_svg"), ) upload.update!(url: "/images/logo-dark.png", extension: "png") - expect { subject.validate_twitter_summary_large_image(upload.id) }.not_to raise_error - expect { subject.validate_twitter_summary_large_image(nil) }.not_to raise_error + expect { validations.validate_twitter_summary_large_image(upload.id) }.not_to raise_error + expect { validations.validate_twitter_summary_large_image(nil) }.not_to raise_error end end end diff --git a/spec/lib/topic_upload_security_manager_spec.rb b/spec/lib/topic_upload_security_manager_spec.rb index 41c4db69a2a..c684444312f 100644 --- a/spec/lib/topic_upload_security_manager_spec.rb +++ b/spec/lib/topic_upload_security_manager_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.describe TopicUploadSecurityManager do + subject(:manager) { described_class.new(topic) } + let(:group) { Fabricate(:group) } let(:category) { Fabricate(:category) } let!(:topic) { Fabricate(:topic, user: user, category: category) } @@ -10,8 +12,6 @@ RSpec.describe TopicUploadSecurityManager do let!(:post3) { Fabricate(:post, topic: topic) } let!(:post4) { Fabricate(:post, topic: topic) } - subject { described_class.new(topic) } - context "when a topic has posts linked to secure uploads" do let!(:upload) { Fabricate(:secure_upload) } let!(:upload2) { Fabricate(:secure_upload) } @@ -127,7 +127,7 @@ RSpec.describe TopicUploadSecurityManager do it "changes the upload secure status to true and changes the ACL and rebakes the post and sets the access control post" do Post.any_instance.expects(:rebake!).once - subject.run + manager.run expect(upload3.reload.secure?).to eq(true) expect(upload3.reload.access_control_post).to eq(post4) end @@ -136,7 +136,7 @@ RSpec.describe TopicUploadSecurityManager do before { SiteSetting.secure_uploads = false } it "does not change the upload secure status and does not set the access control post" do - subject.run + manager.run expect(upload3.reload.secure?).to eq(false) expect(upload3.reload.access_control_post).to eq(nil) end @@ -151,7 +151,7 @@ RSpec.describe TopicUploadSecurityManager do it "does not change the upload secure status and does not set the access control post" do Post.any_instance.expects(:rebake!).never - subject.run + manager.run expect(upload3.reload.secure?).to eq(false) expect(upload3.reload.access_control_post).to eq(nil) end @@ -161,14 +161,14 @@ RSpec.describe TopicUploadSecurityManager do def expect_upload_status_not_to_change Post.any_instance.expects(:rebake!).never - subject.run + manager.run expect(upload.reload.secure?).to eq(true) expect(upload2.reload.secure?).to eq(true) end def expect_upload_status_to_change_and_rebake Post.any_instance.expects(:rebake!).twice - subject.run + manager.run expect(upload.reload.secure?).to eq(false) expect(upload2.reload.secure?).to eq(false) end diff --git a/spec/lib/upload_security_spec.rb b/spec/lib/upload_security_spec.rb index a4feac8646d..7ad9174a757 100644 --- a/spec/lib/upload_security_spec.rb +++ b/spec/lib/upload_security_spec.rb @@ -1,16 +1,17 @@ # frozen_string_literal: true RSpec.describe UploadSecurity do + subject(:security) { described_class.new(upload, opts) } + fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) } fab!(:post_in_secure_context) do Fabricate(:post, topic: Fabricate(:topic, category: private_category)) end fab!(:upload) { Fabricate(:upload) } + let(:type) { nil } let(:opts) { { type: type, creating: creating } } - subject { described_class.new(upload, opts) } - context "when secure uploads is enabled" do before do setup_s3 @@ -24,63 +25,63 @@ RSpec.describe UploadSecurity do before { SiteSetting.login_required = true } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end context "when uploading in public context" do describe "for a public type badge_image" do let(:type) { "badge_image" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type group_flair" do let(:type) { "group_flair" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type avatar" do let(:type) { "avatar" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type custom_emoji" do let(:type) { "custom_emoji" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type profile_background" do let(:type) { "profile_background" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type avatar" do let(:type) { "avatar" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type category_logo" do let(:type) { "category_logo" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end describe "for a public type category_background" do let(:type) { "category_background" } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -88,12 +89,12 @@ RSpec.describe UploadSecurity do let(:type) { "my_custom_type" } it "returns true if the custom type has not been added" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end it "returns false if the custom type has been added" do UploadSecurity.register_custom_public_type(type) - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) UploadSecurity.reset_custom_public_types end end @@ -102,7 +103,7 @@ RSpec.describe UploadSecurity do before { upload.stubs(:for_theme).returns(true) } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -110,7 +111,7 @@ RSpec.describe UploadSecurity do before { upload.stubs(:for_site_setting).returns(true) } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -118,7 +119,7 @@ RSpec.describe UploadSecurity do before { upload.stubs(:for_gravatar).returns(true) } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -129,7 +130,7 @@ RSpec.describe UploadSecurity do e.url == "/images/emoji/twitter/falafel.png?v=#{Emoji::EMOJI_VERSION}" end upload.update!(origin: "http://localhost:3000#{falafel.url}") - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end end @@ -139,14 +140,14 @@ RSpec.describe UploadSecurity do before { upload.update(access_control_post_id: post_in_secure_context.id) } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end context "when the post is deleted" do before { post_in_secure_context.trash! } it "still determines whether the post has secure uploads; returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end end @@ -154,28 +155,28 @@ RSpec.describe UploadSecurity do context "when uploading in the composer" do let(:type) { "composer" } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end context "when uploading for a group message" do before { upload.stubs(:for_group_message).returns(true) } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end context "when uploading for a PM" do before { upload.stubs(:for_private_message).returns(true) } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end context "when upload is already secure" do before { upload.update(secure: true) } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end @@ -185,7 +186,7 @@ RSpec.describe UploadSecurity do context "when the access control post has_secure_uploads?" do before { upload.update(access_control_post: post_in_secure_context) } it "returns true" do - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end end @@ -213,7 +214,7 @@ RSpec.describe UploadSecurity do describe "when the upload is first used for a post in a secure context" do it "returns true" do create_secure_post_reference - expect(subject.should_be_secure?).to eq(true) + expect(security.should_be_secure?).to eq(true) end end @@ -223,7 +224,7 @@ RSpec.describe UploadSecurity do post_in_secure_context.trash! CustomEmoji.create(name: "meme", upload: upload) - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -231,7 +232,7 @@ RSpec.describe UploadSecurity do it "returns false" do SiteSetting.favicon = upload create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -239,7 +240,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:theme_field, type_id: ThemeField.types[:theme_upload_var], upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -247,7 +248,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:group, flair_upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -255,7 +256,7 @@ RSpec.describe UploadSecurity do it "returns false" do CustomEmoji.create(name: "meme", upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end context "when the created_at dates for upload references are identical" do @@ -266,7 +267,7 @@ RSpec.describe UploadSecurity do UploadReference.find_by(target: custom_emoji).update!(created_at: now) UploadReference.find_by(target: post_in_secure_context).update!(created_at: now) - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end end @@ -275,7 +276,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:badge, image_upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -283,7 +284,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:category, uploaded_logo: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -292,7 +293,7 @@ RSpec.describe UploadSecurity do user = Fabricate(:user) user.user_profile.update!(card_background_upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -300,7 +301,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:user, uploaded_avatar: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end @@ -308,7 +309,7 @@ RSpec.describe UploadSecurity do it "returns false" do Fabricate(:user_avatar, custom_upload: upload) create_secure_post_reference - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end end @@ -320,14 +321,14 @@ RSpec.describe UploadSecurity do before { SiteSetting.secure_uploads = false } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end context "for attachments" do before { upload.update(original_filename: "test.pdf") } it "returns false" do - expect(subject.should_be_secure?).to eq(false) + expect(security.should_be_secure?).to eq(false) end end end diff --git a/spec/lib/user_comm_screener_spec.rb b/spec/lib/user_comm_screener_spec.rb index 4f8b851a58a..1305c3f51e9 100644 --- a/spec/lib/user_comm_screener_spec.rb +++ b/spec/lib/user_comm_screener_spec.rb @@ -1,18 +1,7 @@ # frozen_string_literal: true RSpec.describe UserCommScreener do - fab!(:target_user1) { Fabricate(:user, username: "bobscreen") } - fab!(:target_user2) { Fabricate(:user, username: "hughscreen") } - fab!(:target_user3) do - user = Fabricate(:user, username: "alicescreen") - user.user_option.update(allow_private_messages: false) - user - end - fab!(:target_user4) { Fabricate(:user, username: "janescreen") } - fab!(:target_user5) { Fabricate(:user, username: "maryscreen") } - fab!(:other_user) { Fabricate(:user) } - - subject do + subject(:screener) do described_class.new( acting_user: acting_user, target_user_ids: [ @@ -25,6 +14,17 @@ RSpec.describe UserCommScreener do ) end + fab!(:target_user1) { Fabricate(:user, username: "bobscreen") } + fab!(:target_user2) { Fabricate(:user, username: "hughscreen") } + fab!(:target_user3) do + user = Fabricate(:user, username: "alicescreen") + user.user_option.update(allow_private_messages: false) + user + end + fab!(:target_user4) { Fabricate(:user, username: "janescreen") } + fab!(:target_user5) { Fabricate(:user, username: "maryscreen") } + fab!(:other_user) { Fabricate(:user) } + it "allows initializing the class with both an acting_user_id and an acting_user" do acting_user = Fabricate(:user) screener = described_class.new(acting_user: acting_user, target_user_ids: [target_user1.id]) @@ -58,7 +58,7 @@ RSpec.describe UserCommScreener do describe "#allowing_actor_communication" do it "returns the usernames of people not ignoring, muting, or disallowing PMs from the actor" do - expect(subject.allowing_actor_communication).to match_array( + expect(screener.allowing_actor_communication).to match_array( [target_user4.id, target_user5.id], ) end @@ -66,7 +66,7 @@ RSpec.describe UserCommScreener do describe "#preventing_actor_communication" do it "returns the usernames of people ignoring, muting, or disallowing PMs from the actor" do - expect(subject.preventing_actor_communication).to match_array( + expect(screener.preventing_actor_communication).to match_array( [target_user1.id, target_user2.id, target_user3.id], ) end @@ -74,23 +74,23 @@ RSpec.describe UserCommScreener do describe "#ignoring_or_muting_actor?" do it "does not raise an error when looking for a user who has no communication preferences" do - expect { subject.ignoring_or_muting_actor?(target_user5.id) }.not_to raise_error + expect { screener.ignoring_or_muting_actor?(target_user5.id) }.not_to raise_error end it "returns true for a user muting the actor" do - expect(subject.ignoring_or_muting_actor?(target_user1.id)).to eq(true) + expect(screener.ignoring_or_muting_actor?(target_user1.id)).to eq(true) end it "returns true for a user ignoring the actor" do - expect(subject.ignoring_or_muting_actor?(target_user2.id)).to eq(true) + expect(screener.ignoring_or_muting_actor?(target_user2.id)).to eq(true) end it "returns false for a user neither ignoring or muting the actor" do - expect(subject.ignoring_or_muting_actor?(target_user3.id)).to eq(false) + expect(screener.ignoring_or_muting_actor?(target_user3.id)).to eq(false) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.ignoring_or_muting_actor?(other_user.id) }.to raise_error( + expect { screener.ignoring_or_muting_actor?(other_user.id) }.to raise_error( Discourse::NotFound, ) end @@ -98,34 +98,34 @@ RSpec.describe UserCommScreener do describe "#disallowing_pms_from_actor?" do it "returns true for a user disallowing all PMs" do - expect(subject.disallowing_pms_from_actor?(target_user3.id)).to eq(true) + expect(screener.disallowing_pms_from_actor?(target_user3.id)).to eq(true) end it "returns true for a user allowing only PMs for certain users but not the actor" do target_user4.user_option.update!(enable_allowed_pm_users: true) - expect(subject.disallowing_pms_from_actor?(target_user4.id)).to eq(true) + expect(screener.disallowing_pms_from_actor?(target_user4.id)).to eq(true) end it "returns false for a user allowing only PMs for certain users which the actor allowed" do target_user4.user_option.update!(enable_allowed_pm_users: true) AllowedPmUser.create!(user: target_user4, allowed_pm_user: acting_user) - expect(subject.disallowing_pms_from_actor?(target_user4.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user4.id)).to eq(false) end it "returns false for a user not disallowing PMs or muting or ignoring" do - expect(subject.disallowing_pms_from_actor?(target_user5.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user5.id)).to eq(false) end it "returns true for a user not disallowing PMs but still ignoring" do - expect(subject.disallowing_pms_from_actor?(target_user1.id)).to eq(true) + expect(screener.disallowing_pms_from_actor?(target_user1.id)).to eq(true) end it "returns true for a user not disallowing PMs but still muting" do - expect(subject.disallowing_pms_from_actor?(target_user2.id)).to eq(true) + expect(screener.disallowing_pms_from_actor?(target_user2.id)).to eq(true) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.disallowing_pms_from_actor?(other_user.id) }.to raise_error( + expect { screener.disallowing_pms_from_actor?(other_user.id) }.to raise_error( Discourse::NotFound, ) end @@ -146,7 +146,7 @@ RSpec.describe UserCommScreener do describe "#allowing_actor_communication" do it "returns all usernames since staff can communicate with anyone" do - expect(subject.allowing_actor_communication).to match_array( + expect(screener.allowing_actor_communication).to match_array( [target_user1.id, target_user2.id, target_user3.id, target_user4.id, target_user5.id], ) end @@ -154,25 +154,25 @@ RSpec.describe UserCommScreener do describe "#preventing_actor_communication" do it "does not return any usernames since no users can prevent staff communicating with them" do - expect(subject.preventing_actor_communication).to eq([]) + expect(screener.preventing_actor_communication).to eq([]) end end describe "#ignoring_or_muting_actor?" do it "returns false for a user muting the staff" do - expect(subject.ignoring_or_muting_actor?(target_user1.id)).to eq(false) + expect(screener.ignoring_or_muting_actor?(target_user1.id)).to eq(false) end it "returns false for a user ignoring the staff actor" do - expect(subject.ignoring_or_muting_actor?(target_user2.id)).to eq(false) + expect(screener.ignoring_or_muting_actor?(target_user2.id)).to eq(false) end it "returns false for a user neither ignoring or muting the actor" do - expect(subject.ignoring_or_muting_actor?(target_user3.id)).to eq(false) + expect(screener.ignoring_or_muting_actor?(target_user3.id)).to eq(false) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.ignoring_or_muting_actor?(other_user.id) }.to raise_error( + expect { screener.ignoring_or_muting_actor?(other_user.id) }.to raise_error( Discourse::NotFound, ) end @@ -180,28 +180,28 @@ RSpec.describe UserCommScreener do describe "#disallowing_pms_from_actor?" do it "returns false for a user disallowing all PMs" do - expect(subject.disallowing_pms_from_actor?(target_user3.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user3.id)).to eq(false) end it "returns false for a user allowing only PMs for certain users but not the actor" do target_user4.user_option.update!(enable_allowed_pm_users: true) - expect(subject.disallowing_pms_from_actor?(target_user4.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user4.id)).to eq(false) end it "returns false for a user not disallowing PMs or muting or ignoring" do - expect(subject.disallowing_pms_from_actor?(target_user5.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user5.id)).to eq(false) end it "returns false for a user not disallowing PMs but still ignoring" do - expect(subject.disallowing_pms_from_actor?(target_user1.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user1.id)).to eq(false) end it "returns false for a user not disallowing PMs but still muting" do - expect(subject.disallowing_pms_from_actor?(target_user2.id)).to eq(false) + expect(screener.disallowing_pms_from_actor?(target_user2.id)).to eq(false) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.disallowing_pms_from_actor?(other_user.id) }.to raise_error( + expect { screener.disallowing_pms_from_actor?(other_user.id) }.to raise_error( Discourse::NotFound, ) end @@ -232,13 +232,13 @@ RSpec.describe UserCommScreener do describe "#actor_preventing_communication" do it "returns the user_ids of the users the actor is ignoring, muting, or disallowing PMs from" do acting_user.user_option.update!(enable_allowed_pm_users: true) - expect(subject.actor_preventing_communication).to match_array( + expect(screener.actor_preventing_communication).to match_array( [target_user1.id, target_user2.id, target_user3.id, target_user5.id], ) end it "does not include users the actor is disallowing PMs from if they have not set enable_allowed_pm_users" do - expect(subject.actor_preventing_communication).to match_array( + expect(screener.actor_preventing_communication).to match_array( [target_user1.id, target_user2.id], ) end @@ -250,7 +250,7 @@ RSpec.describe UserCommScreener do end it "returns an empty array and does not error" do - expect(subject.actor_preventing_communication).to match_array([]) + expect(screener.actor_preventing_communication).to match_array([]) end end end @@ -258,7 +258,7 @@ RSpec.describe UserCommScreener do describe "#actor_allowing_communication" do it "returns the user_ids of the users who the actor is not ignoring, muting, or disallowing PMs from" do acting_user.user_option.update!(enable_allowed_pm_users: true) - expect(subject.actor_allowing_communication).to match_array([target_user4.id]) + expect(screener.actor_allowing_communication).to match_array([target_user4.id]) end describe "when the actor has no preferences" do @@ -268,7 +268,7 @@ RSpec.describe UserCommScreener do end it "returns an array of the target users and does not error" do - expect(subject.actor_allowing_communication).to match_array( + expect(screener.actor_allowing_communication).to match_array( [target_user1.id, target_user2.id, target_user3.id, target_user4.id, target_user5.id], ) end @@ -277,49 +277,51 @@ RSpec.describe UserCommScreener do describe "#actor_ignoring?" do it "returns true for user ids that the actor is ignoring" do - expect(subject.actor_ignoring?(target_user2.id)).to eq(true) - expect(subject.actor_ignoring?(target_user4.id)).to eq(false) + expect(screener.actor_ignoring?(target_user2.id)).to eq(true) + expect(screener.actor_ignoring?(target_user4.id)).to eq(false) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.actor_ignoring?(other_user.id) }.to raise_error(Discourse::NotFound) + expect { screener.actor_ignoring?(other_user.id) }.to raise_error(Discourse::NotFound) end end describe "#actor_muting?" do it "returns true for user ids that the actor is muting" do - expect(subject.actor_muting?(target_user1.id)).to eq(true) - expect(subject.actor_muting?(target_user2.id)).to eq(false) + expect(screener.actor_muting?(target_user1.id)).to eq(true) + expect(screener.actor_muting?(target_user2.id)).to eq(false) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.actor_muting?(other_user.id) }.to raise_error(Discourse::NotFound) + expect { screener.actor_muting?(other_user.id) }.to raise_error(Discourse::NotFound) end end describe "#actor_disallowing_pms?" do it "returns true for user ids that the actor is not explicitly allowing PMs from" do acting_user.user_option.update!(enable_allowed_pm_users: true) - expect(subject.actor_disallowing_pms?(target_user3.id)).to eq(true) - expect(subject.actor_disallowing_pms?(target_user1.id)).to eq(false) + expect(screener.actor_disallowing_pms?(target_user3.id)).to eq(true) + expect(screener.actor_disallowing_pms?(target_user1.id)).to eq(false) end it "returns true if the actor has disallowed all PMs" do acting_user.user_option.update!(allow_private_messages: false) - expect(subject.actor_disallowing_pms?(target_user3.id)).to eq(true) - expect(subject.actor_disallowing_pms?(target_user1.id)).to eq(true) + expect(screener.actor_disallowing_pms?(target_user3.id)).to eq(true) + expect(screener.actor_disallowing_pms?(target_user1.id)).to eq(true) end it "raises a NotFound error if the user_id passed in is not part of the target users" do - expect { subject.actor_disallowing_pms?(other_user.id) }.to raise_error(Discourse::NotFound) + expect { screener.actor_disallowing_pms?(other_user.id) }.to raise_error( + Discourse::NotFound, + ) end end describe "#actor_disallowing_all_pms?" do it "returns true if the acting user has disabled private messages altogether" do - expect(subject.actor_disallowing_all_pms?).to eq(false) + expect(screener.actor_disallowing_all_pms?).to eq(false) acting_user.user_option.update!(allow_private_messages: false) - expect(subject.actor_disallowing_all_pms?).to eq(true) + expect(screener.actor_disallowing_all_pms?).to eq(true) end end end diff --git a/spec/lib/validators/allowed_ip_address_validator_spec.rb b/spec/lib/validators/allowed_ip_address_validator_spec.rb index 03f176293a4..5f9c31b6166 100644 --- a/spec/lib/validators/allowed_ip_address_validator_spec.rb +++ b/spec/lib/validators/allowed_ip_address_validator_spec.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true RSpec.describe AllowedIpAddressValidator do + subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) } + let(:record) { Fabricate.build(:user, trust_level: TrustLevel[0], ip_address: "99.232.23.123") } let(:validator) { described_class.new(attributes: :ip_address) } - subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) } context "when ip address should be blocked" do it "should add an error" do diff --git a/spec/lib/validators/css_color_validator_spec.rb b/spec/lib/validators/css_color_validator_spec.rb index 115531e40b8..acec8e18920 100644 --- a/spec/lib/validators/css_color_validator_spec.rb +++ b/spec/lib/validators/css_color_validator_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true RSpec.describe CssColorValidator do - subject { described_class.new } + subject(:validator) { described_class.new } it "validates hex colors" do - expect(subject.valid_value?("#0")).to eq(false) - expect(subject.valid_value?("#00")).to eq(false) - expect(subject.valid_value?("#000")).to eq(true) - expect(subject.valid_value?("#0000")).to eq(false) - expect(subject.valid_value?("#00000")).to eq(false) - expect(subject.valid_value?("#000000")).to eq(true) + expect(validator.valid_value?("#0")).to eq(false) + expect(validator.valid_value?("#00")).to eq(false) + expect(validator.valid_value?("#000")).to eq(true) + expect(validator.valid_value?("#0000")).to eq(false) + expect(validator.valid_value?("#00000")).to eq(false) + expect(validator.valid_value?("#000000")).to eq(true) end it "validates css colors" do - expect(subject.valid_value?("red")).to eq(true) - expect(subject.valid_value?("green")).to eq(true) - expect(subject.valid_value?("blue")).to eq(true) - expect(subject.valid_value?("hello")).to eq(false) + expect(validator.valid_value?("red")).to eq(true) + expect(validator.valid_value?("green")).to eq(true) + expect(validator.valid_value?("blue")).to eq(true) + expect(validator.valid_value?("hello")).to eq(false) end end diff --git a/spec/lib/validators/enable_local_logins_via_email_validator_spec.rb b/spec/lib/validators/enable_local_logins_via_email_validator_spec.rb index 8469aae93a0..ff68d47a608 100644 --- a/spec/lib/validators/enable_local_logins_via_email_validator_spec.rb +++ b/spec/lib/validators/enable_local_logins_via_email_validator_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe EnableLocalLoginsViaEmailValidator do - subject { described_class.new } + subject(:validator) { described_class.new } describe "#valid_value?" do describe "when 'enable_local_logins' is false" do @@ -9,15 +9,15 @@ RSpec.describe EnableLocalLoginsViaEmailValidator do describe "when val is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should not be valid" do - expect(subject.valid_value?("t")).to eq(false) + expect(validator.valid_value?("t")).to eq(false) - expect(subject.error_message).to eq( + expect(validator.error_message).to eq( I18n.t("site_settings.errors.enable_local_logins_disabled"), ) end @@ -29,13 +29,13 @@ RSpec.describe EnableLocalLoginsViaEmailValidator do describe "when val is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should be valid" do - expect(subject.valid_value?("t")).to eq(true) + expect(validator.valid_value?("t")).to eq(true) end end end diff --git a/spec/lib/validators/enable_sso_validator_spec.rb b/spec/lib/validators/enable_sso_validator_spec.rb index edbdb21c474..c6ff325701f 100644 --- a/spec/lib/validators/enable_sso_validator_spec.rb +++ b/spec/lib/validators/enable_sso_validator_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe EnableSsoValidator do - subject { described_class.new } + subject(:validator) { described_class.new } describe "#valid_value?" do describe "when 'sso url' is empty" do @@ -9,15 +9,15 @@ RSpec.describe EnableSsoValidator do describe "when val is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should not be valid" do - expect(subject.valid_value?("t")).to eq(false) + expect(validator.valid_value?("t")).to eq(false) - expect(subject.error_message).to eq( + expect(validator.error_message).to eq( I18n.t("site_settings.errors.discourse_connect_url_is_empty"), ) end @@ -29,13 +29,13 @@ RSpec.describe EnableSsoValidator do describe "when value is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should be valid" do - expect(subject.valid_value?("t")).to eq(true) + expect(validator.valid_value?("t")).to eq(true) end end end @@ -46,13 +46,13 @@ RSpec.describe EnableSsoValidator do it "should be invalid" do SiteSetting.enforce_second_factor = "all" - expect(subject.valid_value?("t")).to eq(false) + expect(validator.valid_value?("t")).to eq(false) end it "should be valid" do SiteSetting.enforce_second_factor = "no" - expect(subject.valid_value?("t")).to eq(true) + expect(validator.valid_value?("t")).to eq(true) end end end diff --git a/spec/lib/validators/external_system_avatars_validator_spec.rb b/spec/lib/validators/external_system_avatars_validator_spec.rb index 526eaa372ce..c949238daf4 100644 --- a/spec/lib/validators/external_system_avatars_validator_spec.rb +++ b/spec/lib/validators/external_system_avatars_validator_spec.rb @@ -1,25 +1,25 @@ # frozen_string_literal: true RSpec.describe ExternalSystemAvatarsValidator do - subject { described_class.new } + subject(:validator) { described_class.new } it "disallows disabling external system avatars when Unicode usernames are enabled" do SiteSetting.unicode_usernames = true - expect(subject.valid_value?("f")).to eq(false) - expect(subject.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars")) + expect(validator.valid_value?("f")).to eq(false) + expect(validator.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars")) - expect(subject.valid_value?("t")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("t")).to eq(true) + expect(validator.error_message).to be_blank end it "allows disabling external system avatars when Unicode usernames are disabled" do SiteSetting.unicode_usernames = false - expect(subject.valid_value?("t")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("t")).to eq(true) + expect(validator.error_message).to be_blank - expect(subject.valid_value?("f")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("f")).to eq(true) + expect(validator.error_message).to be_blank end end diff --git a/spec/lib/validators/ip_address_format_validator_spec.rb b/spec/lib/validators/ip_address_format_validator_spec.rb index 1e9df7db3cf..d0c5abc71bb 100644 --- a/spec/lib/validators/ip_address_format_validator_spec.rb +++ b/spec/lib/validators/ip_address_format_validator_spec.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true RSpec.describe IpAddressFormatValidator do + subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) } + let(:record) { Fabricate.build(:screened_ip_address, ip_address: "99.232.23.123") } let(:validator) { described_class.new(attributes: :ip_address) } - subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) } %w[99.232.23.123 99.232.0.0/16 fd12:db8::ff00:42:8329 fc00::/7].each do |arg| it "should not add an error for #{arg}" do diff --git a/spec/lib/validators/password_validator_spec.rb b/spec/lib/validators/password_validator_spec.rb index eb8bc4e590a..ce27c633a8d 100644 --- a/spec/lib/validators/password_validator_spec.rb +++ b/spec/lib/validators/password_validator_spec.rb @@ -5,9 +5,10 @@ RSpec.describe PasswordValidator do I18n.t("activerecord.errors.models.user.attributes.password.#{key.to_s}") end - let(:validator) { described_class.new(attributes: :password) } subject(:validate) { validator.validate_each(record, :password, @password) } + let(:validator) { described_class.new(attributes: :password) } + describe "password required" do let(:record) do u = Fabricate.build(:user, password: @password) diff --git a/spec/lib/validators/regex_presence_validator_spec.rb b/spec/lib/validators/regex_presence_validator_spec.rb index 416ac83d2cc..cac2332a2aa 100644 --- a/spec/lib/validators/regex_presence_validator_spec.rb +++ b/spec/lib/validators/regex_presence_validator_spec.rb @@ -1,28 +1,28 @@ # frozen_string_literal: true RSpec.describe RegexPresenceValidator do - subject do + subject(:validator) do described_class.new(regex: "latest", regex_error: "site_settings.errors.must_include_latest") end describe "#valid_value?" do describe "when value is present" do it "without regex match" do - expect(subject.valid_value?("categories|new")).to eq(false) + expect(validator.valid_value?("categories|new")).to eq(false) - expect(subject.error_message).to eq(I18n.t("site_settings.errors.must_include_latest")) + expect(validator.error_message).to eq(I18n.t("site_settings.errors.must_include_latest")) end it "with regex match" do - expect(subject.valid_value?("latest|categories")).to eq(true) + expect(validator.valid_value?("latest|categories")).to eq(true) end end describe "when value is empty" do it "should not be valid" do - expect(subject.valid_value?("")).to eq(false) + expect(validator.valid_value?("")).to eq(false) - expect(subject.error_message).to eq(I18n.t("site_settings.errors.must_include_latest")) + expect(validator.error_message).to eq(I18n.t("site_settings.errors.must_include_latest")) end end end diff --git a/spec/lib/validators/regexp_list_validator_spec.rb b/spec/lib/validators/regexp_list_validator_spec.rb index fb2f816c414..98f2990f11e 100644 --- a/spec/lib/validators/regexp_list_validator_spec.rb +++ b/spec/lib/validators/regexp_list_validator_spec.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true RSpec.describe RegexpListValidator do - subject { described_class.new } + subject(:validator) { described_class.new } it "allows lists of valid regular expressions" do - expect(subject.valid_value?('\d+|[0-9]?|\w+')).to eq(true) + expect(validator.valid_value?('\d+|[0-9]?|\w+')).to eq(true) end it "does not allow lists of invalid regular expressions do" do - expect(subject.valid_value?('\d+|[0-9?|\w+')).to eq(false) - expect(subject.error_message).to eq( + expect(validator.valid_value?('\d+|[0-9?|\w+')).to eq(false) + expect(validator.error_message).to eq( I18n.t( "site_settings.errors.invalid_regex_with_message", regex: "[0-9?", diff --git a/spec/lib/validators/sso_overrides_email_validator_spec.rb b/spec/lib/validators/sso_overrides_email_validator_spec.rb index cb868e6d391..ff5623e7eec 100644 --- a/spec/lib/validators/sso_overrides_email_validator_spec.rb +++ b/spec/lib/validators/sso_overrides_email_validator_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe SsoOverridesEmailValidator do - subject { described_class.new } + subject(:validator) { described_class.new } describe "#valid_value?" do describe "when 'email editable' is true" do @@ -13,15 +13,17 @@ RSpec.describe SsoOverridesEmailValidator do describe "when val is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should not be valid" do - expect(subject.valid_value?("t")).to eq(false) + expect(validator.valid_value?("t")).to eq(false) - expect(subject.error_message).to eq(I18n.t("site_settings.errors.email_editable_enabled")) + expect(validator.error_message).to eq( + I18n.t("site_settings.errors.email_editable_enabled"), + ) end end end @@ -35,13 +37,13 @@ RSpec.describe SsoOverridesEmailValidator do describe "when value is false" do it "should be valid" do - expect(subject.valid_value?("f")).to eq(true) + expect(validator.valid_value?("f")).to eq(true) end end describe "when value is true" do it "should be valid" do - expect(subject.valid_value?("t")).to eq(true) + expect(validator.valid_value?("t")).to eq(true) end end end diff --git a/spec/lib/validators/unicode_username_allowlist_validator_spec.rb b/spec/lib/validators/unicode_username_allowlist_validator_spec.rb index de53888d05c..60d9d8131a7 100644 --- a/spec/lib/validators/unicode_username_allowlist_validator_spec.rb +++ b/spec/lib/validators/unicode_username_allowlist_validator_spec.rb @@ -1,37 +1,37 @@ # frozen_string_literal: true RSpec.describe UnicodeUsernameAllowlistValidator do - subject { described_class.new } + subject(:validator) { described_class.new } it "allows an empty allowlist" do - expect(subject.valid_value?("")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("")).to eq(true) + expect(validator.error_message).to be_blank end it "disallows leading and trailing slashes" do expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash") - expect(subject.valid_value?("/foo/")).to eq(false) - expect(subject.error_message).to eq(expected_error) + expect(validator.valid_value?("/foo/")).to eq(false) + expect(validator.error_message).to eq(expected_error) - expect(subject.valid_value?("foo/")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("foo/")).to eq(true) + expect(validator.error_message).to be_blank - expect(subject.valid_value?("/foo")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("/foo")).to eq(true) + expect(validator.error_message).to be_blank - expect(subject.valid_value?("f/o/o")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("f/o/o")).to eq(true) + expect(validator.error_message).to be_blank - expect(subject.valid_value?("/foo/i")).to eq(false) - expect(subject.error_message).to eq(expected_error) + expect(validator.valid_value?("/foo/i")).to eq(false) + expect(validator.error_message).to eq(expected_error) end it "detects invalid regular expressions" do expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: "") - expect(subject.valid_value?("\\p{Foo}")).to eq(false) - expect(subject.error_message).to start_with(expected_error) + expect(validator.valid_value?("\\p{Foo}")).to eq(false) + expect(validator.error_message).to start_with(expected_error) end end diff --git a/spec/lib/validators/unicode_username_validator_spec.rb b/spec/lib/validators/unicode_username_validator_spec.rb index 23656f0caf4..649fca8632e 100644 --- a/spec/lib/validators/unicode_username_validator_spec.rb +++ b/spec/lib/validators/unicode_username_validator_spec.rb @@ -1,25 +1,25 @@ # frozen_string_literal: true RSpec.describe UnicodeUsernameValidator do - subject { described_class.new } + subject(:validator) { described_class.new } it "disallows Unicode usernames when external system avatars are disabled" do SiteSetting.external_system_avatars_enabled = false - expect(subject.valid_value?("t")).to eq(false) - expect(subject.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars")) + expect(validator.valid_value?("t")).to eq(false) + expect(validator.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars")) - expect(subject.valid_value?("f")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("f")).to eq(true) + expect(validator.error_message).to be_blank end it "allows Unicode usernames when external system avatars are enabled" do SiteSetting.external_system_avatars_enabled = true - expect(subject.valid_value?("t")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("t")).to eq(true) + expect(validator.error_message).to be_blank - expect(subject.valid_value?("f")).to eq(true) - expect(subject.error_message).to be_blank + expect(validator.valid_value?("f")).to eq(true) + expect(validator.error_message).to be_blank end end diff --git a/spec/lib/validators/upload_validator_spec.rb b/spec/lib/validators/upload_validator_spec.rb index 49fec1fef84..3f82ff8ea6c 100644 --- a/spec/lib/validators/upload_validator_spec.rb +++ b/spec/lib/validators/upload_validator_spec.rb @@ -45,7 +45,7 @@ RSpec.describe UploadValidator do original_filename: "test.png", filesize: 2_097_152, ) - subject.validate(upload) + validator.validate(upload) expect(upload.errors.full_messages.first).to eq( "Filesize #{I18n.t("upload.images.too_large_humanized", max_size: "1.5 MB")}", ) @@ -62,7 +62,7 @@ RSpec.describe UploadValidator do for_private_message: true, ) - expect(subject.validate(upload)).to eq(true) + expect(validator.validate(upload)).to eq(true) end describe "for a normal user" do @@ -75,7 +75,7 @@ RSpec.describe UploadValidator do for_private_message: true, ) - expect(subject.validate(upload)).to eq(nil) + expect(validator.validate(upload)).to eq(nil) end end end @@ -91,13 +91,13 @@ RSpec.describe UploadValidator do describe "for admin user" do it "should allow the upload" do - expect(subject.validate(upload)).to eq(true) + expect(validator.validate(upload)).to eq(true) end describe "when filename is invalid" do it "should not allow the upload" do upload.original_filename = "test.txt" - expect(subject.validate(upload)).to eq(nil) + expect(validator.validate(upload)).to eq(nil) end end end @@ -106,7 +106,7 @@ RSpec.describe UploadValidator do fab!(:user) { Fabricate(:user) } it "should not allow the upload" do - expect(subject.validate(upload)).to eq(nil) + expect(validator.validate(upload)).to eq(nil) end end end diff --git a/spec/lib/validators/url_validator_spec.rb b/spec/lib/validators/url_validator_spec.rb index 071c3ae939f..1e763f29e77 100644 --- a/spec/lib/validators/url_validator_spec.rb +++ b/spec/lib/validators/url_validator_spec.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true RSpec.describe UrlValidator do + subject(:validate) { validator.validate_each(record, :website, record.website) } + let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) } let(:validator) { described_class.new(attributes: :website) } - subject(:validate) { validator.validate_each(record, :website, record.website) } [ "http://https://google.com", diff --git a/spec/lib/validators/user_full_name_validator_spec.rb b/spec/lib/validators/user_full_name_validator_spec.rb index c25472fd6b3..9fcbb551ec1 100644 --- a/spec/lib/validators/user_full_name_validator_spec.rb +++ b/spec/lib/validators/user_full_name_validator_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true RSpec.describe UserFullNameValidator do - let(:validator) { described_class.new(attributes: :name) } subject(:validate) { validator.validate_each(record, :name, @name) } + + let(:validator) { described_class.new(attributes: :name) } let(:record) { Fabricate.build(:user, name: @name) } context "when name is not required" do diff --git a/spec/lib/webauthn/security_key_authentication_service_spec.rb b/spec/lib/webauthn/security_key_authentication_service_spec.rb index e159119d061..3ca7e5bc91d 100644 --- a/spec/lib/webauthn/security_key_authentication_service_spec.rb +++ b/spec/lib/webauthn/security_key_authentication_service_spec.rb @@ -38,6 +38,8 @@ require "webauthn/security_key_registration_service" # The origin params just need to be whatever your localhost URL for Discourse is. RSpec.describe Webauthn::SecurityKeyAuthenticationService do + subject(:service) { described_class.new(current_user, params, challenge_params) } + let(:security_key_user) { current_user } let!(:security_key) do Fabricate( @@ -91,24 +93,23 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:challenge_params_origin) { "http://localhost:3000" } let(:challenge_params) { { challenge: challenge, rp_id: rp_id, origin: challenge_params_origin } } let(:current_user) { Fabricate(:user) } - let(:subject) { described_class.new(current_user, params, challenge_params) } it "updates last_used when the security key and params are valid" do - expect(subject.authenticate_security_key).to eq(true) + expect(service.authenticate_security_key).to eq(true) expect(security_key.reload.last_used).not_to eq(nil) end context "when params is blank" do let(:params) { nil } it "returns false with no validation" do - expect(subject.authenticate_security_key).to eq(false) + expect(service.authenticate_security_key).to eq(false) end end context "when params is not blank and not a hash" do let(:params) { "test" } it "returns false with no validation" do - expect(subject.authenticate_security_key).to eq(false) + expect(service.authenticate_security_key).to eq(false) end end @@ -116,7 +117,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do before { security_key.destroy } it "raises a NotFoundError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::NotFoundError, I18n.t("webauthn.validation.not_found_error"), ) @@ -127,7 +128,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:security_key_user) { Fabricate(:user) } it "raises an OwnershipError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::OwnershipError, I18n.t("webauthn.validation.ownership_error"), ) @@ -138,7 +139,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:client_data_webauthn_type) { "webauthn.explode" } it "raises an InvalidTypeError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::InvalidTypeError, I18n.t("webauthn.validation.invalid_type_error"), ) @@ -149,7 +150,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:client_data_challenge) { Base64.strict_encode64("invalid challenge") } it "raises a ChallengeMismatchError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::ChallengeMismatchError, I18n.t("webauthn.validation.challenge_mismatch_error"), ) @@ -160,7 +161,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:client_data_origin) { "https://someothersite.com" } it "raises a InvalidOriginError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::InvalidOriginError, I18n.t("webauthn.validation.invalid_origin_error"), ) @@ -171,7 +172,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:rp_id) { "bad_rp_id" } it "raises a InvalidRelyingPartyIdError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::InvalidRelyingPartyIdError, I18n.t("webauthn.validation.invalid_relying_party_id_error"), ) @@ -182,7 +183,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do let(:signature) { Base64.strict_encode64("badsig") } it "raises a PublicKeyError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::PublicKeyError, I18n.t("webauthn.validation.public_key_error"), ) @@ -193,7 +194,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do before { COSE::Algorithm.expects(:find).returns(nil) } it "raises a UnknownCOSEAlgorithmError" do - expect { subject.authenticate_security_key }.to raise_error( + expect { service.authenticate_security_key }.to raise_error( Webauthn::UnknownCOSEAlgorithmError, I18n.t("webauthn.validation.unknown_cose_algorithm_error"), ) @@ -230,7 +231,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do end it "updates last_used when the security key and params are valid" do - expect(subject.authenticate_security_key).to eq(true) + expect(service.authenticate_security_key).to eq(true) expect(security_key.reload.last_used).not_to eq(nil) end end diff --git a/spec/lib/webauthn/security_key_registration_service_spec.rb b/spec/lib/webauthn/security_key_registration_service_spec.rb index 15abc16019e..45d78c516e1 100644 --- a/spec/lib/webauthn/security_key_registration_service_spec.rb +++ b/spec/lib/webauthn/security_key_registration_service_spec.rb @@ -3,6 +3,8 @@ require "webauthn" require "webauthn/security_key_registration_service" RSpec.describe Webauthn::SecurityKeyRegistrationService do + subject(:service) { described_class.new(current_user, params, challenge_params) } + let(:client_data_challenge) { Base64.encode64(challenge) } let(:client_data_webauthn_type) { "webauthn.create" } let(:client_data_origin) { "http://localhost:3000" } @@ -34,13 +36,12 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do let(:challenge_params) { { challenge: challenge, rp_id: rp_id, origin: "http://localhost:3000" } } let(:challenge) { "f1e04530f34a1b6a08d032d8550e23eb8330be04e4166008f26c0e1b42ad" } let(:current_user) { Fabricate(:user) } - let(:subject) { described_class.new(current_user, params, challenge_params) } context "when the client data webauthn type is not webauthn.create" do let(:client_data_webauthn_type) { "webauthn.explode" } it "raises an InvalidTypeError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::InvalidTypeError, I18n.t("webauthn.validation.invalid_type_error"), ) @@ -51,7 +52,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do let(:client_data_challenge) { Base64.encode64("invalid challenge") } it "raises a ChallengeMismatchError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::ChallengeMismatchError, I18n.t("webauthn.validation.challenge_mismatch_error"), ) @@ -62,7 +63,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do let(:client_data_origin) { "https://someothersite.com" } it "raises a InvalidOriginError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::InvalidOriginError, I18n.t("webauthn.validation.invalid_origin_error"), ) @@ -73,7 +74,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do let(:rp_id) { "bad_rp_id" } it "raises a InvalidRelyingPartyIdError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::InvalidRelyingPartyIdError, I18n.t("webauthn.validation.invalid_relying_party_id_error"), ) @@ -87,7 +88,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do end it "raises a UnsupportedPublicKeyAlgorithmError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::UnsupportedPublicKeyAlgorithmError, I18n.t("webauthn.validation.unsupported_public_key_algorithm_error"), ) @@ -103,7 +104,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do end it "raises a UnsupportedAttestationFormatError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::UnsupportedAttestationFormatError, I18n.t("webauthn.validation.unsupported_attestation_format_error"), ) @@ -117,14 +118,14 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do context "when the credential id is already in use for any user" do it "raises a CredentialIdInUseError" do # register the key to the current user - security_key = subject.register_second_factor_security_key + security_key = service.register_second_factor_security_key # update the key to be on a different user other_user = Fabricate(:user) security_key.update(user: other_user) # error! - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::CredentialIdInUseError, I18n.t("webauthn.validation.credential_id_in_use_error"), ) @@ -137,7 +138,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do end it "raises a MalformedAttestationError" do - expect { subject.register_second_factor_security_key }.to raise_error( + expect { service.register_second_factor_security_key }.to raise_error( Webauthn::MalformedAttestationError, I18n.t("webauthn.validation.malformed_attestation_error"), ) diff --git a/spec/mailers/subscription_mailer_spec.rb b/spec/mailers/subscription_mailer_spec.rb index e61e0657380..fff84e4c534 100644 --- a/spec/mailers/subscription_mailer_spec.rb +++ b/spec/mailers/subscription_mailer_spec.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true RSpec.describe SubscriptionMailer do + subject(:mail) { SubscriptionMailer.confirm_unsubscribe(user) } + fab!(:user) { Fabricate(:user) } - subject { SubscriptionMailer.confirm_unsubscribe(user) } - it "contains the right URL" do - expect(subject.body).to include( + expect(mail.body).to include( "#{Discourse.base_url}/email/unsubscribe/#{UnsubscribeKey.last.key}", ) end diff --git a/spec/mailers/user_notifications_spec.rb b/spec/mailers/user_notifications_spec.rb index 1482d04213e..f9589fffb54 100644 --- a/spec/mailers/user_notifications_spec.rb +++ b/spec/mailers/user_notifications_spec.rb @@ -58,24 +58,24 @@ RSpec.describe UserNotifications do end describe ".signup" do - subject { UserNotifications.signup(user) } + subject(:email) { UserNotifications.signup(user) } it "works" do - expect(subject.to).to eq([user.email]) - expect(subject.subject).to be_present - expect(subject.from).to eq([SiteSetting.notification_email]) - expect(subject.body).to be_present + expect(email.to).to eq([user.email]) + expect(email.subject).to be_present + expect(email.from).to eq([SiteSetting.notification_email]) + expect(email.body).to be_present end end describe ".forgot_password" do - subject { UserNotifications.forgot_password(user) } + subject(:email) { UserNotifications.forgot_password(user) } it "works" do - expect(subject.to).to eq([user.email]) - expect(subject.subject).to be_present - expect(subject.from).to eq([SiteSetting.notification_email]) - expect(subject.body).to be_present + expect(email.to).to eq([user.email]) + expect(email.subject).to be_present + expect(email.from).to eq([SiteSetting.notification_email]) + expect(email.body).to be_present end end @@ -119,20 +119,21 @@ RSpec.describe UserNotifications do end describe ".email_login" do + subject(:email) { UserNotifications.email_login(user, email_token: email_token) } + let(:email_token) do Fabricate(:email_token, user: user, scope: EmailToken.scopes[:email_login]).token end - subject { UserNotifications.email_login(user, email_token: email_token) } it "generates the right email" do - expect(subject.to).to eq([user.email]) - expect(subject.from).to eq([SiteSetting.notification_email]) + expect(email.to).to eq([user.email]) + expect(email.from).to eq([SiteSetting.notification_email]) - expect(subject.subject).to eq( + expect(email.subject).to eq( I18n.t("user_notifications.email_login.subject_template", email_prefix: SiteSetting.title), ) - expect(subject.body.to_s).to match( + expect(email.body.to_s).to match( I18n.t( "user_notifications.email_login.text_body_template", site_name: SiteSetting.title, @@ -144,13 +145,13 @@ RSpec.describe UserNotifications do end describe ".digest" do - subject { UserNotifications.digest(user) } + subject(:email) { UserNotifications.digest(user) } after { Discourse.redis.keys("summary-new-users:*").each { |key| Discourse.redis.del(key) } } context "without new topics" do it "doesn't send the email" do - expect(subject.to).to be_blank + expect(email.to).to be_blank end end @@ -172,8 +173,8 @@ RSpec.describe UserNotifications do end it "returns topics from new users if they're more than 24 hours old" do - expect(subject.to).to eq([user.email]) - html = subject.html_part.body.to_s + expect(email.to).to eq([user.email]) + html = email.html_part.body.to_s expect(html).to include(new_yesterday.title) expect(html).to_not include(new_today.title) end @@ -185,18 +186,18 @@ RSpec.describe UserNotifications do end it "works" do - expect(subject.to).to eq([user.email]) - expect(subject.subject).to be_present - expect(subject.from).to eq([SiteSetting.notification_email]) - expect(subject.html_part.body.to_s).to be_present - expect(subject.text_part.body.to_s).to be_present - expect(subject.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/) - expect(subject.html_part.body.to_s).to include("New Users") + expect(email.to).to eq([user.email]) + expect(email.subject).to be_present + expect(email.from).to eq([SiteSetting.notification_email]) + expect(email.html_part.body.to_s).to be_present + expect(email.text_part.body.to_s).to be_present + expect(email.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/) + expect(email.html_part.body.to_s).to include("New Users") end it "doesn't include new user count if digest_after_minutes is low" do user.user_option.digest_after_minutes = 60 - expect(subject.html_part.body.to_s).to_not include("New Users") + expect(email.html_part.body.to_s).to_not include("New Users") end it "works with min_date string" do @@ -210,8 +211,8 @@ RSpec.describe UserNotifications do SiteSetting.email_prefix = "Try Discourse" SiteSetting.title = "Discourse Meta" - expect(subject.subject).to match(/Try Discourse/) - expect(subject.subject).not_to match(/Discourse Meta/) + expect(email.subject).to match(/Try Discourse/) + expect(email.subject).not_to match(/Discourse Meta/) end it "includes unread likes received count within the since date" do @@ -257,7 +258,7 @@ RSpec.describe UserNotifications do created_at: 1.hour.ago, ) deleted.trash! - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to_not include deleted.title expect(html).to_not include post.raw end @@ -276,7 +277,7 @@ RSpec.describe UserNotifications do raw: "secret draft content", created_at: 1.hour.ago, ) - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to_not include topic.title expect(html).to_not include post.raw end @@ -319,7 +320,7 @@ RSpec.describe UserNotifications do post_type: Post.types[:small_action], created_at: 1.hour.ago, ) - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to_not include whisper.raw expect(html).to_not include mod_action.raw expect(html).to_not include small_action.raw @@ -365,7 +366,7 @@ RSpec.describe UserNotifications do user_deleted: true, created_at: 1.hour.ago, ) - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to_not include deleted.raw expect(html).to_not include hidden.raw expect(html).to_not include user_deleted.raw @@ -389,7 +390,7 @@ RSpec.describe UserNotifications do post_number: 1, created_at: 1.minute.ago, ) - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to_not include too_new.title end @@ -408,20 +409,20 @@ RSpec.describe UserNotifications do theme.set_default! - html = subject.html_part.body.to_s + html = email.html_part.body.to_s expect(html).to include "F0F0F0" expect(html).to include "1E1E1E" end it "supports subfolder" do set_subfolder "/forum" - html = subject.html_part.body.to_s - text = subject.text_part.body.to_s + html = email.html_part.body.to_s + text = email.text_part.body.to_s expect(html).to be_present expect(text).to be_present expect(html).to_not include("/forum/forum") expect(text).to_not include("/forum/forum") - expect(subject.header["List-Unsubscribe"].to_s).to match( + expect(email.header["List-Unsubscribe"].to_s).to match( /http:\/\/test.localhost\/forum\/email\/unsubscribe\/\h{64}/, ) @@ -432,7 +433,7 @@ RSpec.describe UserNotifications do it "applies lang/xml:lang html attributes" do SiteSetting.default_locale = "pl_PL" - html = subject.html_part.to_s + html = email.html_part.to_s expect(html).to match(' lang="pl-PL"') expect(html).to match(' xml:lang="pl-PL"') diff --git a/spec/mailers/version_mailer_spec.rb b/spec/mailers/version_mailer_spec.rb index 59c047ba9d4..9e2da3c2203 100644 --- a/spec/mailers/version_mailer_spec.rb +++ b/spec/mailers/version_mailer_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true RSpec.describe VersionMailer do - subject { VersionMailer.send_notice } + subject(:mail) { VersionMailer.send_notice } context "when contact_email is blank" do before { SiteSetting.contact_email = "" } it "doesn't send the email" do - expect(subject.to).to be_blank + expect(mail.to).to be_blank end end @@ -15,10 +15,10 @@ RSpec.describe VersionMailer do before { SiteSetting.contact_email = "me@example.com" } it "works" do - expect(subject.to).to eq(["me@example.com"]) - expect(subject.subject).to be_present - expect(subject.from).to eq([SiteSetting.notification_email]) - expect(subject.body).to be_present + expect(mail.to).to eq(["me@example.com"]) + expect(mail.subject).to be_present + expect(mail.from).to eq([SiteSetting.notification_email]) + expect(mail.body).to be_present end end end diff --git a/spec/models/admin_dashboard_data_spec.rb b/spec/models/admin_dashboard_data_spec.rb index 7dc061cebbc..bc7b947e5b5 100644 --- a/spec/models/admin_dashboard_data_spec.rb +++ b/spec/models/admin_dashboard_data_spec.rb @@ -126,93 +126,93 @@ RSpec.describe AdminDashboardData do end describe "rails_env_check" do - subject { described_class.new.rails_env_check } + subject(:check) { described_class.new.rails_env_check } it "returns nil when running in production mode" do Rails.stubs(env: ActiveSupport::StringInquirer.new("production")) - expect(subject).to be_nil + expect(check).to be_nil end it "returns a string when running in development mode" do Rails.stubs(env: ActiveSupport::StringInquirer.new("development")) - expect(subject).to_not be_nil + expect(check).to_not be_nil end it "returns a string when running in test mode" do Rails.stubs(env: ActiveSupport::StringInquirer.new("test")) - expect(subject).to_not be_nil + expect(check).to_not be_nil end end describe "host_names_check" do - subject { described_class.new.host_names_check } + subject(:check) { described_class.new.host_names_check } it "returns nil when host_names is set" do Discourse.stubs(:current_hostname).returns("something.com") - expect(subject).to be_nil + expect(check).to be_nil end it "returns a string when host_name is localhost" do Discourse.stubs(:current_hostname).returns("localhost") - expect(subject).to_not be_nil + expect(check).to_not be_nil end it "returns a string when host_name is production.localhost" do Discourse.stubs(:current_hostname).returns("production.localhost") - expect(subject).to_not be_nil + expect(check).to_not be_nil end end describe "sidekiq_check" do - subject { described_class.new.sidekiq_check } + subject(:check) { described_class.new.sidekiq_check } it "returns nil when sidekiq processed a job recently" do Jobs.stubs(:last_job_performed_at).returns(1.minute.ago) Jobs.stubs(:queued).returns(0) - expect(subject).to be_nil + expect(check).to be_nil end it "returns nil when last job processed was a long time ago, but no jobs are queued" do Jobs.stubs(:last_job_performed_at).returns(7.days.ago) Jobs.stubs(:queued).returns(0) - expect(subject).to be_nil + expect(check).to be_nil end it "returns nil when no jobs have ever been processed, but no jobs are queued" do Jobs.stubs(:last_job_performed_at).returns(nil) Jobs.stubs(:queued).returns(0) - expect(subject).to be_nil + expect(check).to be_nil end it "returns a string when no jobs were processed recently and some jobs are queued" do Jobs.stubs(:last_job_performed_at).returns(20.minutes.ago) Jobs.stubs(:queued).returns(1) - expect(subject).to_not be_nil + expect(check).to_not be_nil end it "returns a string when no jobs have ever been processed, and some jobs are queued" do Jobs.stubs(:last_job_performed_at).returns(nil) Jobs.stubs(:queued).returns(1) - expect(subject).to_not be_nil + expect(check).to_not be_nil end end describe "ram_check" do - subject { described_class.new.ram_check } + subject(:check) { described_class.new.ram_check } it "returns nil when total ram is 1 GB" do MemInfo.any_instance.stubs(:mem_total).returns(1_025_272) - expect(subject).to be_nil + expect(check).to be_nil end it "returns nil when total ram cannot be determined" do MemInfo.any_instance.stubs(:mem_total).returns(nil) - expect(subject).to be_nil + expect(check).to be_nil end it "returns a string when total ram is less than 1 GB" do MemInfo.any_instance.stubs(:mem_total).returns(512_636) - expect(subject).to_not be_nil + expect(check).to_not be_nil end end @@ -221,7 +221,7 @@ RSpec.describe AdminDashboardData do context "when disabled" do it "returns nil" do SiteSetting.set(enable_setting, false) - expect(subject).to be_nil + expect(check).to be_nil end end @@ -231,31 +231,32 @@ RSpec.describe AdminDashboardData do it "returns nil when key and secret are set" do SiteSetting.set(key, "12313213") SiteSetting.set(secret, "12312313123") - expect(subject).to be_nil + expect(check).to be_nil end it "returns a string when key is not set" do SiteSetting.set(key, "") SiteSetting.set(secret, "12312313123") - expect(subject).to_not be_nil + expect(check).to_not be_nil end it "returns a string when secret is not set" do SiteSetting.set(key, "123123") SiteSetting.set(secret, "") - expect(subject).to_not be_nil + expect(check).to_not be_nil end it "returns a string when key and secret are not set" do SiteSetting.set(key, "") SiteSetting.set(secret, "") - expect(subject).to_not be_nil + expect(check).to_not be_nil end end end describe "facebook" do - subject { described_class.new.facebook_config_check } + subject(:check) { described_class.new.facebook_config_check } + let(:enable_setting) { :enable_facebook_logins } let(:key) { :facebook_app_id } let(:secret) { :facebook_app_secret } @@ -263,7 +264,8 @@ RSpec.describe AdminDashboardData do end describe "twitter" do - subject { described_class.new.twitter_config_check } + subject(:check) { described_class.new.twitter_config_check } + let(:enable_setting) { :enable_twitter_logins } let(:key) { :twitter_consumer_key } let(:secret) { :twitter_consumer_secret } @@ -271,7 +273,8 @@ RSpec.describe AdminDashboardData do end describe "github" do - subject { described_class.new.github_config_check } + subject(:check) { described_class.new.github_config_check } + let(:enable_setting) { :enable_github_logins } let(:key) { :github_client_id } let(:secret) { :github_client_secret } @@ -280,28 +283,28 @@ RSpec.describe AdminDashboardData do end describe "force_https_check" do - subject { described_class.new(check_force_https: true).force_https_check } + subject(:check) { described_class.new(check_force_https: true).force_https_check } it "returns nil if force_https site setting enabled" do SiteSetting.force_https = true - expect(subject).to be_nil + expect(check).to be_nil end it "returns nil if force_https site setting not enabled" do SiteSetting.force_https = false - expect(subject).to eq(I18n.t("dashboard.force_https_warning", base_path: Discourse.base_path)) + expect(check).to eq(I18n.t("dashboard.force_https_warning", base_path: Discourse.base_path)) end end describe "ignore force_https_check" do - subject { described_class.new(check_force_https: false).force_https_check } + subject(:check) { described_class.new(check_force_https: false).force_https_check } it "returns nil" do SiteSetting.force_https = true - expect(subject).to be_nil + expect(check).to be_nil SiteSetting.force_https = false - expect(subject).to be_nil + expect(check).to be_nil end end diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index d59d7abb984..8b50208fd04 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -556,13 +556,13 @@ RSpec.describe Category do end describe "new" do - subject { Fabricate.build(:category, user: Fabricate(:user)) } + subject(:category) { Fabricate.build(:category, user: Fabricate(:user)) } it "triggers a extensibility event" do - event = DiscourseEvent.track_events { subject.save! }.last + event = DiscourseEvent.track_events { category.save! }.last expect(event[:event_name]).to eq(:category_created) - expect(event[:params].first).to eq(subject) + expect(event[:params].first).to eq(category) end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 7fdbe2f74d6..4689284a524 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -502,13 +502,13 @@ RSpec.describe Group do end describe "new" do - subject { Fabricate.build(:group) } + subject(:group) { Fabricate.build(:group) } it "triggers a extensibility event" do - event = DiscourseEvent.track_events { subject.save! }.first + event = DiscourseEvent.track_events { group.save! }.first expect(event[:event_name]).to eq(:group_created) - expect(event[:params].first).to eq(subject) + expect(event[:params].first).to eq(group) end end diff --git a/spec/models/permalink_spec.rb b/spec/models/permalink_spec.rb index c22c49d1ad2..6e1d2c53451 100644 --- a/spec/models/permalink_spec.rb +++ b/spec/models/permalink_spec.rb @@ -24,12 +24,13 @@ RSpec.describe Permalink do end describe "target_url" do + subject(:target_url) { permalink.target_url } + let(:permalink) { Fabricate.build(:permalink) } let(:topic) { Fabricate(:topic) } let(:post) { Fabricate(:post, topic: topic) } let(:category) { Fabricate(:category) } let(:tag) { Fabricate(:tag) } - subject(:target_url) { permalink.target_url } it "returns a topic url when topic_id is set" do permalink.topic_id = topic.id diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 076d5b846ca..3efcf065fb8 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -46,6 +46,8 @@ RSpec.describe Report do describe "counting" do describe "requests" do + subject(:json) { Report.find("http_total_reqs").as_json } + before do freeze_time DateTime.parse("2017-03-01 12:00") @@ -89,8 +91,6 @@ RSpec.describe Report do ApplicationRequest.insert_all(application_requests) end - subject(:json) { Report.find("http_total_reqs").as_json } - it "counts the correct records" do expect(json[:data].size).to eq(31) # today and 30 full days expect(json[:data][0..-2].sum { |d| d[:y] }).to eq(300) diff --git a/spec/models/screened_email_spec.rb b/spec/models/screened_email_spec.rb index 802b9aa83f1..479df6b19bb 100644 --- a/spec/models/screened_email_spec.rb +++ b/spec/models/screened_email_spec.rb @@ -52,7 +52,7 @@ RSpec.describe ScreenedEmail do end describe "#should_block?" do - subject { ScreenedEmail.should_block?(email) } + subject(:should_block) { ScreenedEmail.should_block?(email) } it "automatically blocks via email canonicalization" do SiteSetting.levenshtein_distance_spammer_emails = 0 @@ -63,7 +63,7 @@ RSpec.describe ScreenedEmail do end it "returns false if a record with the email doesn't exist" do - expect(subject).to eq(false) + expect(should_block).to eq(false) end it "returns true when there is a record with the email" do @@ -86,7 +86,7 @@ RSpec.describe ScreenedEmail do shared_examples "when a ScreenedEmail record matches" do it "updates statistics" do freeze_time do - expect { subject }.to change { screened_email.reload.match_count }.by(1) + expect { should_block }.to change { screened_email.reload.match_count }.by(1) expect(screened_email.last_match_at).to eq_time(Time.zone.now) end end diff --git a/spec/models/screened_url_spec.rb b/spec/models/screened_url_spec.rb index cfcc685ec50..a6ad06cdb2b 100644 --- a/spec/models/screened_url_spec.rb +++ b/spec/models/screened_url_spec.rb @@ -25,27 +25,28 @@ RSpec.describe ScreenedUrl do end describe "normalize" do - let(:record) { described_class.new(@params) } - subject do + subject(:normalized) do record.normalize record end + let(:record) { described_class.new(@params) } + %w[http:// HTTP:// https:// HTTPS://].each do |prefix| it "strips #{prefix}" do @params = valid_params.merge(url: url.gsub("http://", prefix)) - expect(subject.url).to eq(url.gsub("http://", "")) + expect(normalized.url).to eq(url.gsub("http://", "")) end end it "strips trailing slash" do @params = valid_params.merge(url: "silverbullet.in/") - expect(subject.url).to eq("silverbullet.in") + expect(normalized.url).to eq("silverbullet.in") end it "strips trailing slashes" do @params = valid_params.merge(url: "silverbullet.in/buy///") - expect(subject.url).to eq("silverbullet.in/buy") + expect(normalized.url).to eq("silverbullet.in/buy") end it "downcases domains" do diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 47e6b886cb6..9791733edc9 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -35,13 +35,13 @@ RSpec.describe Tag do end describe "new" do - subject { Fabricate.build(:tag) } + subject(:tag) { Fabricate.build(:tag) } it "triggers a extensibility event" do - event = DiscourseEvent.track_events { subject.save! }.last + event = DiscourseEvent.track_events { tag.save! }.last expect(event[:event_name]).to eq(:tag_created) - expect(event[:params].first).to eq(subject) + expect(event[:params].first).to eq(tag) end it "prevents case-insensitive duplicates" do @@ -59,13 +59,13 @@ RSpec.describe Tag do end describe "destroy" do - subject { Fabricate(:tag) } + subject(:tag) { Fabricate(:tag) } it "triggers a extensibility event" do - event = DiscourseEvent.track_events { subject.destroy! }.last + event = DiscourseEvent.track_events { tag.destroy! }.last expect(event[:event_name]).to eq(:tag_destroyed) - expect(event[:params].first).to eq(subject) + expect(event[:params].first).to eq(tag) end it "removes it from its tag group" do diff --git a/spec/models/trust_level3_requirements_spec.rb b/spec/models/trust_level3_requirements_spec.rb index 19bc70b132c..d5abacef6fc 100644 --- a/spec/models/trust_level3_requirements_spec.rb +++ b/spec/models/trust_level3_requirements_spec.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true RSpec.describe TrustLevel3Requirements do - fab!(:user) { Fabricate(:user) } subject(:tl3_requirements) { described_class.new(user) } - fab!(:moderator) { Fabricate(:moderator) } + fab!(:user) { Fabricate(:user) } + fab!(:moderator) { Fabricate(:moderator) } fab!(:topic1) { Fabricate(:topic) } fab!(:topic2) { Fabricate(:topic) } fab!(:topic3) { Fabricate(:topic) } diff --git a/spec/models/user_field_spec.rb b/spec/models/user_field_spec.rb index f39d3911a29..cf056e5f0b0 100644 --- a/spec/models/user_field_spec.rb +++ b/spec/models/user_field_spec.rb @@ -2,12 +2,14 @@ RSpec.describe UserField do describe "doesn't validate presence of name if field type is 'confirm'" do - subject { described_class.new(field_type: "confirm") } + subject(:confirm_field) { described_class.new(field_type: "confirm") } + it { is_expected.not_to validate_presence_of :name } end describe "validates presence of name for other field types" do - subject { described_class.new(field_type: "dropdown") } + subject(:dropdown_field) { described_class.new(field_type: "dropdown") } + it { is_expected.to validate_presence_of :name } end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 892fafc04fd..1c5ecc381d9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -641,35 +641,33 @@ RSpec.describe User do end describe "new" do - subject { Fabricate.build(:user) } + subject(:user) { Fabricate.build(:user) } it { is_expected.to be_valid } it { is_expected.not_to be_admin } it { is_expected.not_to be_approved } it "is properly initialized" do - expect(subject.approved_at).to be_blank - expect(subject.approved_by_id).to be_blank + expect(user.approved_at).to be_blank + expect(user.approved_by_id).to be_blank end it "triggers an extensibility event" do - event = DiscourseEvent.track_events { subject.save! }.first + event = DiscourseEvent.track_events { user.save! }.first expect(event[:event_name]).to eq(:user_created) - expect(event[:params].first).to eq(subject) + expect(event[:params].first).to eq(user) end context "with after_save" do - before { subject.save! } + before { user.save! } it "has correct settings" do - expect(subject.email_tokens).to be_present - expect(subject.user_stat).to be_present - expect(subject.user_profile).to be_present - expect(subject.user_option.email_messages_level).to eq( - UserOption.email_level_types[:always], - ) - expect(subject.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away]) + expect(user.email_tokens).to be_present + expect(user.user_stat).to be_present + expect(user.user_profile).to be_present + expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:always]) + expect(user.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away]) end end @@ -756,41 +754,37 @@ RSpec.describe User do end describe "staff and regular users" do - let(:user) { Fabricate.build(:user) } + subject(:user) { Fabricate.build(:user) } describe "#staff?" do - subject { user.staff? } - - it { is_expected.to eq(false) } + it { is_expected.not_to be_staff } context "for a moderator user" do before { user.moderator = true } - it { is_expected.to eq(true) } + it { is_expected.to be_staff } end context "for an admin user" do before { user.admin = true } - it { is_expected.to eq(true) } + it { is_expected.to be_staff } end end describe "#regular?" do - subject { user.regular? } - - it { is_expected.to eq(true) } + it { is_expected.to be_regular } context "for a moderator user" do before { user.moderator = true } - it { is_expected.to eq(false) } + it { is_expected.not_to be_regular } end context "for an admin user" do before { user.admin = true } - it { is_expected.to eq(false) } + it { is_expected.not_to be_regular } end end end @@ -3251,7 +3245,7 @@ RSpec.describe User do end it "returns false if no whispers groups exist" do - expect(subject.whisperer?).to eq(false) + expect(user.whisperer?).to eq(false) end end diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index 8a3fbef6efb..5a6bf1757ab 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -7,30 +7,30 @@ RSpec.describe WebHook do it { is_expected.to validate_presence_of :web_hook_event_types } describe "#content_types" do - subject { WebHook.content_types } + subject(:content_types) { WebHook.content_types } it "'json' (application/json) should be at 1st position" do - expect(subject["application/json"]).to eq(1) + expect(content_types["application/json"]).to eq(1) end it "'url_encoded' (application/x-www-form-urlencoded) should be at 2st position" do - expect(subject["application/x-www-form-urlencoded"]).to eq(2) + expect(content_types["application/x-www-form-urlencoded"]).to eq(2) end end describe "#last_delivery_statuses" do - subject { WebHook.last_delivery_statuses } + subject(:statuses) { WebHook.last_delivery_statuses } it "inactive should be at 1st position" do - expect(subject[:inactive]).to eq(1) + expect(statuses[:inactive]).to eq(1) end it "failed should be at 2st position" do - expect(subject[:failed]).to eq(2) + expect(statuses[:failed]).to eq(2) end it "successful should be at 3st position" do - expect(subject[:successful]).to eq(3) + expect(statuses[:successful]).to eq(3) end end diff --git a/spec/requests/tags_controller_spec.rb b/spec/requests/tags_controller_spec.rb index 4e7ffe6ad18..238e6cae103 100644 --- a/spec/requests/tags_controller_spec.rb +++ b/spec/requests/tags_controller_spec.rb @@ -1347,18 +1347,19 @@ RSpec.describe TagsController do end describe "#destroy_synonym" do + subject(:destroy_synonym) { delete("/tag/#{tag.name}/synonyms/#{synonym.name}.json") } + fab!(:tag) { Fabricate(:tag) } fab!(:synonym) { Fabricate(:tag, target_tag: tag, name: "synonym") } - subject { delete("/tag/#{tag.name}/synonyms/#{synonym.name}.json") } it "fails if not logged in" do - subject + destroy_synonym expect(response.status).to eq(403) end it "fails if not staff user" do sign_in(user) - subject + destroy_synonym expect(response.status).to eq(403) end @@ -1367,7 +1368,7 @@ RSpec.describe TagsController do it "can remove a synonym from a tag" do synonym2 = Fabricate(:tag, target_tag: tag, name: "synonym2") - expect { subject }.to_not change { Tag.count } + expect { destroy_synonym }.to_not change { Tag.count } expect_same_tag_names(tag.reload.synonyms, [synonym2]) expect(synonym.reload).to_not be_synonym end diff --git a/spec/serializers/admin_plugin_serializer_spec.rb b/spec/serializers/admin_plugin_serializer_spec.rb index 6e242356606..eb2a86bc828 100644 --- a/spec/serializers/admin_plugin_serializer_spec.rb +++ b/spec/serializers/admin_plugin_serializer_spec.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true RSpec.describe AdminPluginSerializer do - let(:instance) { Plugin::Instance.new } + subject(:serializer) { described_class.new(instance) } - subject { described_class.new(instance) } + let(:instance) { Plugin::Instance.new } describe "enabled_setting" do it "should return the right value" do instance.enabled_site_setting("test") - expect(subject.enabled_setting).to eq("test") + expect(serializer.enabled_setting).to eq("test") end end diff --git a/spec/serializers/basic_group_serializer_spec.rb b/spec/serializers/basic_group_serializer_spec.rb index 7758fda3ce7..c4800008f52 100644 --- a/spec/serializers/basic_group_serializer_spec.rb +++ b/spec/serializers/basic_group_serializer_spec.rb @@ -1,16 +1,17 @@ # frozen_string_literal: true RSpec.describe BasicGroupSerializer do + subject(:serializer) { described_class.new(group, scope: guardian, root: false) } + let(:guardian) { Guardian.new } fab!(:group) { Fabricate(:group) } - subject { described_class.new(group, scope: guardian, root: false) } describe "#display_name" do describe "automatic group" do let(:group) { Group.find(1) } it "should include the display name" do - expect(subject.display_name).to eq(I18n.t("groups.default_names.admins")) + expect(serializer.display_name).to eq(I18n.t("groups.default_names.admins")) end end @@ -18,22 +19,22 @@ RSpec.describe BasicGroupSerializer do fab!(:group) { Fabricate(:group) } it "should not include the display name" do - expect(subject.display_name).to eq(nil) + expect(serializer.display_name).to eq(nil) end end end describe "#bio_raw" do - fab!(:group) { Fabricate(:group, bio_raw: "testing :slightly_smiling_face:") } - - subject do + subject(:serializer) do described_class.new(group, scope: guardian, root: false, owner_group_ids: [group.id]) end + fab!(:group) { Fabricate(:group, bio_raw: "testing :slightly_smiling_face:") } + describe "group owner" do it "should include bio_raw" do - expect(subject.as_json[:bio_raw]).to eq("testing :slightly_smiling_face:") - expect(subject.as_json[:bio_excerpt]).to start_with("testing hello world") } fab!(:post) { Fabricate(:post, topic: topic) } @@ -12,29 +14,27 @@ describe BasicReviewableFlaggedPostSerializer do ) end - subject { described_class.new(reviewable, root: false).as_json } - include_examples "basic reviewable attributes" describe "#post_number" do it "equals the post_number of the post" do - expect(subject[:post_number]).to eq(post.post_number) + expect(serializer[:post_number]).to eq(post.post_number) end it "is not included if the reviewable is associated with no post" do reviewable.update!(target: nil) - expect(subject.key?(:post_number)).to eq(false) + expect(serializer.key?(:post_number)).to eq(false) end end describe "#topic_fancy_title" do it "equals the fancy_title of the topic" do - expect(subject[:topic_fancy_title]).to eq("Safe title <a> hello world") + expect(serializer[:topic_fancy_title]).to eq("Safe title <a> hello world") end it "is not included if the reviewable is associated with no topic" do reviewable.update!(topic: nil) - expect(subject.key?(:topic_fancy_title)).to eq(false) + expect(serializer.key?(:topic_fancy_title)).to eq(false) end end end diff --git a/spec/serializers/basic_reviewable_queued_post_serializer_spec.rb b/spec/serializers/basic_reviewable_queued_post_serializer_spec.rb index eb332dc8db8..6cb0728a8e3 100644 --- a/spec/serializers/basic_reviewable_queued_post_serializer_spec.rb +++ b/spec/serializers/basic_reviewable_queued_post_serializer_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true describe BasicReviewableQueuedPostSerializer do + subject(:serializer) { described_class.new(reviewable, root: false).as_json } + fab!(:topic) { Fabricate(:topic, title: "safe title existing topic") } fab!(:reviewable) do ReviewableQueuedPost.create!( @@ -13,40 +15,38 @@ describe BasicReviewableQueuedPostSerializer do ) end - subject { described_class.new(reviewable, root: false).as_json } - include_examples "basic reviewable attributes" describe "#topic_fancy_title" do it "equals the topic's fancy_title" do - expect(subject[:topic_fancy_title]).to eq("Safe title <a> existing topic") + expect(serializer[:topic_fancy_title]).to eq("Safe title <a> existing topic") end it "is not included if the reviewable is associated with no topic" do reviewable.update!(topic: nil) - expect(subject.key?(:topic_fancy_title)).to eq(false) + expect(serializer.key?(:topic_fancy_title)).to eq(false) end end describe "#is_new_topic" do it "is true if the reviewable's payload has a title attribute" do - expect(subject[:is_new_topic]).to eq(true) + expect(serializer[:is_new_topic]).to eq(true) end it "is false if the reviewable's payload doesn't have a title attribute" do reviewable.update!(payload: { raw: "new post 123" }) - expect(subject[:is_new_topic]).to eq(false) + expect(serializer[:is_new_topic]).to eq(false) end end describe "#payload_title" do it "equals the title in the reviewable's payload" do - expect(subject[:payload_title]).to eq("unsafe title ") + expect(serializer[:payload_title]).to eq("unsafe title ") end it "is not included if the reviewable's payload doesn't have a title attribute" do reviewable.update!(payload: { raw: "new post 123" }) - expect(subject.key?(:payload_title)).to eq(false) + expect(serializer.key?(:payload_title)).to eq(false) end end end diff --git a/spec/serializers/basic_reviewable_user_serializer_spec.rb b/spec/serializers/basic_reviewable_user_serializer_spec.rb index abf8f6f9106..f16f899b2cd 100644 --- a/spec/serializers/basic_reviewable_user_serializer_spec.rb +++ b/spec/serializers/basic_reviewable_user_serializer_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true describe BasicReviewableUserSerializer do - fab!(:user) { Fabricate(:user) } + subject(:serializer) { described_class.new(reviewable, root: false).as_json } + fab!(:user) { Fabricate(:user) } fab!(:reviewable) do ReviewableUser.needs_review!( target: user, @@ -17,13 +18,11 @@ describe BasicReviewableUserSerializer do ) end - subject { described_class.new(reviewable, root: false).as_json } - include_examples "basic reviewable attributes" describe "#username" do it "equals the username in the reviewable's payload" do - expect(subject[:username]).to eq(user.username) + expect(serializer[:username]).to eq(user.username) end end end diff --git a/spec/serializers/category_upload_serializer_spec.rb b/spec/serializers/category_upload_serializer_spec.rb index c46b2ad501c..eef9d1f9528 100644 --- a/spec/serializers/category_upload_serializer_spec.rb +++ b/spec/serializers/category_upload_serializer_spec.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true RSpec.describe CategoryUploadSerializer do + subject(:serializer) { described_class.new(upload, root: false) } + fab!(:upload) { Fabricate(:upload) } - let(:subject) { described_class.new(upload, root: false) } it "should include width and height" do - expect(subject.width).to eq(upload.width) - expect(subject.height).to eq(upload.height) + expect(serializer.width).to eq(upload.width) + expect(serializer.height).to eq(upload.height) end end diff --git a/spec/serializers/emoji_serializer_spec.rb b/spec/serializers/emoji_serializer_spec.rb index 732e78da1b1..8c9487f542a 100644 --- a/spec/serializers/emoji_serializer_spec.rb +++ b/spec/serializers/emoji_serializer_spec.rb @@ -4,16 +4,17 @@ RSpec.describe EmojiSerializer do fab!(:custom_emoji) { CustomEmoji.create!(name: "trout", upload: Fabricate(:upload)) } describe "#url" do + subject(:serializer) { described_class.new(emoji, root: false) } + fab!(:emoji) { Emoji.load_custom.first } - subject { described_class.new(emoji, root: false) } it "returns a valid URL" do - expect(subject.url).to start_with("/uploads/") + expect(serializer.url).to start_with("/uploads/") end it "works with a CDN" do set_cdn_url("https://cdn.com") - expect(subject.url).to start_with("https://cdn.com") + expect(serializer.url).to start_with("https://cdn.com") end end diff --git a/spec/serializers/group_show_serializer_spec.rb b/spec/serializers/group_show_serializer_spec.rb index b69d37ef5a4..2bd872d0aa5 100644 --- a/spec/serializers/group_show_serializer_spec.rb +++ b/spec/serializers/group_show_serializer_spec.rb @@ -59,15 +59,16 @@ RSpec.describe GroupShowSerializer do end describe "admin only fields" do + subject(:serializer) { described_class.new(group, scope: guardian, root: false) } + fab!(:group) { Fabricate(:group, email_username: "foo@bar.com", email_password: "pa$$w0rd") } - subject { described_class.new(group, scope: guardian, root: false) } context "for a user" do let(:guardian) { Guardian.new(Fabricate(:user)) } it "are not visible" do - expect(subject.as_json[:email_username]).to be_nil - expect(subject.as_json[:email_password]).to be_nil + expect(serializer.as_json[:email_username]).to be_nil + expect(serializer.as_json[:email_password]).to be_nil end end @@ -75,15 +76,16 @@ RSpec.describe GroupShowSerializer do let(:guardian) { Guardian.new(Fabricate(:admin)) } it "are visible" do - expect(subject.as_json[:email_username]).to eq("foo@bar.com") - expect(subject.as_json[:email_password]).to eq("pa$$w0rd") - expect(subject.as_json[:message_count]).to eq(0) + expect(serializer.as_json[:email_username]).to eq("foo@bar.com") + expect(serializer.as_json[:email_password]).to eq("pa$$w0rd") + expect(serializer.as_json[:message_count]).to eq(0) end end end describe "default notification settings" do - subject { described_class.new(group, scope: guardian, root: false) } + subject(:serializer) { described_class.new(group, scope: guardian, root: false) } + let(:category1) { Fabricate(:category) } let(:category2) { Fabricate(:category) } let(:tag1) { Fabricate(:tag) } @@ -118,8 +120,10 @@ RSpec.describe GroupShowSerializer do let(:guardian) { Guardian.new(Fabricate(:user)) } it "are not visible" do - expect(subject.as_json.keys.select { |k| k.to_s.ends_with?("_category_ids") }).to be_empty - expect(subject.as_json.keys.select { |k| k.to_s.ends_with?("_tags") }).to be_empty + expect( + serializer.as_json.keys.select { |k| k.to_s.ends_with?("_category_ids") }, + ).to be_empty + expect(serializer.as_json.keys.select { |k| k.to_s.ends_with?("_tags") }).to be_empty end end @@ -127,25 +131,25 @@ RSpec.describe GroupShowSerializer do let(:guardian) { Guardian.new(Fabricate(:admin)) } it "are correct" do - expect(subject.as_json[:watching_category_ids]).to eq([category1.id]) - expect(subject.as_json[:tracking_category_ids]).to eq([category2.id]) - expect(subject.as_json[:watching_first_post_category_ids]).to eq([]) - expect(subject.as_json[:regular_category_ids]).to eq([]) - expect(subject.as_json[:muted_category_ids]).to eq([]) + expect(serializer.as_json[:watching_category_ids]).to eq([category1.id]) + expect(serializer.as_json[:tracking_category_ids]).to eq([category2.id]) + expect(serializer.as_json[:watching_first_post_category_ids]).to eq([]) + expect(serializer.as_json[:regular_category_ids]).to eq([]) + expect(serializer.as_json[:muted_category_ids]).to eq([]) - expect(subject.as_json[:watching_tags]).to eq([tag1.name]) - expect(subject.as_json[:tracking_tags]).to eq([tag2.name]) - expect(subject.as_json[:watching_first_post_tags]).to eq([]) - expect(subject.as_json[:regular_tags]).to eq([]) - expect(subject.as_json[:muted_tags]).to eq([]) + expect(serializer.as_json[:watching_tags]).to eq([tag1.name]) + expect(serializer.as_json[:tracking_tags]).to eq([tag2.name]) + expect(serializer.as_json[:watching_first_post_tags]).to eq([]) + expect(serializer.as_json[:regular_tags]).to eq([]) + expect(serializer.as_json[:muted_tags]).to eq([]) end it "doesn't include tag fields if tags are disabled" do SiteSetting.tagging_enabled = false - expect(subject.as_json.keys.select { |k| k.to_s.ends_with?("_category_ids") }.length).to eq( - 5, - ) - expect(subject.as_json.keys.select { |k| k.to_s.ends_with?("_tags") }).to be_empty + expect( + serializer.as_json.keys.select { |k| k.to_s.ends_with?("_category_ids") }.length, + ).to eq(5) + expect(serializer.as_json.keys.select { |k| k.to_s.ends_with?("_tags") }).to be_empty end end end diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 39d7cbe6c75..0b728696c83 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -68,35 +68,35 @@ RSpec.describe PostSerializer do end context "with a post by a nuked user" do - before { post.update!(user_id: nil, deleted_at: Time.zone.now) } - - subject do + subject(:serializer) do PostSerializer.new(post, scope: Guardian.new(Fabricate(:admin)), root: false).as_json end + before { post.update!(user_id: nil, deleted_at: Time.zone.now) } + it "serializes correctly" do %i[name username display_username avatar_template user_title trust_level].each do |attr| - expect(subject[attr]).to be_nil + expect(serializer[attr]).to be_nil end - %i[moderator staff yours].each { |attr| expect(subject[attr]).to eq(false) } + %i[moderator staff yours].each { |attr| expect(serializer[attr]).to eq(false) } end end context "with a post by a suspended user" do - def subject + def serializer PostSerializer.new(post, scope: Guardian.new(Fabricate(:admin)), root: false).as_json end it "serializes correctly" do - expect(subject[:user_suspended]).to be_nil + expect(serializer[:user_suspended]).to be_nil post.user.update!(suspended_till: 1.month.from_now) - expect(subject[:user_suspended]).to eq(true) + expect(serializer[:user_suspended]).to eq(true) freeze_time (2.months.from_now) - expect(subject[:user_suspended]).to be_nil + expect(serializer[:user_suspended]).to be_nil end end diff --git a/spec/serializers/suggested_topic_serializer_spec.rb b/spec/serializers/suggested_topic_serializer_spec.rb index 4627f95c6b0..0d777dc189e 100644 --- a/spec/serializers/suggested_topic_serializer_spec.rb +++ b/spec/serializers/suggested_topic_serializer_spec.rb @@ -5,6 +5,10 @@ RSpec.describe SuggestedTopicSerializer do let(:admin) { Fabricate(:admin) } describe "#featured_link and #featured_link_root_domain" do + subject(:json) do + SuggestedTopicSerializer.new(topic, scope: Guardian.new(user), root: false).as_json + end + let(:featured_link) { "http://meta.discourse.org" } let(:topic) do Fabricate( @@ -13,9 +17,6 @@ RSpec.describe SuggestedTopicSerializer do category: Fabricate(:category, topic_featured_link_allowed: true), ) end - subject(:json) do - SuggestedTopicSerializer.new(topic, scope: Guardian.new(user), root: false).as_json - end context "when topic featured link is disable" do before do diff --git a/spec/serializers/upload_serializer_spec.rb b/spec/serializers/upload_serializer_spec.rb index b2734c38822..39c4b6ded49 100644 --- a/spec/serializers/upload_serializer_spec.rb +++ b/spec/serializers/upload_serializer_spec.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true RSpec.describe UploadSerializer do + subject(:serializer) { UploadSerializer.new(upload, root: false) } + fab!(:upload) { Fabricate(:upload) } - let(:subject) { UploadSerializer.new(upload, root: false) } it "should render without errors" do - json_data = JSON.parse(subject.to_json) + json_data = JSON.parse(serializer.to_json) expect(json_data["id"]).to eql upload.id expect(json_data["width"]).to eql upload.width @@ -21,7 +22,7 @@ RSpec.describe UploadSerializer do context "when secure uploads is disabled" do it "just returns the normal URL, otherwise S3 errors are encountered" do UrlHelper.expects(:cook_url).with(upload.url, secure: false) - subject.to_json + serializer.to_json end end @@ -33,7 +34,7 @@ RSpec.describe UploadSerializer do it "returns the cooked URL based on the upload URL" do UrlHelper.expects(:cook_url).with(upload.url, secure: true) - subject.to_json + serializer.to_json end end end diff --git a/spec/services/auto_silence_spec.rb b/spec/services/auto_silence_spec.rb index cfdac5eb0d8..669d4e5701b 100644 --- a/spec/services/auto_silence_spec.rb +++ b/spec/services/auto_silence_spec.rb @@ -9,12 +9,13 @@ RSpec.describe SpamRule::AutoSilence do end describe "perform" do + subject(:autosilence) { described_class.new(post.user) } + let(:user) { Fabricate.build(:newuser) } let(:post) { Fabricate(:post, user: user) } - subject { described_class.new(post.user) } it "takes no action if user should not be silenced" do - subject.perform + autosilence.perform expect(post.user.reload).not_to be_silenced end @@ -23,81 +24,84 @@ RSpec.describe SpamRule::AutoSilence do SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:low] SiteSetting.num_users_to_silence_new_user = 1 PostActionCreator.spam(Discourse.system_user, post) - subject.perform + autosilence.perform expect(post.user.reload).to be_silenced end end describe "total_spam_score" do + subject(:score) { enforcer.user_spam_stats.total_spam_score } + let(:post) { Fabricate(:post) } let(:enforcer) { described_class.new(post.user) } let(:flagger) { Fabricate(:user) } - subject { enforcer.user_spam_stats.total_spam_score } it "returns 0 when there are no flags" do - expect(subject).to eq(0) + expect(score).to eq(0) end it "returns 0 when there is one flag that has a reason other than spam" do PostActionCreator.off_topic(flagger, post) - expect(subject).to eq(0) + expect(score).to eq(0) end it "returns the score when there are two flags with spam as the reason" do PostActionCreator.spam(Fabricate(:user), post) PostActionCreator.spam(Fabricate(:user), post) - expect(subject).to eq(4.0) + expect(score).to eq(4.0) end it "returns the score when there are two spam flags, each on a different post" do PostActionCreator.spam(Fabricate(:user), post) PostActionCreator.spam(Fabricate(:user), Fabricate(:post, user: post.user)) - expect(subject).to eq(4.0) + expect(score).to eq(4.0) end end describe "spam_user_count" do + subject(:count) { enforcer.user_spam_stats.spam_user_count } + let(:post) { Fabricate(:post) } let(:enforcer) { described_class.new(post.user) } - subject { enforcer.user_spam_stats.spam_user_count } it "returns 0 when there are no flags" do - expect(subject).to eq(0) + expect(count).to eq(0) end it "returns 0 when there is one flag that has a reason other than spam" do Fabricate(:flag, post: post, post_action_type_id: PostActionType.types[:off_topic]) - expect(subject).to eq(0) + expect(count).to eq(0) end it "returns 1 when there is one spam flag" do PostActionCreator.spam(Fabricate(:user), post) - expect(subject).to eq(1) + expect(count).to eq(1) end it "returns 2 when there are two spam flags from 2 users" do PostActionCreator.spam(Fabricate(:user), post) PostActionCreator.spam(Fabricate(:user), post) - expect(subject).to eq(2) + expect(count).to eq(2) end it "returns 1 when there are two spam flags on two different posts from 1 user" do flagger = Fabricate(:user) PostActionCreator.spam(flagger, post) PostActionCreator.spam(flagger, Fabricate(:post, user: post.user)) - expect(subject).to eq(1) + expect(count).to eq(1) end end describe "#silence_user" do + subject(:autosilence) { described_class.new(user) } + let!(:admin) { Fabricate(:admin) } # needed for SystemMessage let(:user) { Fabricate(:user) } let!(:post) { Fabricate(:post, user: user) } - subject { described_class.new(user) } context "when user is not silenced" do it "prevents the user from making new posts" do - subject.silence_user + autosilence.silence_user expect(user).to be_silenced expect(Guardian.new(user).can_create_post?(nil)).to be_falsey end @@ -107,14 +111,14 @@ RSpec.describe SpamRule::AutoSilence do it "sends private message to moderators" do SiteSetting.notify_mods_when_user_silenced = true - subject.silence_user - expect(subject.group_message).to be_present + autosilence.silence_user + expect(autosilence.group_message).to be_present end it "doesn't send a pm to moderators if notify_mods_when_user_silenced is false" do SiteSetting.notify_mods_when_user_silenced = false - subject.silence_user - expect(subject.group_message).to be_blank + autosilence.silence_user + expect(autosilence.group_message).to be_blank end end end @@ -123,8 +127,8 @@ RSpec.describe SpamRule::AutoSilence do before { UserSilencer.silence(user) } it "doesn't send a pm to moderators if the user is already silenced" do - subject.silence_user - expect(subject.group_message).to be_blank + autosilence.silence_user + expect(autosilence.group_message).to be_blank end end end @@ -167,20 +171,21 @@ RSpec.describe SpamRule::AutoSilence do end context "with new user" do - subject { described_class.new(user) } - let(:stats) { subject.user_spam_stats } + subject(:autosilence) { described_class.new(user) } + + let(:stats) { autosilence.user_spam_stats } it "returns false if there are no spam flags" do expect(stats.total_spam_score).to eq(0) expect(stats.spam_user_count).to eq(0) - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end it "returns false if there are not received enough flags" do PostActionCreator.spam(flagger, post) expect(stats.total_spam_score).to eq(2.0) expect(stats.spam_user_count).to eq(1) - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end it "returns false if there have not been enough users" do @@ -188,21 +193,21 @@ RSpec.describe SpamRule::AutoSilence do PostActionCreator.spam(flagger, post2) expect(stats.total_spam_score).to eq(4.0) expect(stats.spam_user_count).to eq(1) - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end it "returns false if silence_new_user_sensitivity is disabled" do SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:disabled] PostActionCreator.spam(flagger, post) PostActionCreator.spam(flagger2, post) - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end it "returns false if num_users_to_silence_new_user is 0" do SiteSetting.num_users_to_silence_new_user = 0 PostActionCreator.spam(flagger, post) PostActionCreator.spam(flagger2, post) - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end it "returns true when there are enough flags from enough users" do @@ -210,16 +215,17 @@ RSpec.describe SpamRule::AutoSilence do PostActionCreator.spam(flagger2, post) expect(stats.total_spam_score).to eq(4.0) expect(stats.spam_user_count).to eq(2) - expect(subject.should_autosilence?).to eq(true) + expect(autosilence.should_autosilence?).to eq(true) end end context "when silenced, but has higher trust level now" do + subject(:autosilence) { described_class.new(user) } + let(:user) { Fabricate(:user, silenced_till: 1.year.from_now, trust_level: TrustLevel[1]) } - subject { described_class.new(user) } it "returns false" do - expect(subject.should_autosilence?).to eq(false) + expect(autosilence.should_autosilence?).to eq(false) end end end diff --git a/spec/services/email_settings_exception_handler_spec.rb b/spec/services/email_settings_exception_handler_spec.rb index e70614dd608..1baa084abbc 100644 --- a/spec/services/email_settings_exception_handler_spec.rb +++ b/spec/services/email_settings_exception_handler_spec.rb @@ -4,21 +4,21 @@ RSpec.describe EmailSettingsExceptionHandler do describe "#friendly_exception_message" do it "formats a Net::POPAuthenticationError" do exception = Net::POPAuthenticationError.new("invalid credentials") - expect(subject.class.friendly_exception_message(exception, "pop.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "pop.test.com")).to eq( I18n.t("email_settings.pop3_authentication_error"), ) end it "formats a Net::IMAP::NoResponseError for invalid credentials" do exception = Net::IMAP::NoResponseError.new(stub(data: stub(text: "Invalid credentials"))) - expect(subject.class.friendly_exception_message(exception, "imap.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "imap.test.com")).to eq( I18n.t("email_settings.imap_authentication_error"), ) end it "formats a general Net::IMAP::NoResponseError" do exception = Net::IMAP::NoResponseError.new(stub(data: stub(text: "NO bad problem (Failure)"))) - expect(subject.class.friendly_exception_message(exception, "imap.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "imap.test.com")).to eq( I18n.t("email_settings.imap_no_response_error", message: "NO bad problem"), ) end @@ -28,14 +28,14 @@ RSpec.describe EmailSettingsExceptionHandler do Net::IMAP::NoResponseError.new( stub(data: stub(text: "NO Application-specific password required")), ) - expect(subject.class.friendly_exception_message(exception, "imap.gmail.com")).to eq( + expect(described_class.friendly_exception_message(exception, "imap.gmail.com")).to eq( I18n.t("email_settings.authentication_error_gmail_app_password"), ) end it "formats a Net::SMTPAuthenticationError" do exception = Net::SMTPAuthenticationError.new("invalid credentials") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.smtp_authentication_error"), ) end @@ -43,58 +43,58 @@ RSpec.describe EmailSettingsExceptionHandler do it "formats a Net::SMTPAuthenticationError with application-specific password Gmail error" do exception = Net::SMTPAuthenticationError.new(nil, message: "Application-specific password required") - expect(subject.class.friendly_exception_message(exception, "smtp.gmail.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.gmail.com")).to eq( I18n.t("email_settings.authentication_error_gmail_app_password"), ) end it "formats a Net::SMTPServerBusy" do exception = Net::SMTPServerBusy.new("call me maybe later") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.smtp_server_busy_error"), ) end it "formats a Net::SMTPSyntaxError, Net::SMTPFatalError, and Net::SMTPUnknownError" do exception = Net::SMTPSyntaxError.new(nil, message: "bad syntax") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.smtp_unhandled_error", message: exception.message), ) exception = Net::SMTPFatalError.new(nil, message: "fatal") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.smtp_unhandled_error", message: exception.message), ) exception = Net::SMTPUnknownError.new(nil, message: "unknown") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.smtp_unhandled_error", message: exception.message), ) end it "formats a SocketError and Errno::ECONNREFUSED" do exception = SocketError.new("bad socket") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.connection_error"), ) exception = Errno::ECONNREFUSED.new("no thanks") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.connection_error"), ) end it "formats a Net::OpenTimeout and Net::ReadTimeout error" do exception = Net::OpenTimeout.new("timed out") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.timeout_error"), ) exception = Net::ReadTimeout.new("timed out") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.timeout_error"), ) end it "formats unhandled errors" do exception = StandardError.new("unknown") - expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq( + expect(described_class.friendly_exception_message(exception, "smtp.test.com")).to eq( I18n.t("email_settings.unhandled_error", message: exception.message), ) end diff --git a/spec/services/email_settings_validator_spec.rb b/spec/services/email_settings_validator_spec.rb index 9ba5fb7e6e0..78bc11fcec0 100644 --- a/spec/services/email_settings_validator_spec.rb +++ b/spec/services/email_settings_validator_spec.rb @@ -20,7 +20,12 @@ RSpec.describe EmailSettingsValidator do net_imap_stub.stubs(:logout).returns(true) net_imap_stub.stubs(:disconnect).returns(true) expect { - subject.class.validate_imap(host: host, port: port, username: username, password: password) + described_class.validate_imap( + host: host, + port: port, + username: username, + password: password, + ) }.not_to raise_error end @@ -30,7 +35,7 @@ RSpec.describe EmailSettingsValidator do stub(data: stub(text: "no response")), ) expect { - subject.class.validate_imap( + described_class.validate_imap( host: host, port: port, username: username, @@ -51,7 +56,7 @@ RSpec.describe EmailSettingsValidator do .with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)) .at_least_once expect { - subject.class.validate_imap( + described_class.validate_imap( host: host, port: port, username: username, @@ -77,14 +82,19 @@ RSpec.describe EmailSettingsValidator do it "is valid if no error is raised" do expect { - subject.class.validate_pop3(host: host, port: port, username: username, password: password) + described_class.validate_pop3( + host: host, + port: port, + username: username, + password: password, + ) }.not_to raise_error end it "is invalid if an error is raised" do net_pop3_stub.stubs(:auth_only).raises(Net::POPAuthenticationError, "invalid credentials") expect { - subject.class.validate_pop3( + described_class.validate_pop3( host: host, port: port, username: username, @@ -102,7 +112,7 @@ RSpec.describe EmailSettingsValidator do .at_least_once net_pop3_stub.stubs(:auth_only).raises(Net::POPAuthenticationError, "invalid credentials") expect { - subject.class.validate_pop3( + described_class.validate_pop3( host: host, port: port, username: username, @@ -117,7 +127,12 @@ RSpec.describe EmailSettingsValidator do SiteSetting.pop3_polling_openssl_verify = true net_pop3_stub.expects(:enable_ssl).with(max_version: OpenSSL::SSL::TLS1_2_VERSION) expect { - subject.class.validate_pop3(host: host, port: port, username: username, password: password) + described_class.validate_pop3( + host: host, + port: port, + username: username, + password: password, + ) }.not_to raise_error end @@ -126,7 +141,12 @@ RSpec.describe EmailSettingsValidator do SiteSetting.pop3_polling_openssl_verify = false net_pop3_stub.expects(:enable_ssl).with(OpenSSL::SSL::VERIFY_NONE) expect { - subject.class.validate_pop3(host: host, port: port, username: username, password: password) + described_class.validate_pop3( + host: host, + port: port, + username: username, + password: password, + ) }.not_to raise_error end end @@ -151,7 +171,7 @@ RSpec.describe EmailSettingsValidator do it "is valid if no error is raised" do expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -164,7 +184,7 @@ RSpec.describe EmailSettingsValidator do it "is invalid if an error is raised" do net_smtp_stub.stubs(:start).raises(Net::SMTPAuthenticationError, "invalid credentials") expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -185,7 +205,7 @@ RSpec.describe EmailSettingsValidator do stub(message: "invalid credentials"), ) expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -199,7 +219,7 @@ RSpec.describe EmailSettingsValidator do it "uses the correct ssl verify params for enable_tls if those settings are enabled" do net_smtp_stub.expects(:enable_tls) expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: 465, username: username, @@ -215,7 +235,7 @@ RSpec.describe EmailSettingsValidator do it "uses the correct ssl verify params for enable_starttls_auto if those settings are enabled" do net_smtp_stub.expects(:enable_starttls_auto) expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: 587, username: username, @@ -230,7 +250,7 @@ RSpec.describe EmailSettingsValidator do it "raises an ArgumentError if both enable_tls is true and enable_starttls_auto is true" do expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -244,7 +264,7 @@ RSpec.describe EmailSettingsValidator do it "raises an ArgumentError if a bad authentication method is used" do expect { - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -259,7 +279,7 @@ RSpec.describe EmailSettingsValidator do let(:domain) { nil } it "gets the domain from the host" do net_smtp_stub.expects(:start).with("gmail.com", username, password, :plain) - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, @@ -272,7 +292,7 @@ RSpec.describe EmailSettingsValidator do it "uses localhost when in development mode" do Rails.env.stubs(:development?).returns(true) net_smtp_stub.expects(:start).with("localhost", username, password, :plain) - subject.class.validate_smtp( + described_class.validate_smtp( host: host, port: port, username: username, diff --git a/spec/services/external_upload_manager_spec.rb b/spec/services/external_upload_manager_spec.rb index 6c4a71a6b91..4ef0304a6f9 100644 --- a/spec/services/external_upload_manager_spec.rb +++ b/spec/services/external_upload_manager_spec.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true RSpec.describe ExternalUploadManager do + subject(:manager) { ExternalUploadManager.new(external_upload_stub) } + fab!(:user) { Fabricate(:user) } + let!(:logo_file) { file_from_fixtures("logo.png") } let!(:pdf_file) { file_from_fixtures("large.pdf", "pdf") } let(:object_size) { 1.megabyte } @@ -13,8 +16,6 @@ RSpec.describe ExternalUploadManager do let!(:external_upload_stub) { Fabricate(:image_external_upload_stub, created_by: user) } let(:s3_bucket_name) { SiteSetting.s3_upload_bucket } - subject { ExternalUploadManager.new(external_upload_stub) } - before do SiteSetting.authorized_extensions += "|pdf" SiteSetting.max_attachment_size_kb = 210.megabytes / 1000 @@ -40,7 +41,7 @@ RSpec.describe ExternalUploadManager do describe "#can_promote?" do it "returns false if the external stub status is not created" do external_upload_stub.update!(status: ExternalUploadStub.statuses[:uploaded]) - expect(subject.can_promote?).to eq(false) + expect(manager.can_promote?).to eq(false) end end @@ -56,7 +57,7 @@ RSpec.describe ExternalUploadManager do before { FileHelper.stubs(:download).returns(nil) } it "raises an error" do - expect { subject.transform! }.to raise_error(ExternalUploadManager::DownloadFailedError) + expect { manager.transform! }.to raise_error(ExternalUploadManager::DownloadFailedError) end end @@ -64,13 +65,13 @@ RSpec.describe ExternalUploadManager do before { external_upload_stub.update!(status: ExternalUploadStub.statuses[:uploaded]) } it "raises an error" do - expect { subject.transform! }.to raise_error(ExternalUploadManager::CannotPromoteError) + expect { manager.transform! }.to raise_error(ExternalUploadManager::CannotPromoteError) end end context "when the upload does not get changed in UploadCreator (resized etc.)" do it "copies the stubbed upload on S3 to its new destination and deletes it" do - upload = subject.transform! + upload = manager.transform! bucket = @fake_s3.bucket(SiteSetting.s3_upload_bucket) expect(@fake_s3.operation_called?(:copy_object)).to eq(true) @@ -80,7 +81,7 @@ RSpec.describe ExternalUploadManager do it "errors if the image upload is too big" do SiteSetting.max_image_size_kb = 1 - upload = subject.transform! + upload = manager.transform! expect(upload.errors.full_messages).to include( "Filesize " + I18n.t( @@ -95,7 +96,7 @@ RSpec.describe ExternalUploadManager do it "errors if the extension is not supported" do SiteSetting.authorized_extensions = "" - upload = subject.transform! + upload = manager.transform! expect(upload.errors.full_messages).to include( "Original filename " + I18n.t("upload.unauthorized", authorized_extensions: ""), ) @@ -114,7 +115,7 @@ RSpec.describe ExternalUploadManager do end it "creates a new upload in s3 (not copy) and deletes the original stubbed upload" do - upload = subject.transform! + upload = manager.transform! bucket = @fake_s3.bucket(SiteSetting.s3_upload_bucket) expect(@fake_s3.operation_called?(:copy_object)).to eq(false) @@ -130,7 +131,7 @@ RSpec.describe ExternalUploadManager do let(:client_sha1) { "blahblah" } it "raises an error, deletes the stub" do - expect { subject.transform! }.to raise_error( + expect { manager.transform! }.to raise_error( ExternalUploadManager::ChecksumMismatchError, ) expect(ExternalUploadStub.exists?(id: external_upload_stub.id)).to eq(false) @@ -141,7 +142,7 @@ RSpec.describe ExternalUploadManager do it "does not delete the stub if enable_upload_debug_mode" do SiteSetting.enable_upload_debug_mode = true - expect { subject.transform! }.to raise_error( + expect { manager.transform! }.to raise_error( ExternalUploadManager::ChecksumMismatchError, ) external_stub = ExternalUploadStub.find(external_upload_stub.id) @@ -159,7 +160,7 @@ RSpec.describe ExternalUploadManager do after { Discourse.redis.flushdb } it "raises an error, deletes the file immediately, and prevents the user from uploading external files for a few minutes" do - expect { subject.transform! }.to raise_error(ExternalUploadManager::SizeMismatchError) + expect { manager.transform! }.to raise_error(ExternalUploadManager::SizeMismatchError) expect(ExternalUploadStub.exists?(id: external_upload_stub.id)).to eq(false) expect( Discourse.redis.get( @@ -173,7 +174,7 @@ RSpec.describe ExternalUploadManager do it "does not delete the stub if enable_upload_debug_mode" do SiteSetting.enable_upload_debug_mode = true - expect { subject.transform! }.to raise_error(ExternalUploadManager::SizeMismatchError) + expect { manager.transform! }.to raise_error(ExternalUploadManager::SizeMismatchError) external_stub = ExternalUploadStub.find(external_upload_stub.id) expect(external_stub.status).to eq(ExternalUploadStub.statuses[:failed]) @@ -199,23 +200,23 @@ RSpec.describe ExternalUploadManager do it "does not try and download the file" do FileHelper.expects(:download).never - subject.transform! + manager.transform! end it "generates a fake sha for the upload record" do - upload = subject.transform! + upload = manager.transform! expect(upload.sha1).not_to eq(sha1) expect(upload.original_sha1).to eq(nil) expect(upload.filesize).to eq(object_size) end it "marks the stub as uploaded" do - subject.transform! + manager.transform! expect(external_upload_stub.reload.status).to eq(ExternalUploadStub.statuses[:uploaded]) end it "copies the stubbed upload on S3 to its new destination and deletes it" do - upload = subject.transform! + upload = manager.transform! bucket = @fake_s3.bucket(SiteSetting.s3_upload_bucket) expect(bucket.find_object(Discourse.store.get_path_for_upload(upload))).to be_present @@ -240,28 +241,28 @@ RSpec.describe ExternalUploadManager do it "does not try and download the file" do FileHelper.expects(:download).never - subject.transform! + manager.transform! end it "raises an error when backups are disabled" do SiteSetting.enable_backups = false - expect { subject.transform! }.to raise_error(Discourse::InvalidAccess) + expect { manager.transform! }.to raise_error(Discourse::InvalidAccess) end it "raises an error when backups are local, not s3" do SiteSetting.backup_location = BackupLocationSiteSetting::LOCAL - expect { subject.transform! }.to raise_error(Discourse::InvalidAccess) + expect { manager.transform! }.to raise_error(Discourse::InvalidAccess) end it "does not create an upload record" do - expect { subject.transform! }.not_to change { Upload.count } + expect { manager.transform! }.not_to change { Upload.count } end it "copies the stubbed upload on S3 to its new destination and deletes it" do bucket = @fake_s3.bucket(SiteSetting.s3_backup_bucket) expect(bucket.find_object(external_upload_stub.key)).to be_present - subject.transform! + manager.transform! expect( bucket.find_object( diff --git a/spec/services/flag_sockpuppets_spec.rb b/spec/services/flag_sockpuppets_spec.rb index 8e921a72b4c..4f77d79b215 100644 --- a/spec/services/flag_sockpuppets_spec.rb +++ b/spec/services/flag_sockpuppets_spec.rb @@ -5,9 +5,10 @@ RSpec.describe SpamRule::FlagSockpuppets do fab!(:post1) { Fabricate(:post, user: user1, topic: Fabricate(:topic, user: user1)) } describe "#perform" do - let(:rule) { described_class.new(post1) } subject(:perform) { rule.perform } + let(:rule) { described_class.new(post1) } + it "does nothing if flag_sockpuppets is disabled" do SiteSetting.flag_sockpuppets = false rule.expects(:reply_is_from_sockpuppet?).never diff --git a/spec/services/group_action_logger_spec.rb b/spec/services/group_action_logger_spec.rb index 28eb7865759..6e7b8c07896 100644 --- a/spec/services/group_action_logger_spec.rb +++ b/spec/services/group_action_logger_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true RSpec.describe GroupActionLogger do + subject(:logger) { described_class.new(group_owner, group) } + fab!(:group_owner) { Fabricate(:user) } fab!(:group) { Fabricate(:group) } fab!(:user) { Fabricate(:user) } - subject { described_class.new(group_owner, group) } - before { group.add_owner(group_owner) } describe "#log_make_user_group_owner" do it "should create the right record" do - subject.log_make_user_group_owner(user) + logger.log_make_user_group_owner(user) group_history = GroupHistory.last @@ -23,7 +23,7 @@ RSpec.describe GroupActionLogger do describe "#log_remove_user_as_group_owner" do it "should create the right record" do - subject.log_remove_user_as_group_owner(user) + logger.log_remove_user_as_group_owner(user) group_history = GroupHistory.last @@ -36,7 +36,7 @@ RSpec.describe GroupActionLogger do describe "#log_add_user_to_group" do context "as a group owner" do it "should create the right record" do - subject.log_add_user_to_group(user) + logger.log_add_user_to_group(user) group_history = GroupHistory.last @@ -47,12 +47,12 @@ RSpec.describe GroupActionLogger do end context "as a normal user" do - subject { described_class.new(user, group) } + subject(:logger) { described_class.new(user, group) } before { group.update!(public_admission: true) } it "should create the right record" do - subject.log_add_user_to_group(user) + logger.log_add_user_to_group(user) group_history = GroupHistory.last @@ -66,7 +66,7 @@ RSpec.describe GroupActionLogger do describe "#log_remove_user_from_group" do context "as group owner" do it "should create the right record" do - subject.log_remove_user_from_group(user) + logger.log_remove_user_from_group(user) group_history = GroupHistory.last @@ -77,12 +77,12 @@ RSpec.describe GroupActionLogger do end context "as a normal user" do - subject { described_class.new(user, group) } + subject(:logger) { described_class.new(user, group) } before { group.update!(public_exit: true) } it "should create the right record" do - subject.log_remove_user_from_group(user) + logger.log_remove_user_from_group(user) group_history = GroupHistory.last @@ -97,7 +97,7 @@ RSpec.describe GroupActionLogger do it "should create the right record" do group.update!(public_admission: true, created_at: Time.zone.now) - expect { subject.log_change_group_settings }.to change { GroupHistory.count }.by(1) + expect { logger.log_change_group_settings }.to change { GroupHistory.count }.by(1) group_history = GroupHistory.last diff --git a/spec/services/group_message_spec.rb b/spec/services/group_message_spec.rb index 6ff2e5911d5..4cd007becfc 100644 --- a/spec/services/group_message_spec.rb +++ b/spec/services/group_message_spec.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true RSpec.describe GroupMessage do + subject(:send_group_message) do + GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) + end + let(:moderators_group) { Group[:moderators].name } let!(:admin) { Fabricate.build(:admin, id: 999) } @@ -8,10 +12,6 @@ RSpec.describe GroupMessage do before { Discourse.stubs(:system_user).returns(admin) } - subject(:send_group_message) do - GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) - end - describe "not sent recently" do before { GroupMessage.any_instance.stubs(:sent_recently?).returns(false) } @@ -42,14 +42,17 @@ RSpec.describe GroupMessage do end describe "sent recently" do + subject(:group_message) do + GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) + end + before { GroupMessage.any_instance.stubs(:sent_recently?).returns(true) } - subject { GroupMessage.create(moderators_group, :user_automatically_silenced, user: user) } it { is_expected.to eq(false) } it "should not send the same notification again" do PostCreator.expects(:create).never - subject + group_message end end @@ -57,29 +60,35 @@ RSpec.describe GroupMessage do let(:user) { Fabricate.build(:user, id: 123_123) } shared_examples "common message params for group messages" do it "returns the correct params" do - expect(subject[:username]).to eq(user.username) - expect(subject[:user_url]).to be_present + expect(message_params[:username]).to eq(user.username) + expect(message_params[:user_url]).to be_present end end context "with user_automatically_silenced" do - subject do + subject(:message_params) do GroupMessage.new(moderators_group, :user_automatically_silenced, user: user).message_params end + include_examples "common message params for group messages" end context "with spam_post_blocked" do - subject { GroupMessage.new(moderators_group, :spam_post_blocked, user: user).message_params } + subject(:message_params) do + GroupMessage.new(moderators_group, :spam_post_blocked, user: user).message_params + end + include_examples "common message params for group messages" end end describe "methods that use redis" do - let(:user) { Fabricate.build(:user, id: 123_123) } subject(:group_message) do GroupMessage.new(moderators_group, :user_automatically_silenced, user: user) end + + let(:user) { Fabricate.build(:user, id: 123_123) } + before do PostCreator.stubs(:create).returns(stub_everything) group_message.stubs(:sent_recently_key).returns("the_key") diff --git a/spec/services/hashtag_autocomplete_service_spec.rb b/spec/services/hashtag_autocomplete_service_spec.rb index fce479967df..4b8912a83bc 100644 --- a/spec/services/hashtag_autocomplete_service_spec.rb +++ b/spec/services/hashtag_autocomplete_service_spec.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true RSpec.describe HashtagAutocompleteService do + subject(:service) { described_class.new(guardian) } + fab!(:user) { Fabricate(:user) } fab!(:category1) { Fabricate(:category, name: "The Book Club", slug: "the-book-club") } fab!(:tag1) do Fabricate(:tag, name: "great-books", staff_topic_count: 22, public_topic_count: 22) end fab!(:topic1) { Fabricate(:topic) } - let(:guardian) { Guardian.new(user) } - subject { described_class.new(guardian) } + let(:guardian) { Guardian.new(user) } after { DiscoursePluginRegistry.reset! } @@ -42,24 +43,24 @@ RSpec.describe HashtagAutocompleteService do describe "#search" do it "returns search results for tags and categories by default" do - expect(subject.search("book", %w[category tag]).map(&:text)).to eq( + expect(service.search("book", %w[category tag]).map(&:text)).to eq( ["The Book Club", "great-books"], ) end it "respects the types_in_priority_order param" do - expect(subject.search("book", %w[tag category]).map(&:text)).to eq( + expect(service.search("book", %w[tag category]).map(&:text)).to eq( ["great-books", "The Book Club"], ) end it "respects the limit param" do - expect(subject.search("book", %w[tag category], limit: 1).map(&:text)).to eq(["great-books"]) + expect(service.search("book", %w[tag category], limit: 1).map(&:text)).to eq(["great-books"]) end it "does not allow more than SEARCH_MAX_LIMIT results to be specified by the limit param" do stub_const(HashtagAutocompleteService, "SEARCH_MAX_LIMIT", 1) do - expect(subject.search("book", %w[category tag], limit: 1000).map(&:text)).to eq( + expect(service.search("book", %w[category tag], limit: 1000).map(&:text)).to eq( ["The Book Club"], ) end @@ -68,35 +69,35 @@ RSpec.describe HashtagAutocompleteService do it "does not search other data sources if the limit is reached by earlier type data sources" do # only expected once to try get the exact matches first DiscourseTagging.expects(:filter_allowed_tags).never - subject.search("the-book", %w[category tag], limit: 1) + service.search("the-book", %w[category tag], limit: 1) end it "includes the tag count" do tag1.update!(staff_topic_count: 78, public_topic_count: 78) - expect(subject.search("book", %w[tag category]).map(&:text)).to eq( + expect(service.search("book", %w[tag category]).map(&:text)).to eq( ["great-books", "The Book Club"], ) end it "does case-insensitive search" do - expect(subject.search("bOOk", %w[category tag]).map(&:text)).to eq( + expect(service.search("bOOk", %w[category tag]).map(&:text)).to eq( ["The Book Club", "great-books"], ) end it "can search categories by name or slug" do - expect(subject.search("the-book-club", %w[category]).map(&:text)).to eq(["The Book Club"]) - expect(subject.search("Book C", %w[category]).map(&:text)).to eq(["The Book Club"]) + expect(service.search("the-book-club", %w[category]).map(&:text)).to eq(["The Book Club"]) + expect(service.search("Book C", %w[category]).map(&:text)).to eq(["The Book Club"]) end it "does not include categories the user cannot access" do category1.update!(read_restricted: true) - expect(subject.search("book", %w[tag category]).map(&:text)).to eq(["great-books"]) + expect(service.search("book", %w[tag category]).map(&:text)).to eq(["great-books"]) end it "does not include tags the user cannot access" do Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: ["great-books"]) - expect(subject.search("book", %w[tag]).map(&:text)).to be_empty + expect(service.search("book", %w[tag]).map(&:text)).to be_empty end it "includes other data sources" do @@ -109,7 +110,7 @@ RSpec.describe HashtagAutocompleteService do stub(enabled?: true), ) - expect(subject.search("book", %w[category tag bookmark]).map(&:text)).to eq( + expect(service.search("book", %w[category tag bookmark]).map(&:text)).to eq( ["The Book Club", "great-books", "read review of this fantasy book"], ) end @@ -117,7 +118,7 @@ RSpec.describe HashtagAutocompleteService do it "handles refs for categories that have a parent" do parent = Fabricate(:category, name: "Hobbies", slug: "hobbies") category1.update!(parent_category: parent) - expect(subject.search("book", %w[category tag]).map(&:ref)).to eq( + expect(service.search("book", %w[category tag]).map(&:ref)).to eq( %w[hobbies:the-book-club great-books], ) category1.update!(parent_category: nil) @@ -125,7 +126,7 @@ RSpec.describe HashtagAutocompleteService do it "appends type suffixes for the ref on conflicting slugs on items that are not the top priority type" do Fabricate(:tag, name: "the-book-club") - expect(subject.search("book", %w[category tag]).map(&:ref)).to eq( + expect(service.search("book", %w[category tag]).map(&:ref)).to eq( %w[the-book-club great-books the-book-club::tag], ) @@ -137,7 +138,7 @@ RSpec.describe HashtagAutocompleteService do stub(enabled?: true), ) - expect(subject.search("book", %w[category tag bookmark]).map(&:ref)).to eq( + expect(service.search("book", %w[category tag bookmark]).map(&:ref)).to eq( %w[book-club the-book-club great-books the-book-club::tag], ) end @@ -157,7 +158,7 @@ RSpec.describe HashtagAutocompleteService do stub(enabled?: true), ) - expect(subject.search("book", %w[bookmark category tag]).map(&:ref)).to eq( + expect(service.search("book", %w[bookmark category tag]).map(&:ref)).to eq( %w[book-club hobbies:the-book-club great-books the-book-club::tag], ) end @@ -175,7 +176,7 @@ RSpec.describe HashtagAutocompleteService do stub(enabled?: true), ) - expect(subject.search("book", %w[bookmark category tag]).map(&:ref)).to eq( + expect(service.search("book", %w[bookmark category tag]).map(&:ref)).to eq( %w[the-book-club hobbies:the-book-club::category great-books the-book-club::tag], ) end @@ -194,7 +195,7 @@ RSpec.describe HashtagAutocompleteService do Fabricate(:tag, name: "bookmania", staff_topic_count: 15, public_topic_count: 15) Fabricate(:tag, name: "awful-books", staff_topic_count: 56, public_topic_count: 56) - expect(subject.search("book", %w[category tag]).map(&:ref)).to eq( + expect(service.search("book", %w[category tag]).map(&:ref)).to eq( [ "book-reviews:book", # category exact match on slug, name sorted "book-library:book", @@ -208,7 +209,7 @@ RSpec.describe HashtagAutocompleteService do "great-books", ], ) - expect(subject.search("book", %w[category tag]).map(&:text)).to eq( + expect(service.search("book", %w[category tag]).map(&:text)).to eq( [ "Good Books", "Horror", @@ -233,13 +234,13 @@ RSpec.describe HashtagAutocompleteService do fab!(:tag4) { Fabricate(:tag, name: "book") } it "orders them by name within their type order" do - expect(subject.search("book", %w[category tag], limit: 10).map(&:ref)).to eq( + expect(service.search("book", %w[category tag], limit: 10).map(&:ref)).to eq( %w[book book::tag book-dome book-zone the-book-club great-books mid-books terrible-books], ) end it "prioritises exact matches to the top of the list" do - expect(subject.search("book", %w[category tag], limit: 10).map(&:ref)).to eq( + expect(service.search("book", %w[category tag], limit: 10).map(&:ref)).to eq( %w[book book::tag book-dome book-zone the-book-club great-books mid-books terrible-books], ) end @@ -249,7 +250,7 @@ RSpec.describe HashtagAutocompleteService do before { SiteSetting.tagging_enabled = false } it "does not return any tags" do - expect(subject.search("book", %w[category tag]).map(&:text)).to eq(["The Book Club"]) + expect(service.search("book", %w[category tag]).map(&:text)).to eq(["The Book Club"]) end end @@ -274,7 +275,7 @@ RSpec.describe HashtagAutocompleteService do category1.update!(read_restricted: true) Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: ["terrible-books"]) - expect(subject.search(nil, %w[category tag]).map(&:text)).to eq( + expect(service.search(nil, %w[category tag]).map(&:text)).to eq( [ "Book Dome", "Book Zone", @@ -294,7 +295,7 @@ RSpec.describe HashtagAutocompleteService do fab!(:tag2) { Fabricate(:tag, name: "fiction-books") } it "returns categories and tags in a hash format with the slug and url" do - result = subject.lookup_old(%w[the-book-club great-books fiction-books]) + result = service.lookup_old(%w[the-book-club great-books fiction-books]) expect(result[:categories]).to eq({ "the-book-club" => "/c/the-book-club/#{category1.id}" }) expect(result[:tags]).to eq( { @@ -306,18 +307,18 @@ RSpec.describe HashtagAutocompleteService do it "does not include categories the user cannot access" do category1.update!(read_restricted: true) - result = subject.lookup_old(%w[the-book-club great-books fiction-books]) + result = service.lookup_old(%w[the-book-club great-books fiction-books]) expect(result[:categories]).to eq({}) end it "does not include tags the user cannot access" do Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: ["great-books"]) - result = subject.lookup_old(%w[the-book-club great-books fiction-books]) + result = service.lookup_old(%w[the-book-club great-books fiction-books]) expect(result[:tags]).to eq({ "fiction-books" => "http://test.localhost/tag/fiction-books" }) end it "handles tags which have the ::tag suffix" do - result = subject.lookup_old(%w[the-book-club great-books::tag fiction-books]) + result = service.lookup_old(%w[the-book-club great-books::tag fiction-books]) expect(result[:tags]).to eq( { "fiction-books" => "http://test.localhost/tag/fiction-books", @@ -330,7 +331,7 @@ RSpec.describe HashtagAutocompleteService do before { SiteSetting.tagging_enabled = false } it "does not return tags" do - result = subject.lookup_old(%w[the-book-club great-books fiction-books]) + result = service.lookup_old(%w[the-book-club great-books fiction-books]) expect(result[:categories]).to eq({ "the-book-club" => "/c/the-book-club/#{category1.id}" }) expect(result[:tags]).to eq({}) end @@ -341,7 +342,7 @@ RSpec.describe HashtagAutocompleteService do fab!(:tag2) { Fabricate(:tag, name: "fiction-books") } it "returns category and tag in a hash format with the slug and url" do - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:relative_url)).to eq(["/c/the-book-club/#{category1.id}"]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books great-books]) @@ -350,20 +351,20 @@ RSpec.describe HashtagAutocompleteService do it "does not include category the user cannot access" do category1.update!(read_restricted: true) - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category]).to eq([]) end it "does not include tag the user cannot access" do Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: ["great-books"]) - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books]) expect(result[:tag].map(&:relative_url)).to eq(["/tag/fiction-books"]) end it "handles type suffixes for slugs" do result = - subject.lookup(%w[the-book-club::category great-books::tag fiction-books], %w[category tag]) + service.lookup(%w[the-book-club::category great-books::tag fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:relative_url)).to eq(["/c/the-book-club/#{category1.id}"]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books great-books]) @@ -373,7 +374,7 @@ RSpec.describe HashtagAutocompleteService do it "handles parent:child category lookups" do parent_category = Fabricate(:category, name: "Media", slug: "media") category1.update!(parent_category: parent_category) - result = subject.lookup(%w[media:the-book-club], %w[category tag]) + result = service.lookup(%w[media:the-book-club], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:ref)).to eq(["media:the-book-club"]) expect(result[:category].map(&:relative_url)).to eq( @@ -385,7 +386,7 @@ RSpec.describe HashtagAutocompleteService do it "handles parent:child category lookups with type suffix" do parent_category = Fabricate(:category, name: "Media", slug: "media") category1.update!(parent_category: parent_category) - result = subject.lookup(%w[media:the-book-club::category], %w[category tag]) + result = service.lookup(%w[media:the-book-club::category], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:ref)).to eq(["media:the-book-club::category"]) expect(result[:category].map(&:relative_url)).to eq( @@ -397,19 +398,19 @@ RSpec.describe HashtagAutocompleteService do it "does not return the category if the parent does not match the child" do parent_category = Fabricate(:category, name: "Media", slug: "media") category1.update!(parent_category: parent_category) - result = subject.lookup(%w[bad-parent:the-book-club], %w[category tag]) + result = service.lookup(%w[bad-parent:the-book-club], %w[category tag]) expect(result[:category]).to be_empty end it "for slugs without a type suffix it falls back in type order until a result is found or types are exhausted" do - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:relative_url)).to eq(["/c/the-book-club/#{category1.id}"]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books great-books]) expect(result[:tag].map(&:relative_url)).to eq(%w[/tag/fiction-books /tag/great-books]) category2 = Fabricate(:category, name: "Great Books", slug: "great-books") - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(%w[great-books the-book-club]) expect(result[:category].map(&:relative_url)).to eq( ["/c/great-books/#{category2.id}", "/c/the-book-club/#{category1.id}"], @@ -419,13 +420,13 @@ RSpec.describe HashtagAutocompleteService do category1.destroy! Fabricate(:tag, name: "the-book-club") - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["great-books"]) expect(result[:category].map(&:relative_url)).to eq(["/c/great-books/#{category2.id}"]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books the-book-club]) expect(result[:tag].map(&:relative_url)).to eq(%w[/tag/fiction-books /tag/the-book-club]) - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[tag category]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[tag category]) expect(result[:category]).to eq([]) expect(result[:tag].map(&:slug)).to eq(%w[fiction-books great-books the-book-club]) expect(result[:tag].map(&:relative_url)).to eq( @@ -443,14 +444,14 @@ RSpec.describe HashtagAutocompleteService do stub(enabled?: true), ) - result = subject.lookup(["coolrock"], %w[category tag bookmark]) + result = service.lookup(["coolrock"], %w[category tag bookmark]) expect(result[:bookmark].map(&:slug)).to eq(["coolrock"]) end it "handles type suffix lookups where there is another type with a conflicting slug that the user cannot access" do category1.update!(read_restricted: true) Fabricate(:tag, name: "the-book-club") - result = subject.lookup(%w[the-book-club::tag the-book-club], %w[category tag]) + result = service.lookup(%w[the-book-club::tag the-book-club], %w[category tag]) expect(result[:category].map(&:ref)).to eq([]) expect(result[:tag].map(&:ref)).to eq(["the-book-club::tag"]) end @@ -459,7 +460,7 @@ RSpec.describe HashtagAutocompleteService do before { SiteSetting.tagging_enabled = false } it "does not return tag" do - result = subject.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) + result = service.lookup(%w[the-book-club great-books fiction-books], %w[category tag]) expect(result[:category].map(&:slug)).to eq(["the-book-club"]) expect(result[:category].map(&:relative_url)).to eq(["/c/the-book-club/#{category1.id}"]) expect(result[:tag]).to eq([]) diff --git a/spec/services/notifications/consolidation_planner_spec.rb b/spec/services/notifications/consolidation_planner_spec.rb index 707d719e4a0..5e9526b4472 100644 --- a/spec/services/notifications/consolidation_planner_spec.rb +++ b/spec/services/notifications/consolidation_planner_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true RSpec.describe Notifications::ConsolidationPlanner do + subject(:planner) { described_class.new } + describe "#consolidate_or_save!" do let(:threshold) { 1 } fab!(:user) { Fabricate(:user) } @@ -11,7 +13,7 @@ RSpec.describe Notifications::ConsolidationPlanner do it "does nothing it haven't passed the consolidation threshold yet" do notification = build_notification(:liked, { display_username: like_user }) - saved_like = subject.consolidate_or_save!(notification) + saved_like = planner.consolidate_or_save!(notification) expect(saved_like.id).to be_present expect(saved_like.notification_type).to eq(Notification.types[:liked]) @@ -27,7 +29,7 @@ RSpec.describe Notifications::ConsolidationPlanner do ) notification = build_notification(:liked, { display_username: like_user }) - consolidated_like = subject.consolidate_or_save!(notification) + consolidated_like = planner.consolidate_or_save!(notification) expect(consolidated_like.id).not_to eq(first_notification.id) expect(consolidated_like.notification_type).to eq(Notification.types[:liked_consolidated]) @@ -45,7 +47,7 @@ RSpec.describe Notifications::ConsolidationPlanner do ) notification = build_notification(:liked, { display_username: like_user }) - updated = subject.consolidate_or_save!(notification) + updated = planner.consolidate_or_save!(notification) expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound) data = JSON.parse(updated.data) @@ -63,6 +65,6 @@ RSpec.describe Notifications::ConsolidationPlanner do end def plan_for(notification) - subject.plan_for(notification) + planner.plan_for(notification) end end diff --git a/spec/services/post_bookmarkable_spec.rb b/spec/services/post_bookmarkable_spec.rb index 94fed97f9af..dbd1d8855ca 100644 --- a/spec/services/post_bookmarkable_spec.rb +++ b/spec/services/post_bookmarkable_spec.rb @@ -3,10 +3,13 @@ require "rails_helper" RSpec.describe PostBookmarkable do + subject(:registered_bookmarkable) { RegisteredBookmarkable.new(PostBookmarkable) } + fab!(:user) { Fabricate(:user) } - let(:guardian) { Guardian.new(user) } fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) } + let(:guardian) { Guardian.new(user) } + let!(:post1) { Fabricate(:post) } let!(:post2) { Fabricate(:post) } let!(:bookmark1) do @@ -17,23 +20,25 @@ RSpec.describe PostBookmarkable do let!(:topic_user1) { Fabricate(:topic_user, user: user, topic: post1.topic) } let!(:topic_user2) { Fabricate(:topic_user, user: user, topic: post2.topic) } - subject { RegisteredBookmarkable.new(PostBookmarkable) } - describe "#perform_list_query" do it "returns all the user's bookmarks" do - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array( + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( [bookmark1.id, bookmark2.id], ) end it "does not return bookmarks for posts where the user does not have access to the topic category" do bookmark1.bookmarkable.topic.update(category: private_category) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array([bookmark2.id]) + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( + [bookmark2.id], + ) end it "does not return bookmarks for posts where the user does not have access to the private message" do bookmark1.bookmarkable.update(topic: Fabricate(:private_message_topic)) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array([bookmark2.id]) + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( + [bookmark2.id], + ) end end @@ -43,8 +48,8 @@ RSpec.describe PostBookmarkable do it "returns bookmarks that match by name" do ts_query = Search.ts_query(term: "gotta", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%gotta%", ts_query, ).map(&:id), @@ -57,8 +62,8 @@ RSpec.describe PostBookmarkable do ts_query = Search.ts_query(term: "post content", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%post content%", ts_query, ).map(&:id), @@ -66,8 +71,8 @@ RSpec.describe PostBookmarkable do ts_query = Search.ts_query(term: "great topic", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%great topic%", ts_query, ).map(&:id), @@ -75,8 +80,8 @@ RSpec.describe PostBookmarkable do ts_query = Search.ts_query(term: "blah", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%blah%", ts_query, ).map(&:id), @@ -86,23 +91,23 @@ RSpec.describe PostBookmarkable do describe "#can_send_reminder?" do it "cannot send reminder if the post or topic is deleted" do - expect(subject.can_send_reminder?(bookmark1)).to eq(true) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(true) bookmark1.bookmarkable.trash! bookmark1.reload - expect(subject.can_send_reminder?(bookmark1)).to eq(false) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false) Post.with_deleted.find_by(id: bookmark1.bookmarkable_id).recover! bookmark1.reload bookmark1.bookmarkable.topic.trash! bookmark1.reload - expect(subject.can_send_reminder?(bookmark1)).to eq(false) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false) end end describe "#reminder_handler" do it "creates a notification for the user with the correct details" do - expect { subject.send_reminder_notification(bookmark1) }.to change { Notification.count }.by( - 1, - ) + expect { registered_bookmarkable.send_reminder_notification(bookmark1) }.to change { + Notification.count + }.by(1) notif = user.notifications.last expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder]) expect(notif.topic_id).to eq(bookmark1.bookmarkable.topic_id) @@ -121,11 +126,11 @@ RSpec.describe PostBookmarkable do describe "#can_see?" do it "returns false if the post is in a private category or private message the user cannot see" do - expect(subject.can_see?(guardian, bookmark1)).to eq(true) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(true) bookmark1.bookmarkable.topic.update(category: private_category) - expect(subject.can_see?(guardian, bookmark1)).to eq(false) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false) bookmark1.bookmarkable.update(topic: Fabricate(:private_message_topic)) - expect(subject.can_see?(guardian, bookmark1)).to eq(false) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false) end end end diff --git a/spec/services/post_owner_changer_spec.rb b/spec/services/post_owner_changer_spec.rb index 70eb1bb3808..ecf44e8c41e 100644 --- a/spec/services/post_owner_changer_spec.rb +++ b/spec/services/post_owner_changer_spec.rb @@ -171,6 +171,15 @@ RSpec.describe PostOwnerChanger do end context "with integration tests" do + subject(:change_owners) do + PostOwnerChanger.new( + post_ids: [p1.id, p2.id], + topic_id: topic.id, + new_owner: user_a, + acting_user: editor, + ).change_owner! + end + let(:p1user) { p1.user } let(:p2user) { p2.user } @@ -209,15 +218,6 @@ RSpec.describe PostOwnerChanger do UserActionManager.enable end - subject(:change_owners) do - PostOwnerChanger.new( - post_ids: [p1.id, p2.id], - topic_id: topic.id, - new_owner: user_a, - acting_user: editor, - ).change_owner! - end - it "updates users' topic and post counts" do PostActionCreator.like(p2user, p1) expect(p1user.user_stat.reload.likes_received).to eq(1) diff --git a/spec/services/staff_action_logger_spec.rb b/spec/services/staff_action_logger_spec.rb index 4241857bf64..b1a9cfa660e 100644 --- a/spec/services/staff_action_logger_spec.rb +++ b/spec/services/staff_action_logger_spec.rb @@ -15,10 +15,10 @@ RSpec.describe StaffActionLogger do end describe "log_user_deletion" do - fab!(:deleted_user) { Fabricate(:user) } - subject(:log_user_deletion) { described_class.new(admin).log_user_deletion(deleted_user) } + fab!(:deleted_user) { Fabricate(:user) } + it "raises an error when user is nil" do expect { logger.log_user_deletion(nil) }.to raise_error(Discourse::InvalidParameters) end @@ -47,10 +47,10 @@ RSpec.describe StaffActionLogger do end describe "log_post_deletion" do - fab!(:deleted_post) { Fabricate(:post) } - subject(:log_post_deletion) { described_class.new(admin).log_post_deletion(deleted_post) } + fab!(:deleted_post) { Fabricate(:post) } + it "raises an error when post is nil" do expect { logger.log_post_deletion(nil) }.to raise_error(Discourse::InvalidParameters) end @@ -116,14 +116,15 @@ RSpec.describe StaffActionLogger do end describe "log_trust_level_change" do - fab!(:user) { Fabricate(:user) } - let(:old_trust_level) { TrustLevel[0] } - let(:new_trust_level) { TrustLevel[1] } - subject(:log_trust_level_change) do described_class.new(admin).log_trust_level_change(user, old_trust_level, new_trust_level) end + fab!(:user) { Fabricate(:user) } + + let(:old_trust_level) { TrustLevel[0] } + let(:new_trust_level) { TrustLevel[1] } + it "raises an error when user or trust level is nil" do expect { logger.log_trust_level_change(nil, old_trust_level, new_trust_level) @@ -371,11 +372,11 @@ RSpec.describe StaffActionLogger do end describe "log_roll_up" do + subject(:log_roll_up) { described_class.new(admin).log_roll_up(subnet, ips) } + let(:subnet) { "1.2.3.0/24" } let(:ips) { %w[1.2.3.4 1.2.3.100] } - subject(:log_roll_up) { described_class.new(admin).log_roll_up(subnet, ips) } - it "creates a new UserHistory record" do log_record = logger.log_roll_up(subnet, ips) expect(log_record).to be_valid @@ -584,12 +585,12 @@ RSpec.describe StaffActionLogger do end describe "log_check_personal_message" do - fab!(:personal_message) { Fabricate(:private_message_topic) } - subject(:log_check_personal_message) do described_class.new(admin).log_check_personal_message(personal_message) end + fab!(:personal_message) { Fabricate(:private_message_topic) } + it "raises an error when topic is nil" do expect { logger.log_check_personal_message(nil) }.to raise_error(Discourse::InvalidParameters) end @@ -604,10 +605,10 @@ RSpec.describe StaffActionLogger do end describe "log_post_approved" do - fab!(:approved_post) { Fabricate(:post) } - subject(:log_post_approved) { described_class.new(admin).log_post_approved(approved_post) } + fab!(:approved_post) { Fabricate(:post) } + it "raises an error when post is nil" do expect { logger.log_post_approved(nil) }.to raise_error(Discourse::InvalidParameters) end @@ -622,12 +623,12 @@ RSpec.describe StaffActionLogger do end describe "log_post_rejected" do - fab!(:reviewable) { Fabricate(:reviewable_queued_post) } - subject(:log_post_rejected) do described_class.new(admin).log_post_rejected(reviewable, DateTime.now) end + fab!(:reviewable) { Fabricate(:reviewable_queued_post) } + it "raises an error when reviewable not supplied" do expect { logger.log_post_rejected(nil, DateTime.now) }.to raise_error( Discourse::InvalidParameters, diff --git a/spec/services/topic_bookmarkable_spec.rb b/spec/services/topic_bookmarkable_spec.rb index ac2ad2454b4..b5aa7685974 100644 --- a/spec/services/topic_bookmarkable_spec.rb +++ b/spec/services/topic_bookmarkable_spec.rb @@ -3,10 +3,13 @@ require "rails_helper" RSpec.describe TopicBookmarkable do + subject(:registered_bookmarkable) { RegisteredBookmarkable.new(TopicBookmarkable) } + fab!(:user) { Fabricate(:user) } - let(:guardian) { Guardian.new(user) } fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) } + let(:guardian) { Guardian.new(user) } + let!(:topic1) { Fabricate(:topic) } let!(:topic2) { Fabricate(:topic) } let!(:post) { Fabricate(:post, topic: topic1) } @@ -18,23 +21,25 @@ RSpec.describe TopicBookmarkable do let!(:topic_user1) { Fabricate(:topic_user, user: user, topic: topic1) } let!(:topic_user2) { Fabricate(:topic_user, user: user, topic: topic2) } - subject { RegisteredBookmarkable.new(TopicBookmarkable) } - describe "#perform_list_query" do it "returns all the user's bookmarks" do - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array( + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( [bookmark1.id, bookmark2.id], ) end it "does not return bookmarks for posts where the user does not have access to the topic category" do bookmark1.bookmarkable.update!(category: private_category) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array([bookmark2.id]) + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( + [bookmark2.id], + ) end it "does not return bookmarks for posts where the user does not have access to the private message" do bookmark1.update!(bookmarkable: Fabricate(:private_message_topic)) - expect(subject.perform_list_query(user, guardian).map(&:id)).to match_array([bookmark2.id]) + expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array( + [bookmark2.id], + ) end end @@ -44,8 +49,8 @@ RSpec.describe TopicBookmarkable do it "returns bookmarks that match by name" do ts_query = Search.ts_query(term: "gotta", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%gotta%", ts_query, ).map(&:id), @@ -58,8 +63,8 @@ RSpec.describe TopicBookmarkable do ts_query = Search.ts_query(term: "post content", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%post content%", ts_query, ).map(&:id), @@ -67,8 +72,8 @@ RSpec.describe TopicBookmarkable do ts_query = Search.ts_query(term: "great topic", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%great topic%", ts_query, ).map(&:id), @@ -76,8 +81,8 @@ RSpec.describe TopicBookmarkable do ts_query = Search.ts_query(term: "blah", ts_config: "simple") expect( - subject.perform_search_query( - subject.perform_list_query(user, guardian), + registered_bookmarkable.perform_search_query( + registered_bookmarkable.perform_list_query(user, guardian), "%blah%", ts_query, ).map(&:id), @@ -87,18 +92,18 @@ RSpec.describe TopicBookmarkable do describe "#can_send_reminder?" do it "cannot send reminder if the topic is deleted" do - expect(subject.can_send_reminder?(bookmark1)).to eq(true) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(true) bookmark1.bookmarkable.trash! bookmark1.reload - expect(subject.can_send_reminder?(bookmark1)).to eq(false) + expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false) end end describe "#reminder_handler" do it "creates a notification for the user with the correct details" do - expect { subject.send_reminder_notification(bookmark1) }.to change { Notification.count }.by( - 1, - ) + expect { registered_bookmarkable.send_reminder_notification(bookmark1) }.to change { + Notification.count + }.by(1) notif = user.notifications.last expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder]) expect(notif.topic_id).to eq(bookmark1.bookmarkable_id) @@ -117,11 +122,11 @@ RSpec.describe TopicBookmarkable do describe "#can_see?" do it "returns false if the post is in a private category or private message the user cannot see" do - expect(subject.can_see?(guardian, bookmark1)).to eq(true) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(true) bookmark1.bookmarkable.update!(category: private_category) - expect(subject.can_see?(guardian, bookmark1)).to eq(false) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false) bookmark1.update!(bookmarkable: Fabricate(:private_message_topic)) - expect(subject.can_see?(guardian, bookmark1)).to eq(false) + expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false) end end end diff --git a/spec/services/user_anonymizer_spec.rb b/spec/services/user_anonymizer_spec.rb index e79845ee628..d82e2e2c77e 100644 --- a/spec/services/user_anonymizer_spec.rb +++ b/spec/services/user_anonymizer_spec.rb @@ -4,11 +4,12 @@ RSpec.describe UserAnonymizer do let(:admin) { Fabricate(:admin) } describe "event" do - let(:user) { Fabricate(:user, username: "edward") } subject(:make_anonymous) do described_class.make_anonymous(user, admin, anonymize_ip: "2.2.2.2") end + let(:user) { Fabricate(:user, username: "edward") } + it "triggers the event" do events = DiscourseEvent.track_events { make_anonymous } @@ -22,10 +23,11 @@ RSpec.describe UserAnonymizer do end describe ".make_anonymous" do + subject(:make_anonymous) { described_class.make_anonymous(user, admin) } + let(:original_email) { "edward@example.net" } let(:user) { Fabricate(:user, username: "edward", email: original_email) } fab!(:another_user) { Fabricate(:evil_trout) } - subject(:make_anonymous) { described_class.make_anonymous(user, admin) } it "changes username" do make_anonymous diff --git a/spec/services/user_destroyer_spec.rb b/spec/services/user_destroyer_spec.rb index 48210ff932b..46df20a9a75 100644 --- a/spec/services/user_destroyer_spec.rb +++ b/spec/services/user_destroyer_spec.rb @@ -75,9 +75,10 @@ RSpec.describe UserDestroyer do end context "when user deletes self" do - let(:destroy_opts) { { delete_posts: true, context: "/u/username/preferences/account" } } subject(:destroy) { UserDestroyer.new(user).destroy(user, destroy_opts) } + let(:destroy_opts) { { delete_posts: true, context: "/u/username/preferences/account" } } + include_examples "successfully destroy a user" it "should log proper context" do @@ -147,6 +148,7 @@ RSpec.describe UserDestroyer do context "when delete_posts is false" do subject(:destroy) { UserDestroyer.new(admin).destroy(user) } + before do user.stubs(:post_count).returns(1) user.stubs(:first_post_created_at).returns(Time.zone.now) @@ -253,18 +255,21 @@ RSpec.describe UserDestroyer do end context "when user has no posts, but user_stats table has post_count > 0" do + subject(:destroy) { UserDestroyer.new(user).destroy(user, delete_posts: false) } + + let(:destroy_opts) { {} } + before do # out of sync user_stat data shouldn't break UserDestroyer user.user_stat.update_attribute(:post_count, 1) end - let(:destroy_opts) { {} } - subject(:destroy) { UserDestroyer.new(user).destroy(user, delete_posts: false) } include_examples "successfully destroy a user" end context "when user has deleted posts" do let!(:deleted_post) { Fabricate(:post, user: user, deleted_at: 1.hour.ago) } + it "should mark the user's deleted posts as belonging to a nuked user" do expect { UserDestroyer.new(admin).destroy(user) }.to change { User.count }.by(-1) expect(deleted_post.reload.user_id).to eq(nil) @@ -273,9 +278,10 @@ RSpec.describe UserDestroyer do context "when user has no posts" do context "when destroy succeeds" do - let(:destroy_opts) { {} } subject(:destroy) { UserDestroyer.new(admin).destroy(user) } + let(:destroy_opts) { {} } + include_examples "successfully destroy a user" include_examples "email block list" end diff --git a/spec/services/user_silencer_spec.rb b/spec/services/user_silencer_spec.rb index b637fc6e9db..4a0b548d38e 100644 --- a/spec/services/user_silencer_spec.rb +++ b/spec/services/user_silencer_spec.rb @@ -6,9 +6,10 @@ RSpec.describe UserSilencer do fab!(:admin) { Fabricate(:admin) } describe "silence" do - let(:silencer) { UserSilencer.new(user) } subject(:silence_user) { silencer.silence } + let(:silencer) { UserSilencer.new(user) } + it "silences the user correctly" do expect { UserSilencer.silence(user, admin) }.to change { user.reload.silenced? }