DEV: Update the rubocop-discourse gem

This enables cops related to RSpec `subject`.

See https://github.com/discourse/rubocop-discourse/pull/32
This commit is contained in:
Loïc Guitaut 2023-06-21 16:00:19 +02:00 committed by Loïc Guitaut
parent 8e1d049e6b
commit 0f4beab0fb
129 changed files with 1697 additions and 1506 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 },

View File

@ -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

View File

@ -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

View File

@ -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 "doesnt 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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('<h1 style="color: red;">FOR YOU</h1>').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('<h1 style="color: red;">FOR YOU</h1>').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('<h1 style="color: red;">FOR YOU</h1>').count).to eq(1)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<mailto:somebadccemail@test.com"
subject.execute(args2)
job.execute(args2)
expect(ActionMailer::Base.deliveries.count).to eq(1)
last_email = ActionMailer::Base.deliveries.last
expect(last_email.subject).to eq("Re: Help I need support")
@ -199,7 +201,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when there are cc_addresses" do
it "has the cc_addresses and cc_user_ids filled in correctly" do
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(1)
sent_mail = ActionMailer::Base.deliveries.last
expect(sent_mail.subject).to eq("Re: Help I need support")
@ -212,7 +214,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
it "where cc_addresses match non-staged users, convert to bcc_addresses" do
staged2.update!(staged: false, active: true)
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(1)
sent_mail = ActionMailer::Base.deliveries.last
expect(sent_mail.subject).to eq("Re: Help I need support")
@ -233,7 +235,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
before { group.update!(imap_enabled: true) }
it "aborts and does not send a group SMTP email; the OP is the one that sent the email in the first place" do
expect { subject.execute(args) }.not_to(change { EmailLog.count })
expect { job.execute(args) }.not_to(change { EmailLog.count })
expect(ActionMailer::Base.deliveries.count).to eq(0)
end
end
@ -242,7 +244,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
before { group.update!(imap_enabled: false) }
it "sends the email as expected" do
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(1)
end
end
@ -251,7 +253,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when the post is deleted" do
it "aborts and adds a skipped email log" do
post.trash!
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
expect(
SkippedEmailLog.exists?(
@ -268,7 +270,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when the topic is deleted" do
it "aborts and adds a skipped email log" do
post.topic.trash!
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
expect(
SkippedEmailLog.exists?(
@ -285,7 +287,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when smtp is not enabled" do
it "returns without sending email" do
SiteSetting.enable_smtp = false
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
end
end
@ -293,7 +295,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when disable_emails is yes" do
it "returns without sending email" do
SiteSetting.disable_emails = "yes"
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
end
end
@ -301,7 +303,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when group is deleted" do
it "returns without sending email" do
group.destroy
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
end
end
@ -309,7 +311,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
context "when smtp is not enabled for the group" do
it "returns without sending email" do
group.update!(smtp_enabled: false)
subject.execute(args)
job.execute(args)
expect(ActionMailer::Base.deliveries.count).to eq(0)
expect(
SkippedEmailLog.exists?(

View File

@ -1,13 +1,15 @@
# frozen_string_literal: true
describe Jobs::PublishGroupMembershipUpdates do
subject(:job) { described_class.new }
fab!(:user) { Fabricate(:user) }
fab!(:group) { Fabricate(:group) }
it "publishes events for added users" do
events =
DiscourseEvent.track_events do
subject.execute(user_ids: [user.id], group_id: group.id, type: "add")
job.execute(user_ids: [user.id], group_id: group.id, type: "add")
end
expect(events).to include(
@ -19,7 +21,7 @@ describe Jobs::PublishGroupMembershipUpdates do
it "publishes events for removed users" do
events =
DiscourseEvent.track_events do
subject.execute(user_ids: [user.id], group_id: group.id, type: "remove")
job.execute(user_ids: [user.id], group_id: group.id, type: "remove")
end
expect(events).to include(event_name: :user_removed_from_group, params: [user, group])
@ -27,9 +29,7 @@ describe Jobs::PublishGroupMembershipUpdates do
it "does nothing if the group doesn't exist" do
events =
DiscourseEvent.track_events do
subject.execute(user_ids: [user.id], group_id: nil, type: "add")
end
DiscourseEvent.track_events { job.execute(user_ids: [user.id], group_id: nil, type: "add") }
expect(events).not_to include(
event_name: :user_added_to_group,
@ -38,7 +38,7 @@ describe Jobs::PublishGroupMembershipUpdates do
end
it "fails when the update type is invalid" do
expect { subject.execute(user_ids: [user.id], group_id: nil, type: nil) }.to raise_error(
expect { job.execute(user_ids: [user.id], group_id: nil, type: nil) }.to raise_error(
Discourse::InvalidParameters,
)
end
@ -46,7 +46,7 @@ describe Jobs::PublishGroupMembershipUpdates do
it "does nothing when the user is not human" do
events =
DiscourseEvent.track_events do
subject.execute(user_ids: [Discourse.system_user.id], group_id: nil, type: "add")
job.execute(user_ids: [Discourse.system_user.id], group_id: nil, type: "add")
end
expect(events).not_to include(

View File

@ -1,12 +1,15 @@
# frozen_string_literal: true
RSpec.describe Jobs::ReindexSearch do
subject(:job) { described_class.new }
let(:locale) { "fr" }
before do
SearchIndexer.enable
Jobs.run_immediately!
end
let(:locale) { "fr" }
# This works since test db has a small record less than limit.
# Didn't check `topic` because topic doesn't have posts in fabrication
# thus no search data
@ -15,7 +18,7 @@ RSpec.describe Jobs::ReindexSearch do
SiteSetting.default_locale = "en"
model = Fabricate(m.to_sym)
SiteSetting.default_locale = locale
subject.execute({})
job.execute({})
expect(model.public_send("#{m}_search_data").locale).to eq locale
end
@ -26,7 +29,7 @@ RSpec.describe Jobs::ReindexSearch do
search_data.update!(version: 0)
model.reload
subject.execute({})
job.execute({})
expect(model.public_send("#{m}_search_data").version).to eq(
"SearchIndexer::#{m.upcase}_INDEX_VERSION".constantize,
)
@ -64,7 +67,7 @@ RSpec.describe Jobs::ReindexSearch do
post2.topic.trash!
post3.trash!
subject.rebuild_posts(indexer: FakeIndexer)
job.rebuild_posts(indexer: FakeIndexer)
expect(FakeIndexer.posts).to contain_exactly(post)
end
@ -72,7 +75,7 @@ RSpec.describe Jobs::ReindexSearch do
it "should not reindex posts with a developmental version" do
Fabricate(:post, version: SearchIndexer::POST_INDEX_VERSION + 1)
subject.rebuild_posts(indexer: FakeIndexer)
job.rebuild_posts(indexer: FakeIndexer)
expect(FakeIndexer.posts).to eq([])
end
@ -85,7 +88,7 @@ RSpec.describe Jobs::ReindexSearch do
post2.save!(validate: false)
subject.rebuild_posts(indexer: FakeIndexer)
job.rebuild_posts(indexer: FakeIndexer)
expect(FakeIndexer.posts).to contain_exactly(post)
end
@ -100,7 +103,7 @@ RSpec.describe Jobs::ReindexSearch do
freeze_time(1.day.ago) { topic.trash! }
expect { subject.execute({}) }.to change { TopicSearchData.count }.by(-1)
expect { job.execute({}) }.to change { TopicSearchData.count }.by(-1)
expect(Topic.pluck(:id)).to contain_exactly(topic2.id)
expect(TopicSearchData.pluck(:topic_id)).to contain_exactly(topic2.topic_search_data.topic_id)
@ -124,7 +127,7 @@ RSpec.describe Jobs::ReindexSearch do
post6.trash!
end
expect { subject.execute({}) }.to change { PostSearchData.count }.by(-3)
expect { job.execute({}) }.to change { PostSearchData.count }.by(-3)
expect(Post.pluck(:id)).to contain_exactly(post.id, post2.id, post3.id, post4.id, post5.id)

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
RSpec.describe Jobs::SyncTopicUserBookmarked do
subject(:job) { described_class.new }
fab!(:topic) { Fabricate(:topic) }
fab!(:post1) { Fabricate(:post, topic: topic) }
fab!(:post2) { Fabricate(:post, topic: topic) }
@ -16,7 +18,7 @@ RSpec.describe Jobs::SyncTopicUserBookmarked do
Fabricate(:bookmark, user: tu1.user, bookmarkable: topic.posts.sample)
Fabricate(:bookmark, user: tu4.user, bookmarkable: topic.posts.sample)
subject.execute(topic_id: topic.id)
job.execute(topic_id: topic.id)
expect(tu1.reload.bookmarked).to eq(true)
expect(tu2.reload.bookmarked).to eq(false)
@ -31,7 +33,7 @@ RSpec.describe Jobs::SyncTopicUserBookmarked do
post1.trash!
subject.execute(topic_id: topic.id)
job.execute(topic_id: topic.id)
expect(tu1.reload.bookmarked).to eq(false)
expect(tu2.reload.bookmarked).to eq(false)
@ -41,7 +43,7 @@ RSpec.describe Jobs::SyncTopicUserBookmarked do
Fabricate(:bookmark, user: tu1.user, bookmarkable: topic.posts.sample)
Fabricate(:bookmark, user: tu4.user, bookmarkable: topic.posts.sample)
subject.execute
job.execute
expect(tu1.reload.bookmarked).to eq(true)
expect(tu2.reload.bookmarked).to eq(false)

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe Jobs::TopicTimerEnqueuer do
subject { described_class.new }
subject(:job) { described_class.new }
fab!(:timer1) do
Fabricate(
@ -40,20 +40,20 @@ RSpec.describe Jobs::TopicTimerEnqueuer do
it "does not enqueue deleted timers" do
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: deleted_timer.id })
subject.execute
job.execute
expect(deleted_timer.topic.reload.closed?).to eq(false)
end
it "does not enqueue future timers" do
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: future_timer.id })
subject.execute
job.execute
expect(future_timer.topic.reload.closed?).to eq(false)
end
it "enqueues the related job" do
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: deleted_timer.id })
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: future_timer.id })
subject.execute
job.execute
expect_job_enqueued(job: :close_topic, args: { topic_timer_id: timer1.id })
expect_job_enqueued(job: :open_topic, args: { topic_timer_id: timer2.id })
end
@ -61,11 +61,11 @@ RSpec.describe Jobs::TopicTimerEnqueuer do
it "does not re-enqueue a job that has already been scheduled ahead of time in sidekiq (legacy topic timers)" do
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: timer1.id })
Jobs.enqueue_at(1.hours.from_now, :close_topic, topic_timer_id: timer1.id)
subject.execute
job.execute
end
it "does not fail to enqueue other timers just because one timer errors" do
TopicTimer.any_instance.stubs(:enqueue_typed_job).raises(StandardError).then.returns(true)
expect { subject.execute }.not_to raise_error
expect { job.execute }.not_to raise_error
end
end

View File

@ -3,12 +3,12 @@
require_relative "shared_context_for_backup_restore"
RSpec.describe BackupRestore::DatabaseRestorer, type: :multisite do
subject(:restorer) { BackupRestore::DatabaseRestorer.new(logger, current_db) }
include_context "with shared stuff"
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
describe "#restore" do
context "with database connection" do
it "reconnects to the correct database" do

View File

@ -3,12 +3,12 @@
require_relative "shared_context_for_backup_restore"
RSpec.describe BackupRestore::DatabaseRestorer do
subject(:restorer) { BackupRestore::DatabaseRestorer.new(logger, current_db) }
include_context "with shared stuff"
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
describe "#restore" do
it "executes everything in the correct order" do
restore = sequence("restore")
@ -18,7 +18,7 @@ RSpec.describe BackupRestore::DatabaseRestorer do
expect_db_migrate.in_sequence(restore)
expect_db_reconnect.in_sequence(restore)
subject.restore("foo.sql")
restorer.restore("foo.sql")
end
it "stores the date of the last restore" do
@ -146,12 +146,12 @@ RSpec.describe BackupRestore::DatabaseRestorer do
it "moves tables back when tables were moved" do
BackupRestore.stubs(:can_rollback?).returns(true)
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").never
subject.rollback
restorer.rollback
execute_stubbed_restore
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").once
subject.rollback
restorer.rollback
end
end
@ -164,7 +164,7 @@ RSpec.describe BackupRestore::DatabaseRestorer do
it "doesn't try to drop function when no functions have been created" do
Migration::BaseDropper.expects(:drop_readonly_function).never
subject.clean_up
restorer.clean_up
end
it "creates and drops all functions when none exist" do
@ -174,7 +174,7 @@ RSpec.describe BackupRestore::DatabaseRestorer do
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :via_email)
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :raw_email)
subject.clean_up
restorer.clean_up
end
it "creates and drops only missing functions during restore" do
@ -186,19 +186,17 @@ RSpec.describe BackupRestore::DatabaseRestorer do
execute_stubbed_restore(stub_readonly_functions: false)
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :via_email)
subject.clean_up
restorer.clean_up
end
end
describe ".drop_backup_schema" do
subject { BackupRestore::DatabaseRestorer }
context "when no backup schema exists" do
it "doesn't do anything" do
ActiveRecord::Base.connection.expects(:schema_exists?).with("backup").returns(false)
ActiveRecord::Base.connection.expects(:drop_schema).never
subject.drop_backup_schema
described_class.drop_backup_schema
end
end
@ -209,14 +207,14 @@ RSpec.describe BackupRestore::DatabaseRestorer do
ActiveRecord::Base.connection.expects(:drop_schema).with("backup")
BackupMetadata.update_last_restore_date(8.days.ago)
subject.drop_backup_schema
described_class.drop_backup_schema
end
it "doesn't drop the schema when the last restore was recently" do
ActiveRecord::Base.connection.expects(:drop_schema).with("backup").never
BackupMetadata.update_last_restore_date(6.days.ago)
subject.drop_backup_schema
described_class.drop_backup_schema
end
it "stores the current date when there is no record of the last restore" do
@ -225,7 +223,7 @@ RSpec.describe BackupRestore::DatabaseRestorer do
date_string = "2020-01-08T17:38:27Z"
freeze_time(Time.parse(date_string))
subject.drop_backup_schema
described_class.drop_backup_schema
expect(BackupMetadata.value_for(BackupMetadata::LAST_RESTORE_DATE)).to eq(date_string)
end
end

View File

@ -4,6 +4,8 @@ require "backup_restore/local_backup_store"
require_relative "shared_examples_for_backup_store"
RSpec.describe BackupRestore::LocalBackupStore do
subject(:store) { BackupRestore::BackupStore.create(root_directory: @root_directory) }
before do
@root_directory = Dir.mktmpdir
@paths = []
@ -12,7 +14,6 @@ RSpec.describe BackupRestore::LocalBackupStore do
after { FileUtils.remove_dir(@root_directory, true) }
subject(:store) { BackupRestore::BackupStore.create(root_directory: @root_directory) }
let(:expected_type) { BackupRestore::LocalBackupStore }
it_behaves_like "backup store"

View File

@ -5,6 +5,8 @@ require "backup_restore/s3_backup_store"
require_relative "shared_examples_for_backup_store"
RSpec.describe BackupRestore::S3BackupStore do
subject(:store) { BackupRestore::BackupStore.create(s3_options: @s3_options) }
before do
@s3_client = Aws::S3::Client.new(stub_responses: true)
@s3_options = { client: @s3_client }
@ -86,7 +88,6 @@ RSpec.describe BackupRestore::S3BackupStore do
SiteSetting.backup_location = BackupLocationSiteSetting::S3
end
subject(:store) { BackupRestore::BackupStore.create(s3_options: @s3_options) }
let(:expected_type) { BackupRestore::S3BackupStore }
it_behaves_like "backup store"

View File

@ -3,9 +3,9 @@
require_relative "shared_context_for_backup_restore"
RSpec.describe BackupRestore::SystemInterface, type: :multisite do
include_context "with shared stuff"
subject(:system_interface) { BackupRestore::SystemInterface.new(logger) }
subject { BackupRestore::SystemInterface.new(logger) }
include_context "with shared stuff"
describe "#flush_redis" do
it "removes only keys from the current site in a multisite" do
@ -24,7 +24,7 @@ RSpec.describe BackupRestore::SystemInterface, type: :multisite do
expect(Discourse.redis.get("foo")).to eq("second-foo")
expect(Discourse.redis.get("bar")).to eq("second-bar")
subject.flush_redis
system_interface.flush_redis
expect(Discourse.redis.get("foo")).to be_nil
expect(Discourse.redis.get("bar")).to be_nil
@ -43,7 +43,7 @@ RSpec.describe BackupRestore::SystemInterface, type: :multisite do
BackupRestore.mark_as_running!
expect do
thread = subject.listen_for_shutdown_signal
thread = system_interface.listen_for_shutdown_signal
BackupRestore.set_shutdown_signal!
thread.join
end.to raise_error(SystemExit)

View File

@ -3,9 +3,9 @@
require_relative "shared_context_for_backup_restore"
RSpec.describe BackupRestore::SystemInterface do
include_context "with shared stuff"
subject(:system_interface) { BackupRestore::SystemInterface.new(logger) }
subject { BackupRestore::SystemInterface.new(logger) }
include_context "with shared stuff"
describe "readonly mode" do
after { Discourse::READONLY_KEYS.each { |key| Discourse.redis.del(key) } }
@ -13,26 +13,26 @@ RSpec.describe BackupRestore::SystemInterface do
describe "#enable_readonly_mode" do
it "enables readonly mode" do
Discourse.expects(:enable_readonly_mode).once
subject.enable_readonly_mode
system_interface.enable_readonly_mode
end
it "does not enable readonly mode when it is already in readonly mode" do
Discourse.enable_readonly_mode
Discourse.expects(:enable_readonly_mode).never
subject.enable_readonly_mode
system_interface.enable_readonly_mode
end
end
describe "#disable_readonly_mode" do
it "disables readonly mode" do
Discourse.expects(:disable_readonly_mode).once
subject.disable_readonly_mode
system_interface.disable_readonly_mode
end
it "does not disable readonly mode when readonly mode was explicitly enabled" do
Discourse.enable_readonly_mode
Discourse.expects(:disable_readonly_mode).never
subject.disable_readonly_mode
system_interface.disable_readonly_mode
end
end
end
@ -40,14 +40,14 @@ RSpec.describe BackupRestore::SystemInterface do
describe "#mark_restore_as_running" do
it "calls mark_restore_as_running" do
BackupRestore.expects(:mark_as_running!).once
subject.mark_restore_as_running
system_interface.mark_restore_as_running
end
end
describe "#mark_restore_as_not_running" do
it "calls mark_restore_as_not_running" do
BackupRestore.expects(:mark_as_not_running!).once
subject.mark_restore_as_not_running
system_interface.mark_restore_as_not_running
end
end
@ -61,7 +61,7 @@ RSpec.describe BackupRestore::SystemInterface do
it "exits the process when shutdown signal is set" do
expect do
thread = subject.listen_for_shutdown_signal
thread = system_interface.listen_for_shutdown_signal
BackupRestore.set_shutdown_signal!
thread.join
end.to raise_error(SystemExit)
@ -71,7 +71,7 @@ RSpec.describe BackupRestore::SystemInterface do
BackupRestore.set_shutdown_signal!
expect(BackupRestore.should_shutdown?).to eq(true)
thread = subject.listen_for_shutdown_signal
thread = system_interface.listen_for_shutdown_signal
expect(BackupRestore.should_shutdown?).to eq(false)
Thread.kill(thread)
end
@ -82,7 +82,7 @@ RSpec.describe BackupRestore::SystemInterface do
it "calls pause!" do
expect(Sidekiq.paused?).to eq(false)
subject.pause_sidekiq("my reason")
system_interface.pause_sidekiq("my reason")
expect(Sidekiq.paused?).to eq(true)
expect(Discourse.redis.get(SidekiqPauser::PAUSED_KEY)).to eq("my reason")
end
@ -93,15 +93,15 @@ RSpec.describe BackupRestore::SystemInterface do
Sidekiq.pause!
expect(Sidekiq.paused?).to eq(true)
subject.unpause_sidekiq
system_interface.unpause_sidekiq
expect(Sidekiq.paused?).to eq(false)
end
end
describe "#wait_for_sidekiq" do
it "waits 6 seconds even when there are no running Sidekiq jobs" do
subject.expects(:sleep).with(6).once
subject.wait_for_sidekiq
system_interface.expects(:sleep).with(6).once
system_interface.wait_for_sidekiq
end
context "with Sidekiq workers" do
@ -146,22 +146,26 @@ RSpec.describe BackupRestore::SystemInterface do
end
it "waits up to 60 seconds for jobs running for the current site to finish" do
subject.expects(:sleep).with(6).times(10)
system_interface.expects(:sleep).with(6).times(10)
create_workers
expect { subject.wait_for_sidekiq }.to raise_error(BackupRestore::RunningSidekiqJobsError)
expect { system_interface.wait_for_sidekiq }.to raise_error(
BackupRestore::RunningSidekiqJobsError,
)
end
it "waits up to 60 seconds for jobs running on all sites to finish" do
subject.expects(:sleep).with(6).times(10)
system_interface.expects(:sleep).with(6).times(10)
create_workers(all_sites: true)
expect { subject.wait_for_sidekiq }.to raise_error(BackupRestore::RunningSidekiqJobsError)
expect { system_interface.wait_for_sidekiq }.to raise_error(
BackupRestore::RunningSidekiqJobsError,
)
end
it "ignores jobs of other sites" do
subject.expects(:sleep).with(6).once
system_interface.expects(:sleep).with(6).once
create_workers(site_id: "another_site")
subject.wait_for_sidekiq
system_interface.wait_for_sidekiq
end
end
end
@ -172,7 +176,7 @@ RSpec.describe BackupRestore::SystemInterface do
it "doesn't unpause Sidekiq" do
Sidekiq.pause!
subject.flush_redis
system_interface.flush_redis
expect(Sidekiq.paused?).to eq(true)
end

View File

@ -4,9 +4,9 @@
require_relative "shared_context_for_backup_restore"
RSpec.describe BackupRestore::UploadsRestorer do
include_context "with shared stuff"
subject(:restorer) { BackupRestore::UploadsRestorer.new(logger) }
subject { BackupRestore::UploadsRestorer.new(logger) }
include_context "with shared stuff"
def with_temp_uploads_directory(name: "default", with_optimized: false)
Dir.mktmpdir do |directory|
@ -93,7 +93,7 @@ RSpec.describe BackupRestore::UploadsRestorer do
def setup_and_restore(directory, metadata)
metadata.each { |d| BackupMetadata.create!(d) }
subject.restore(directory)
restorer.restore(directory)
end
def uploads_path(database)
@ -119,15 +119,15 @@ RSpec.describe BackupRestore::UploadsRestorer do
let(:target_site_name) { target_site_type == multisite ? "second" : "default" }
let(:target_hostname) { target_site_type == multisite ? "test2.localhost" : "test.localhost" }
shared_context "with no uploads" do
shared_examples "with no uploads" do
it "does nothing when temporary uploads directory is missing or empty" do
store_class.any_instance.expects(:copy_from).never
Dir.mktmpdir do |directory|
subject.restore(directory)
restorer.restore(directory)
FileUtils.mkdir(File.join(directory, "uploads"))
subject.restore(directory)
restorer.restore(directory)
end
end
end
@ -176,7 +176,7 @@ RSpec.describe BackupRestore::UploadsRestorer do
with_temp_uploads_directory do |directory, path|
store_class.any_instance.expects(:copy_from).with(path).once
expect { subject.restore(directory) }.to change { OptimizedImage.count }.by_at_most(
expect { restorer.restore(directory) }.to change { OptimizedImage.count }.by_at_most(
-1,
).and change { Jobs::CreateAvatarThumbnails.jobs.size }.by(1).and change {
Post.where(baked_version: nil).count
@ -190,7 +190,7 @@ RSpec.describe BackupRestore::UploadsRestorer do
with_temp_uploads_directory(with_optimized: true) do |directory, path|
store_class.any_instance.expects(:copy_from).with(path).once
expect { subject.restore(directory) }.to not_change {
expect { restorer.restore(directory) }.to not_change {
OptimizedImage.count
}.and not_change { Jobs::CreateAvatarThumbnails.jobs.size }.and change {
Post.where(baked_version: nil).count
@ -609,14 +609,14 @@ RSpec.describe BackupRestore::UploadsRestorer do
Discourse.stubs(:store).returns(Object.new)
with_temp_uploads_directory do |directory|
expect { subject.restore(directory) }.to raise_error(BackupRestore::UploadsRestoreError)
expect { restorer.restore(directory) }.to raise_error(BackupRestore::UploadsRestoreError)
end
end
it "raises an exception when there are multiple folders in the uploads directory" do
with_temp_uploads_directory do |directory|
FileUtils.mkdir_p(File.join(directory, "uploads", "foo"))
expect { subject.restore(directory) }.to raise_error(BackupRestore::UploadsRestoreError)
expect { restorer.restore(directory) }.to raise_error(BackupRestore::UploadsRestoreError)
end
end

View File

@ -1,25 +1,25 @@
# frozen_string_literal: true
RSpec.describe BookmarkManager do
let(:user) { Fabricate(:user) }
subject(:manager) { described_class.new(user) }
let(:reminder_at) { 1.day.from_now }
fab!(:post) { Fabricate(:post) }
let(:name) { "Check this out!" }
subject { described_class.new(user) }
let(:user) { Fabricate(:user) }
let(:reminder_at) { 1.day.from_now }
let(:name) { "Check this out!" }
describe ".destroy" do
let!(:bookmark) { Fabricate(:bookmark, user: user, bookmarkable: post) }
it "deletes the existing bookmark" do
subject.destroy(bookmark.id)
manager.destroy(bookmark.id)
expect(Bookmark.exists?(id: bookmark.id)).to eq(false)
end
context "if the bookmark is the last one bookmarked in the topic" do
it "marks the topic user bookmarked column as false" do
TopicUser.create(user: user, topic: post.topic, bookmarked: true)
subject.destroy(bookmark.id)
manager.destroy(bookmark.id)
tu = TopicUser.find_by(user: user)
expect(tu.bookmarked).to eq(false)
end
@ -28,13 +28,13 @@ RSpec.describe BookmarkManager do
context "if the bookmark is belonging to some other user" do
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin), bookmarkable: post) }
it "raises an invalid access error" do
expect { subject.destroy(bookmark.id) }.to raise_error(Discourse::InvalidAccess)
expect { manager.destroy(bookmark.id) }.to raise_error(Discourse::InvalidAccess)
end
end
context "if the bookmark no longer exists" do
it "raises a not found error" do
expect { subject.destroy(9999) }.to raise_error(Discourse::NotFound)
expect { manager.destroy(9999) }.to raise_error(Discourse::NotFound)
end
end
end
@ -53,7 +53,7 @@ RSpec.describe BookmarkManager do
let(:options) { {} }
def update_bookmark
subject.update(
manager.update(
bookmark_id: bookmark.id,
name: new_name,
reminder_at: new_reminder_at,
@ -70,7 +70,7 @@ RSpec.describe BookmarkManager do
it "does not reminder_last_sent_at if reminder did not change" do
bookmark.update(reminder_last_sent_at: 1.day.ago)
subject.update(bookmark_id: bookmark.id, name: new_name, reminder_at: bookmark.reminder_at)
manager.update(bookmark_id: bookmark.id, name: new_name, reminder_at: bookmark.reminder_at)
bookmark.reload
expect(bookmark.reminder_last_sent_at).not_to eq(nil)
end
@ -112,20 +112,20 @@ RSpec.describe BookmarkManager do
end
it "destroys all bookmarks for the topic for the specified user" do
subject.destroy_for_topic(topic)
manager.destroy_for_topic(topic)
expect(Bookmark.for_user_in_topic(user.id, topic.id).length).to eq(0)
end
it "does not destroy any other user's topic bookmarks" do
user2 = Fabricate(:user)
Fabricate(:bookmark, bookmarkable: Fabricate(:post, topic: topic), user: user2)
subject.destroy_for_topic(topic)
manager.destroy_for_topic(topic)
expect(Bookmark.for_user_in_topic(user2.id, topic.id).length).to eq(1)
end
it "updates the topic user bookmarked column to false" do
TopicUser.create(user: user, topic: topic, bookmarked: true)
subject.destroy_for_topic(topic)
manager.destroy_for_topic(topic)
tu = TopicUser.find_by(user: user)
expect(tu.bookmarked).to eq(false)
end
@ -176,20 +176,20 @@ RSpec.describe BookmarkManager do
it "sets pinned to false if it is true" do
bookmark.update(pinned: true)
subject.toggle_pin(bookmark_id: bookmark.id)
manager.toggle_pin(bookmark_id: bookmark.id)
expect(bookmark.reload.pinned).to eq(false)
end
it "sets pinned to true if it is false" do
bookmark.update(pinned: false)
subject.toggle_pin(bookmark_id: bookmark.id)
manager.toggle_pin(bookmark_id: bookmark.id)
expect(bookmark.reload.pinned).to eq(true)
end
context "if the bookmark is belonging to some other user" do
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin)) }
it "raises an invalid access error" do
expect { subject.toggle_pin(bookmark_id: bookmark.id) }.to raise_error(
expect { manager.toggle_pin(bookmark_id: bookmark.id) }.to raise_error(
Discourse::InvalidAccess,
)
end
@ -198,18 +198,18 @@ RSpec.describe BookmarkManager do
context "if the bookmark no longer exists" do
before { bookmark.destroy! }
it "raises a not found error" do
expect { subject.toggle_pin(bookmark_id: bookmark.id) }.to raise_error(Discourse::NotFound)
expect { manager.toggle_pin(bookmark_id: bookmark.id) }.to raise_error(Discourse::NotFound)
end
end
end
describe "#create_for" do
it "allows creating a bookmark for the topic and for the first post" do
subject.create_for(bookmarkable_id: post.topic_id, bookmarkable_type: "Topic", name: name)
manager.create_for(bookmarkable_id: post.topic_id, bookmarkable_type: "Topic", name: name)
bookmark = Bookmark.find_by(user: user, bookmarkable: post.topic)
expect(bookmark.present?).to eq(true)
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
bookmark = Bookmark.find_by(user: user, bookmarkable: post)
expect(bookmark).not_to eq(nil)
end
@ -217,26 +217,26 @@ RSpec.describe BookmarkManager do
it "when topic is deleted it raises invalid access from guardian check" do
post.topic.trash!
expect {
subject.create_for(bookmarkable_id: post.topic_id, bookmarkable_type: "Topic", name: name)
manager.create_for(bookmarkable_id: post.topic_id, bookmarkable_type: "Topic", name: name)
}.to raise_error(Discourse::InvalidAccess)
end
it "when post is deleted it raises invalid access from guardian check" do
post.trash!
expect do
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
end.to raise_error(Discourse::InvalidAccess)
end
it "adds a validation error when the bookmarkable_type is not registered" do
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "BlahFactory", name: name)
expect(subject.errors.full_messages).to include(
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "BlahFactory", name: name)
expect(manager.errors.full_messages).to include(
I18n.t("bookmarks.errors.invalid_bookmarkable", type: "BlahFactory"),
)
end
it "updates the topic user bookmarked column to true if any post is bookmarked" do
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -246,14 +246,14 @@ RSpec.describe BookmarkManager do
expect(tu.bookmarked).to eq(true)
tu.update(bookmarked: false)
new_post = Fabricate(:post, topic: post.topic)
subject.create_for(bookmarkable_id: new_post.id, bookmarkable_type: "Post")
manager.create_for(bookmarkable_id: new_post.id, bookmarkable_type: "Post")
tu.reload
expect(tu.bookmarked).to eq(true)
end
it "sets auto_delete_preference to clear_reminder by default" do
bookmark =
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -273,7 +273,7 @@ RSpec.describe BookmarkManager do
it "sets auto_delete_preferences to the user's user_option.bookmark_auto_delete_preference" do
bookmark =
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -286,7 +286,7 @@ RSpec.describe BookmarkManager do
it "uses the passed in auto_delete_preference option instead of the user's one" do
bookmark =
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -303,7 +303,7 @@ RSpec.describe BookmarkManager do
context "when a reminder time is provided" do
it "saves the values correctly" do
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -322,7 +322,7 @@ RSpec.describe BookmarkManager do
end
it "saves any additional options successfully" do
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
@ -339,8 +339,8 @@ RSpec.describe BookmarkManager do
before { Bookmark.create(bookmarkable: post, user: user) }
it "adds an error to the manager" do
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post")
expect(subject.errors.full_messages).to include(
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post")
expect(manager.errors.full_messages).to include(
I18n.t("bookmarks.errors.already_bookmarked", type: "Post"),
)
end
@ -348,8 +348,8 @@ RSpec.describe BookmarkManager do
context "when the bookmark name is too long" do
it "adds an error to the manager" do
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: "test" * 100)
expect(subject.errors.full_messages).to include(
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: "test" * 100)
expect(manager.errors.full_messages).to include(
"Name is too long (maximum is 100 characters)",
)
end
@ -359,13 +359,13 @@ RSpec.describe BookmarkManager do
let(:reminder_at) { 10.days.ago }
it "adds an error to the manager" do
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
reminder_at: reminder_at,
)
expect(subject.errors.full_messages).to include(
expect(manager.errors.full_messages).to include(
I18n.t("bookmarks.errors.cannot_set_past_reminder"),
)
end
@ -375,13 +375,13 @@ RSpec.describe BookmarkManager do
let(:reminder_at) { 11.years.from_now }
it "adds an error to the manager" do
subject.create_for(
manager.create_for(
bookmarkable_id: post.id,
bookmarkable_type: "Post",
name: name,
reminder_at: reminder_at,
)
expect(subject.errors.full_messages).to include(
expect(manager.errors.full_messages).to include(
I18n.t("bookmarks.errors.cannot_set_reminder_in_distant_future"),
)
end
@ -391,7 +391,7 @@ RSpec.describe BookmarkManager do
before { post.trash! }
it "raises an invalid access error" do
expect {
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
}.to raise_error(Discourse::InvalidAccess)
end
end
@ -400,7 +400,7 @@ RSpec.describe BookmarkManager do
before { post.topic.update(category: Fabricate(:private_category, group: Fabricate(:group))) }
it "raises an invalid access error" do
expect {
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: name)
}.to raise_error(Discourse::InvalidAccess)
end
end

View File

@ -1,19 +1,20 @@
# frozen_string_literal: true
RSpec.describe BookmarkReminderNotificationHandler do
subject { described_class }
fab!(:user) { Fabricate(:user) }
before { Discourse.redis.flushdb }
describe "#send_notification" do
subject(:send_notification) { handler.send_notification }
let(:handler) { described_class.new(bookmark) }
let!(:bookmark) do
Fabricate(:bookmark_next_business_day_reminder, user: user, bookmarkable: Fabricate(:post))
end
it "creates a bookmark reminder notification with the correct details" do
subject.new(bookmark).send_notification
send_notification
notif = bookmark.user.notifications.last
expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder])
expect(notif.topic_id).to eq(bookmark.bookmarkable.topic_id)
@ -32,7 +33,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
end
it "does not send a notification and updates last notification attempt time" do
expect { subject.new(bookmark).send_notification }.not_to change { Notification.count }
expect { send_notification }.not_to change { Notification.count }
expect(bookmark.reload.reminder_last_sent_at).not_to be_blank
end
end
@ -46,12 +47,12 @@ RSpec.describe BookmarkReminderNotificationHandler do
end
it "deletes the bookmark after the reminder gets sent" do
subject.new(bookmark).send_notification
send_notification
expect(Bookmark.find_by(id: bookmark.id)).to eq(nil)
end
it "changes the TopicUser bookmarked column to false" do
subject.new(bookmark).send_notification
send_notification
expect(TopicUser.find_by(topic: bookmark.bookmarkable.topic, user: user).bookmarked).to eq(
false,
)
@ -67,7 +68,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
end
it "does not change the TopicUser bookmarked column to false" do
subject.new(bookmark).send_notification
send_notification
expect(
TopicUser.find_by(topic: bookmark.bookmarkable.topic, user: user).bookmarked,
).to eq(true)
@ -82,7 +83,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
end
it "resets reminder_at after the reminder gets sent" do
subject.new(bookmark).send_notification
send_notification
expect(Bookmark.find_by(id: bookmark.id).reminder_at).to eq(nil)
end
end

View File

@ -6,32 +6,32 @@ RSpec.describe CommonPasswords do
end
describe "#common_password?" do
before { described_class.stubs(:redis).returns(stub_everything) }
subject(:common_password) { described_class.common_password? @password }
subject { described_class.common_password? @password }
before { described_class.stubs(:redis).returns(stub_everything) }
it "returns false if password isn't in the common passwords list" do
described_class.stubs(:password_list).returns(stub_everything(include?: false))
@password = "uncommonPassword"
expect(subject).to eq(false)
expect(common_password).to eq(false)
end
it "returns false if password is nil" do
described_class.expects(:password_list).never
@password = nil
expect(subject).to eq(false)
expect(common_password).to eq(false)
end
it "returns false if password is blank" do
described_class.expects(:password_list).never
@password = ""
expect(subject).to eq(false)
expect(common_password).to eq(false)
end
it "returns true if password is in the common passwords list" do
described_class.stubs(:password_list).returns(stub_everything(include?: true))
@password = "password"
expect(subject).to eq(true)
expect(common_password).to eq(true)
end
end

View File

@ -8,7 +8,7 @@ RSpec.describe DiscourseUpdates do
DiscourseUpdates.updated_at = updated_at
end
subject { DiscourseUpdates.check_version }
subject(:version) { DiscourseUpdates.check_version }
context "when version check was done at the current installed version" do
before { DiscourseUpdates.last_installed_version = Discourse::VERSION::STRING }
@ -19,15 +19,15 @@ RSpec.describe DiscourseUpdates do
before { stub_data(Discourse::VERSION::STRING, 0, false, time) }
it "returns all the version fields" do
expect(subject.latest_version).to eq(Discourse::VERSION::STRING)
expect(subject.missing_versions_count).to eq(0)
expect(subject.critical_updates).to eq(false)
expect(subject.installed_version).to eq(Discourse::VERSION::STRING)
expect(subject.stale_data).to eq(false)
expect(version.latest_version).to eq(Discourse::VERSION::STRING)
expect(version.missing_versions_count).to eq(0)
expect(version.critical_updates).to eq(false)
expect(version.installed_version).to eq(Discourse::VERSION::STRING)
expect(version.stale_data).to eq(false)
end
it "returns the timestamp of the last version check" do
expect(subject.updated_at).to be_within_one_second_of(time)
expect(version.updated_at).to be_within_one_second_of(time)
end
end
@ -36,14 +36,14 @@ RSpec.describe DiscourseUpdates do
before { stub_data("0.9.0", 2, false, time) }
it "returns all the version fields" do
expect(subject.latest_version).to eq("0.9.0")
expect(subject.missing_versions_count).to eq(2)
expect(subject.critical_updates).to eq(false)
expect(subject.installed_version).to eq(Discourse::VERSION::STRING)
expect(version.latest_version).to eq("0.9.0")
expect(version.missing_versions_count).to eq(2)
expect(version.critical_updates).to eq(false)
expect(version.installed_version).to eq(Discourse::VERSION::STRING)
end
it "returns the timestamp of the last version check" do
expect(subject.updated_at).to be_within_one_second_of(time)
expect(version.updated_at).to be_within_one_second_of(time)
end
end
end
@ -52,22 +52,22 @@ RSpec.describe DiscourseUpdates do
before { stub_data(nil, nil, false, nil) }
it "returns the installed version" do
expect(subject.installed_version).to eq(Discourse::VERSION::STRING)
expect(version.installed_version).to eq(Discourse::VERSION::STRING)
end
it "indicates that version check has not been performed" do
expect(subject.updated_at).to eq(nil)
expect(subject.stale_data).to eq(true)
expect(version.updated_at).to eq(nil)
expect(version.stale_data).to eq(true)
end
it "does not return latest version info" do
expect(subject.latest_version).to eq(nil)
expect(subject.missing_versions_count).to eq(nil)
expect(subject.critical_updates).to eq(nil)
expect(version.latest_version).to eq(nil)
expect(version.missing_versions_count).to eq(nil)
expect(version.critical_updates).to eq(nil)
end
it "queues a version check" do
expect_enqueued_with(job: :version_check) { subject }
expect_enqueued_with(job: :version_check) { version }
end
end
@ -76,15 +76,15 @@ RSpec.describe DiscourseUpdates do
context "with old version check data" do
shared_examples "queue version check and report that version is ok" do
it "queues a version check" do
expect_enqueued_with(job: :version_check) { subject }
expect_enqueued_with(job: :version_check) { version }
end
it "reports 0 missing versions" do
expect(subject.missing_versions_count).to eq(0)
expect(version.missing_versions_count).to eq(0)
end
it "reports that a version check will be run soon" do
expect(subject.version_check_pending).to eq(true)
expect(version.version_check_pending).to eq(true)
end
end
@ -105,15 +105,15 @@ RSpec.describe DiscourseUpdates do
shared_examples "when last_installed_version is old" do
it "queues a version check" do
expect_enqueued_with(job: :version_check) { subject }
expect_enqueued_with(job: :version_check) { version }
end
it "reports 0 missing versions" do
expect(subject.missing_versions_count).to eq(0)
expect(version.missing_versions_count).to eq(0)
end
it "reports that a version check will be run soon" do
expect(subject.version_check_pending).to eq(true)
expect(version.version_check_pending).to eq(true)
end
end

View File

@ -4,9 +4,9 @@ require "email/message_builder"
RSpec.describe Email::MessageBuilder do
let(:to_address) { "jake@adventuretime.ooo" }
let(:subject) { "Tree Trunks has made some apple pie!" }
let(:email_subject) { "Tree Trunks has made some apple pie!" }
let(:body) { "oh my glob Jake, Tree Trunks just made the tastiest apple pie ever!" }
let(:builder) { Email::MessageBuilder.new(to_address, subject: subject, body: body) }
let(:builder) { Email::MessageBuilder.new(to_address, subject: email_subject, body: body) }
let(:build_args) { builder.build_args }
let(:header_args) { builder.header_args }
let(:allow_reply_header) { described_class::ALLOW_REPLY_BY_EMAIL_HEADER }
@ -16,7 +16,7 @@ RSpec.describe Email::MessageBuilder do
end
it "has the subject" do
expect(builder.subject).to eq(subject)
expect(builder.subject).to eq(email_subject)
end
it "has the body" do

View File

@ -6,8 +6,8 @@ describe FinalDestination::SSRFDetector do
SiteSetting.blocked_ip_blocks = "13.134.89.0/24|73.234.19.0/30\n"
SiteSetting.allowed_internal_hosts = "awesomesauce.com\n|goodbye.net"
expect(subject.blocked_ip_blocks).to eq(%w[13.134.89.0/24 73.234.19.0/30])
expect(subject.allowed_internal_hosts).to eq(
expect(described_class.blocked_ip_blocks).to eq(%w[13.134.89.0/24 73.234.19.0/30])
expect(described_class.allowed_internal_hosts).to eq(
[
"test.localhost", # Discourse.base_url
"awesomesauce.com",
@ -20,8 +20,8 @@ describe FinalDestination::SSRFDetector do
SiteSetting.blocked_ip_blocks = "13.134.89.0/24\n73.234.19.0/30\n\n"
SiteSetting.allowed_internal_hosts = "awesomesauce.com\n\ngoodbye.net\n\n"
expect(subject.blocked_ip_blocks).to eq(%w[13.134.89.0/24 73.234.19.0/30])
expect(subject.allowed_internal_hosts).to eq(
expect(described_class.blocked_ip_blocks).to eq(%w[13.134.89.0/24 73.234.19.0/30])
expect(described_class.allowed_internal_hosts).to eq(
[
"test.localhost", # Discourse.base_url
"awesomesauce.com",
@ -32,90 +32,90 @@ describe FinalDestination::SSRFDetector do
it "ignores invalid IP blocks" do
SiteSetting.blocked_ip_blocks = "2001:abc:de::/48|notanip"
expect(subject.blocked_ip_blocks).to eq(%w[2001:abc:de::/48])
expect(described_class.blocked_ip_blocks).to eq(%w[2001:abc:de::/48])
end
end
describe ".ip_allowed?" do
it "returns false for blocked IPs" do
SiteSetting.blocked_ip_blocks = "98.0.0.0/8|78.13.47.0/24|9001:82f3::/32"
expect(subject.ip_allowed?("98.23.19.111")).to eq(false)
expect(subject.ip_allowed?("9001:82f3:8873::3")).to eq(false)
expect(described_class.ip_allowed?("98.23.19.111")).to eq(false)
expect(described_class.ip_allowed?("9001:82f3:8873::3")).to eq(false)
end
%w[0.0.0.0 10.0.0.0 127.0.0.0 172.31.100.31 255.255.255.255 ::1 ::].each do |internal_ip|
it "returns false for '#{internal_ip}'" do
expect(subject.ip_allowed?(internal_ip)).to eq(false)
expect(described_class.ip_allowed?(internal_ip)).to eq(false)
end
end
it "returns false for private IPv4-mapped IPv6 addresses" do
expect(subject.ip_allowed?("::ffff:172.31.100.31")).to eq(false)
expect(subject.ip_allowed?("::ffff:0.0.0.0")).to eq(false)
expect(described_class.ip_allowed?("::ffff:172.31.100.31")).to eq(false)
expect(described_class.ip_allowed?("::ffff:0.0.0.0")).to eq(false)
end
it "returns true for public IPv4-mapped IPv6 addresses" do
expect(subject.ip_allowed?("::ffff:52.52.167.244")).to eq(true)
expect(described_class.ip_allowed?("::ffff:52.52.167.244")).to eq(true)
end
end
describe ".host_bypasses_checks?" do
it "returns true for URLs when allowed_internal_hosts allows the host" do
SiteSetting.allowed_internal_hosts = "allowedhost1.com|allowedhost2.com"
expect(subject.host_bypasses_checks?("allowedhost1.com")).to eq(true)
expect(subject.host_bypasses_checks?("allowedhost2.com")).to eq(true)
expect(described_class.host_bypasses_checks?("allowedhost1.com")).to eq(true)
expect(described_class.host_bypasses_checks?("allowedhost2.com")).to eq(true)
end
it "returns false for other hosts" do
expect(subject.host_bypasses_checks?("otherhost.com")).to eq(false)
expect(described_class.host_bypasses_checks?("otherhost.com")).to eq(false)
end
it "returns true for the base uri" do
SiteSetting.force_hostname = "final-test.example.com"
expect(subject.host_bypasses_checks?("final-test.example.com")).to eq(true)
expect(described_class.host_bypasses_checks?("final-test.example.com")).to eq(true)
end
it "returns true for the S3 CDN url" do
SiteSetting.enable_s3_uploads = true
SiteSetting.s3_cdn_url = "https://s3.example.com"
expect(subject.host_bypasses_checks?("s3.example.com")).to eq(true)
expect(described_class.host_bypasses_checks?("s3.example.com")).to eq(true)
end
it "returns true for the CDN url" do
GlobalSetting.stubs(:cdn_url).returns("https://cdn.example.com/discourse")
expect(subject.host_bypasses_checks?("cdn.example.com")).to eq(true)
expect(described_class.host_bypasses_checks?("cdn.example.com")).to eq(true)
end
end
describe ".lookup_and_filter_ips" do
it "returns a fake response in tests" do
expect(subject.lookup_and_filter_ips("example.com")).to eq(["1.2.3.4"])
expect(described_class.lookup_and_filter_ips("example.com")).to eq(["1.2.3.4"])
end
it "correctly filters private and blocked IPs" do
SiteSetting.blocked_ip_blocks = "9.10.11.12/24"
subject.stubs(:lookup_ips).returns(%w[127.0.0.1 5.6.7.8 9.10.11.12])
expect(subject.lookup_and_filter_ips("example.com")).to eq(["5.6.7.8"])
described_class.stubs(:lookup_ips).returns(%w[127.0.0.1 5.6.7.8 9.10.11.12])
expect(described_class.lookup_and_filter_ips("example.com")).to eq(["5.6.7.8"])
end
it "raises an exception if all IPs are blocked" do
subject.stubs(:lookup_ips).returns(["127.0.0.1"])
expect { subject.lookup_and_filter_ips("example.com") }.to raise_error(
subject::DisallowedIpError,
described_class.stubs(:lookup_ips).returns(["127.0.0.1"])
expect { described_class.lookup_and_filter_ips("example.com") }.to raise_error(
described_class::DisallowedIpError,
)
end
it "raises an exception if lookup fails" do
subject.stubs(:lookup_ips).raises(SocketError)
expect { subject.lookup_and_filter_ips("example.com") }.to raise_error(
subject::LookupFailedError,
described_class.stubs(:lookup_ips).raises(SocketError)
expect { described_class.lookup_and_filter_ips("example.com") }.to raise_error(
described_class::LookupFailedError,
)
end
it "bypasses filtering for allowlisted hosts" do
SiteSetting.allowed_internal_hosts = "example.com"
subject.stubs(:lookup_ips).returns(["127.0.0.1"])
expect(subject.lookup_and_filter_ips("example.com")).to eq(["127.0.0.1"])
described_class.stubs(:lookup_ips).returns(["127.0.0.1"])
expect(described_class.lookup_and_filter_ips("example.com")).to eq(["127.0.0.1"])
end
end
end

View File

@ -39,14 +39,14 @@ RSpec.describe Imap::Sync do
describe "no previous sync" do
let(:from) { "john@free.fr" }
let(:subject) { "Testing email post" }
let(:email_subject) { "Testing email post" }
let(:message_id) { "#{SecureRandom.hex}@example.com" }
let(:email) do
EmailFabricator(
from: from,
to: group.email_username,
subject: subject,
subject: email_subject,
message_id: message_id,
)
end
@ -80,7 +80,7 @@ RSpec.describe Imap::Sync do
expect(group.imap_last_uid).to eq(100)
topic = Topic.last
expect(topic.title).to eq(subject)
expect(topic.title).to eq(email_subject)
expect(topic.user.email).to eq(from)
expect(topic.tags.pluck(:name)).to contain_exactly("seen", "important", "test-label")
@ -110,7 +110,7 @@ RSpec.describe Imap::Sync do
expect(group.imap_last_uid).to eq(100)
topic = Topic.last
expect(topic.title).to eq(subject)
expect(topic.title).to eq(email_subject)
expect(topic.user.email).to eq(from)
expect(topic.tags).to eq([])
end
@ -161,7 +161,7 @@ RSpec.describe Imap::Sync do
end
describe "previous sync" do
let(:subject) { "Testing email post" }
let(:email_subject) { "Testing email post" }
let(:first_from) { "john@free.fr" }
let(:first_message_id) { SecureRandom.hex }
@ -191,7 +191,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -203,7 +203,7 @@ RSpec.describe Imap::Sync do
}.by(1).and change { IncomingEmail.count }.by(1)
topic = Topic.last
expect(topic.title).to eq(subject)
expect(topic.title).to eq(email_subject)
expect(GroupArchivedMessage.where(topic_id: topic.id).exists?).to eq(false)
post = Post.where(post_type: Post.types[:regular]).last
@ -233,7 +233,7 @@ RSpec.describe Imap::Sync do
in_reply_to: first_message_id,
from: second_from,
to: group.email_username,
subject: "Re: #{subject}",
subject: "Re: #{email_subject}",
body: second_body,
),
},
@ -267,7 +267,7 @@ RSpec.describe Imap::Sync do
}.and not_change { IncomingEmail.count }
topic = Topic.last
expect(topic.title).to eq(subject)
expect(topic.title).to eq(email_subject)
expect(GroupArchivedMessage.where(topic_id: topic.id).exists?).to eq(true)
expect(Topic.last.posts.where(post_type: Post.types[:regular]).count).to eq(2)
@ -294,7 +294,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -389,7 +389,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -446,7 +446,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -494,7 +494,7 @@ RSpec.describe Imap::Sync do
end
describe "invalidated previous sync" do
let(:subject) { "Testing email post" }
let(:email_subject) { "Testing email post" }
let(:first_from) { "john@free.fr" }
let(:first_message_id) { SecureRandom.hex }
@ -526,7 +526,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -540,7 +540,7 @@ RSpec.describe Imap::Sync do
in_reply_to: first_message_id,
from: second_from,
to: group.email_username,
subject: "Re: #{subject}",
subject: "Re: #{email_subject}",
body: second_body,
),
},
@ -571,7 +571,7 @@ RSpec.describe Imap::Sync do
from: first_from,
to: group.email_username,
cc: second_from,
subject: subject,
subject: email_subject,
body: first_body,
),
},
@ -585,7 +585,7 @@ RSpec.describe Imap::Sync do
in_reply_to: first_message_id,
from: second_from,
to: group.email_username,
subject: "Re: #{subject}",
subject: "Re: #{email_subject}",
body: second_body,
),
},

View File

@ -5,18 +5,16 @@ RSpec.describe Email::MessageIdService do
fab!(:post) { Fabricate(:post, topic: topic) }
fab!(:second_post) { Fabricate(:post, topic: topic) }
subject { described_class }
describe "#generate_or_use_existing" do
it "does not override a post's existing outbound_message_id" do
post.update!(outbound_message_id: "blah@host.test")
result = subject.generate_or_use_existing(post.id)
result = described_class.generate_or_use_existing(post.id)
expect(result).to eq(["<blah@host.test>"])
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(["<discourse/post/#{post.id}@#{Email::MessageIdService.host}>"])
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

View File

@ -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("<iframe")
expect(subject.placeholder_html).to include("placeholder-icon map")
expect(onebox.url).to eq t[:expect]
expect(onebox.streetview?).to t[:streetview] ? be_truthy : be_falsey
expect(onebox.to_html).to include("<iframe")
expect(onebox.placeholder_html).to include("placeholder-icon map")
end
end
end

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
RSpec.describe Plugin::Instance do
subject(:plugin_instance) { described_class.new }
after { DiscoursePluginRegistry.reset! }
describe "find_all" do
@ -601,7 +603,7 @@ RSpec.describe Plugin::Instance do
highest_flag_id = ReviewableScore.types.values.max
flag_name = :new_flag
subject.replace_flags(settings: original_flags) do |settings, next_flag_id|
plugin_instance.replace_flags(settings: original_flags) do |settings, next_flag_id|
settings.add(next_flag_id, flag_name)
end
@ -613,7 +615,7 @@ RSpec.describe Plugin::Instance do
highest_flag_id = ReviewableScore.types.values.max
new_score_type = :new_score_type
subject.replace_flags(
plugin_instance.replace_flags(
settings: original_flags,
score_type_names: [new_score_type],
) { |settings, next_flag_id| settings.add(next_flag_id, :new_flag) }
@ -629,7 +631,7 @@ RSpec.describe Plugin::Instance do
it "adds a custom api key scope" do
actions = %w[admin/groups#create]
subject.add_api_key_scope(:groups, create: { actions: actions })
plugin_instance.add_api_key_scope(:groups, create: { actions: actions })
expect(ApiKeyScope.scope_mappings.dig(:groups, :create, :actions)).to contain_exactly(
*actions,

View File

@ -735,20 +735,20 @@ RSpec.describe PostDestroyer do
end
context "as an admin" do
subject { PostDestroyer.new(admin, post).destroy }
subject(:destroyer) { PostDestroyer.new(admin, post).destroy }
it "deletes the post" do
subject
destroyer
expect(post.deleted_at).to be_present
expect(post.deleted_by).to eq(admin)
end
it "creates a new user history entry" do
expect { subject }.to change { UserHistory.count }.by(1)
expect { destroyer }.to change { UserHistory.count }.by(1)
end
it "triggers a extensibility event" do
events = DiscourseEvent.track_events { subject }
events = DiscourseEvent.track_events { destroyer }
expect(events[0][:event_name]).to eq(:post_destroyed)
expect(events[0][:params].first).to eq(post)
@ -768,34 +768,34 @@ RSpec.describe PostDestroyer do
end
context "as a moderator" do
subject { PostDestroyer.new(moderator, reply).destroy }
subject(:destroyer) { PostDestroyer.new(moderator, reply).destroy }
it "deletes the reply" do
subject
destroyer
expect(reply.deleted_at).to be_present
expect(reply.deleted_by).to eq(moderator)
end
it "doesn't decrement post_count again" do
expect { subject }.to_not change { author.user_stat.post_count }
expect { destroyer }.to_not change { author.user_stat.post_count }
end
end
context "as an admin" do
subject { PostDestroyer.new(admin, reply).destroy }
subject(:destroyer) { PostDestroyer.new(admin, reply).destroy }
it "deletes the post" do
subject
destroyer
expect(reply.deleted_at).to be_present
expect(reply.deleted_by).to eq(admin)
end
it "doesn't decrement post_count again" do
expect { subject }.to_not change { author.user_stat.post_count }
expect { destroyer }.to_not change { author.user_stat.post_count }
end
it "creates a new user history entry" do
expect { subject }.to change { UserHistory.count }.by(1)
expect { destroyer }.to change { UserHistory.count }.by(1)
end
end
end

View File

@ -1,13 +1,13 @@
# frozen_string_literal: true
RSpec.describe PostJobsEnqueuer do
subject(:enqueuer) { described_class.new(post, topic, new_topic, opts) }
let!(:post) { Fabricate(:post, topic: topic) }
let!(:topic) { Fabricate(:topic) }
let(:new_topic) { false }
let(:opts) { { post_alert_options: {} } }
subject { described_class.new(post, topic, new_topic, opts) }
context "for regular topics" do
it "enqueues the :post_alert job" do
expect_enqueued_with(
@ -17,24 +17,24 @@ RSpec.describe PostJobsEnqueuer do
new_record: true,
options: opts[:post_alert_options],
},
) { subject.enqueue_jobs }
) { enqueuer.enqueue_jobs }
end
it "enqueues the :notify_mailing_list_subscribers job" do
expect_enqueued_with(job: :notify_mailing_list_subscribers, args: { post_id: post.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
it "enqueues the :post_update_topic_tracking_state job" do
expect_enqueued_with(job: :post_update_topic_tracking_state, args: { post_id: post.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
it "enqueues the :feature_topic_users job" do
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
@ -44,7 +44,7 @@ RSpec.describe PostJobsEnqueuer do
it "calls the correct topic tracking state class to publish_new" do
TopicTrackingState.expects(:publish_new).with(topic)
PrivateMessageTopicTrackingState.expects(:publish_new).never
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
end
@ -54,19 +54,19 @@ RSpec.describe PostJobsEnqueuer do
it "does not enqueue the :notify_mailing_list_subscribers job" do
expect_not_enqueued_with(job: :notify_mailing_list_subscribers, args: { post_id: post.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
it "enqueues the :post_update_topic_tracking_state job" do
expect_enqueued_with(job: :post_update_topic_tracking_state, args: { post_id: post.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
it "enqueues the :feature_topic_users job" do
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
@ -76,7 +76,7 @@ RSpec.describe PostJobsEnqueuer do
it "calls the correct topic tracking state class to publish_new" do
TopicTrackingState.expects(:publish_new).never
PrivateMessageTopicTrackingState.expects(:publish_new).with(topic)
subject.enqueue_jobs
enqueuer.enqueue_jobs
end
end
@ -99,7 +99,7 @@ RSpec.describe PostJobsEnqueuer do
args: {
topic_id: topic.id,
},
) { subject.enqueue_jobs }
) { enqueuer.enqueue_jobs }
end
end
end

View File

@ -197,9 +197,9 @@ RSpec.describe PostRevisor do
end
describe "editing tags" do
fab!(:post) { Fabricate(:post) }
subject(:post_revisor) { PostRevisor.new(post) }
subject { PostRevisor.new(post) }
fab!(:post) { Fabricate(:post) }
before do
Jobs.run_immediately!
@ -212,19 +212,21 @@ RSpec.describe PostRevisor do
end
it "creates notifications" do
expect { subject.revise!(admin, tags: ["new-tag"]) }.to change { Notification.count }.by(1)
expect { post_revisor.revise!(admin, tags: ["new-tag"]) }.to change { Notification.count }.by(
1,
)
end
it "skips notifications if disable_tags_edit_notifications" do
SiteSetting.disable_tags_edit_notifications = true
expect { subject.revise!(admin, tags: ["new-tag"]) }.not_to change { Notification.count }
expect { post_revisor.revise!(admin, tags: ["new-tag"]) }.not_to change { Notification.count }
end
it "doesn't create a small_action post when create_post_for_category_and_tag_changes is false" do
SiteSetting.create_post_for_category_and_tag_changes = false
expect { subject.revise!(admin, tags: ["new-tag"]) }.not_to change { Post.count }
expect { post_revisor.revise!(admin, tags: ["new-tag"]) }.not_to change { Post.count }
end
describe "when `create_post_for_category_and_tag_changes` site setting is enabled" do
@ -236,7 +238,7 @@ RSpec.describe PostRevisor do
it "Creates a small_action post with correct translation when both adding and removing tags" do
post.topic.update!(tags: [tag1])
expect { subject.revise!(admin, tags: [tag2.name]) }.to change {
expect { post_revisor.revise!(admin, tags: [tag2.name]) }.to change {
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
}.by(1)
@ -252,7 +254,7 @@ RSpec.describe PostRevisor do
it "Creates a small_action post with correct translation when adding tags" do
post.topic.update!(tags: [])
expect { subject.revise!(admin, tags: [tag1.name]) }.to change {
expect { post_revisor.revise!(admin, tags: [tag1.name]) }.to change {
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
}.by(1)
@ -264,7 +266,7 @@ RSpec.describe PostRevisor do
it "Creates a small_action post with correct translation when removing tags" do
post.topic.update!(tags: [tag1, tag2])
expect { subject.revise!(admin, tags: []) }.to change {
expect { post_revisor.revise!(admin, tags: []) }.to change {
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
}.by(1)
@ -277,7 +279,7 @@ RSpec.describe PostRevisor do
current_category = post.topic.category
category = Fabricate(:category)
expect { subject.revise!(admin, category_id: category.id) }.to change {
expect { post_revisor.revise!(admin, category_id: category.id) }.to change {
Post.where(topic_id: post.topic_id, action_code: "category_changed").count
}.by(1)
@ -310,24 +312,24 @@ RSpec.describe PostRevisor do
end
describe "revise" do
subject(:post_revisor) { PostRevisor.new(post) }
let(:post) { Fabricate(:post, post_args) }
let(:first_version_at) { post.last_version_at }
subject { PostRevisor.new(post) }
it "destroys last revision if edit is undone" do
old_raw = post.raw
subject.revise!(admin, raw: "new post body", tags: ["new-tag"])
post_revisor.revise!(admin, raw: "new post body", tags: ["new-tag"])
expect(post.topic.reload.tags.map(&:name)).to contain_exactly("new-tag")
expect(post.post_revisions.reload.size).to eq(1)
expect(subject.raw_changed?).to eq(true)
expect(post_revisor.raw_changed?).to eq(true)
subject.revise!(admin, raw: old_raw, tags: [])
post_revisor.revise!(admin, raw: old_raw, tags: [])
expect(post.topic.reload.tags.map(&:name)).to be_empty
expect(post.post_revisions.reload.size).to eq(0)
subject.revise!(admin, raw: "next post body", tags: ["new-tag"])
post_revisor.revise!(admin, raw: "next post body", tags: ["new-tag"])
expect(post.topic.reload.tags.map(&:name)).to contain_exactly("new-tag")
expect(post.post_revisions.reload.size).to eq(1)
end
@ -335,7 +337,7 @@ RSpec.describe PostRevisor do
describe "with the same body" do
it "doesn't change version" do
expect {
expect(subject.revise!(post.user, raw: post.raw)).to eq(false)
expect(post_revisor.revise!(post.user, raw: post.raw)).to eq(false)
post.reload
}.not_to change(post, :version)
end
@ -344,7 +346,7 @@ RSpec.describe PostRevisor do
describe "with nil raw contents" do
it "doesn't change version" do
expect {
expect(subject.revise!(post.user, raw: nil)).to eq(false)
expect(post_revisor.revise!(post.user, raw: nil)).to eq(false)
post.reload
}.not_to change(post, :version)
end
@ -354,7 +356,7 @@ RSpec.describe PostRevisor do
before { topic.update!(slow_mode_seconds: 1000) }
it "regular edits are not allowed by default" do
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + 1000.minutes,
@ -368,7 +370,7 @@ RSpec.describe PostRevisor do
it "grace period editing is allowed" do
SiteSetting.editing_grace_period = 1.minute
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + 10.seconds,
@ -381,7 +383,7 @@ RSpec.describe PostRevisor do
it "regular edits are allowed if it was turned on in settings" do
SiteSetting.slow_mode_prevents_editing = false
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + 10.minutes,
@ -393,7 +395,11 @@ RSpec.describe PostRevisor do
it "staff is allowed to edit posts even if the topic is in slow mode" do
admin = Fabricate(:admin)
subject.revise!(admin, { raw: "updated body" }, revised_at: post.updated_at + 10.minutes)
post_revisor.revise!(
admin,
{ raw: "updated body" },
revised_at: post.updated_at + 10.minutes,
)
post.reload
expect(post.errors).to be_empty
@ -404,7 +410,7 @@ RSpec.describe PostRevisor do
it "correctly applies edits" do
SiteSetting.editing_grace_period = 1.minute
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + 10.seconds,
@ -415,7 +421,7 @@ RSpec.describe PostRevisor do
expect(post.public_version).to eq(1)
expect(post.revisions.size).to eq(0)
expect(post.last_version_at).to eq_time(first_version_at)
expect(subject.category_changed).to be_blank
expect(post_revisor.category_changed).to be_blank
end
it "does create a new version if a large diff happens" do
@ -486,13 +492,13 @@ RSpec.describe PostRevisor do
SiteSetting.editing_grace_period_max_diff = 100
# making a revision
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
)
# "roll back"
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "Hello world" },
revised_at: post.updated_at + SiteSetting.editing_grace_period + 2.seconds,
@ -507,7 +513,7 @@ RSpec.describe PostRevisor do
it "should bump the topic" do
expect {
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
@ -520,7 +526,7 @@ RSpec.describe PostRevisor do
post_from_topic_with_no_category = Fabricate(:post, topic: topic_with_no_category)
expect {
result =
subject.revise!(
post_revisor.revise!(
Fabricate(:admin),
raw: post_from_topic_with_no_category.raw,
tags: ["foo"],
@ -533,7 +539,7 @@ RSpec.describe PostRevisor do
TopicUser.create!(topic: post.topic, user: post.user, notification_level: 0)
messages =
MessageBus.track_publish("/latest") do
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "updated body" },
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
@ -632,12 +638,12 @@ RSpec.describe PostRevisor do
before do
SiteSetting.editing_grace_period = 1.minute
subject.revise!(post.user, { raw: "updated body" }, revised_at: revised_at)
post_revisor.revise!(post.user, { raw: "updated body" }, revised_at: revised_at)
post.reload
end
it "doesn't update a category" do
expect(subject.category_changed).to be_blank
expect(post_revisor.category_changed).to be_blank
end
it "updates the versions" do
@ -655,7 +661,11 @@ RSpec.describe PostRevisor do
describe "new edit window" do
before do
subject.revise!(post.user, { raw: "yet another updated body" }, revised_at: revised_at)
post_revisor.revise!(
post.user,
{ raw: "yet another updated body" },
revised_at: revised_at,
)
post.reload
end
@ -669,14 +679,14 @@ RSpec.describe PostRevisor do
end
it "doesn't update a category" do
expect(subject.category_changed).to be_blank
expect(post_revisor.category_changed).to be_blank
end
context "after second window" do
let!(:new_revised_at) { revised_at + 2.minutes }
before do
subject.revise!(
post_revisor.revise!(
post.user,
{ raw: "yet another, another updated body" },
revised_at: new_revised_at,
@ -711,12 +721,12 @@ RSpec.describe PostRevisor do
context "with one paragraph description" do
before do
subject.revise!(post.user, raw: new_description)
post_revisor.revise!(post.user, raw: new_description)
category.reload
end
it "returns the changed category info" do
expect(subject.category_changed).to eq(category)
expect(post_revisor.category_changed).to eq(category)
end
it "updates the description of the category" do
@ -726,12 +736,12 @@ RSpec.describe PostRevisor do
context "with multiple paragraph description" do
before do
subject.revise!(post.user, raw: "#{new_description}\n\nOther content goes here.")
post_revisor.revise!(post.user, raw: "#{new_description}\n\nOther content goes here.")
category.reload
end
it "returns the changed category info" do
expect(subject.category_changed).to eq(category)
expect(post_revisor.category_changed).to eq(category)
end
it "updates the description of the category" do
@ -741,7 +751,7 @@ RSpec.describe PostRevisor do
context "with invalid description without paragraphs" do
before do
subject.revise!(post.user, raw: "# This is a title")
post_revisor.revise!(post.user, raw: "# This is a title")
category.reload
end
@ -760,7 +770,7 @@ RSpec.describe PostRevisor do
context "when updating back to the original paragraph" do
before do
category.update_column(:description, "this is my description")
subject.revise!(post.user, raw: Category.post_template)
post_revisor.revise!(post.user, raw: Category.post_template)
category.reload
end
@ -769,7 +779,7 @@ RSpec.describe PostRevisor do
end
it "returns the changed category info" do
expect(subject.category_changed).to eq(category)
expect(post_revisor.category_changed).to eq(category)
end
end
end
@ -786,16 +796,16 @@ RSpec.describe PostRevisor do
it "triggers a rate limiter" do
EditRateLimiter.any_instance.expects(:performed!)
subject.revise!(changed_by, raw: "updated body")
post_revisor.revise!(changed_by, raw: "updated body")
end
it "raises error when a user gets rate limited" do
SiteSetting.max_edits_per_day = 1
user = Fabricate(:user, trust_level: 1)
subject.revise!(user, raw: "body (edited)")
post_revisor.revise!(user, raw: "body (edited)")
expect do subject.revise!(user, raw: "body (edited twice) ") end.to raise_error(
expect do post_revisor.revise!(user, raw: "body (edited twice) ") end.to raise_error(
RateLimiter::LimitExceeded,
)
end
@ -807,26 +817,26 @@ RSpec.describe PostRevisor do
SiteSetting.tl4_additional_edits_per_day_multiplier = 4
user = Fabricate(:user, trust_level: 2)
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect do subject.revise!(user, raw: "body (edited three times) ") end.to raise_error(
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect do post_revisor.revise!(user, raw: "body (edited three times) ") end.to raise_error(
RateLimiter::LimitExceeded,
)
user = Fabricate(:user, trust_level: 3)
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited three times)") }.to_not raise_error
expect do subject.revise!(user, raw: "body (edited four times) ") end.to raise_error(
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited three times)") }.to_not raise_error
expect do post_revisor.revise!(user, raw: "body (edited four times) ") end.to raise_error(
RateLimiter::LimitExceeded,
)
user = Fabricate(:user, trust_level: 4)
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited three times)") }.to_not raise_error
expect { subject.revise!(user, raw: "body (edited four times)") }.to_not raise_error
expect do subject.revise!(user, raw: "body (edited five times) ") end.to raise_error(
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited twice)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited three times)") }.to_not raise_error
expect { post_revisor.revise!(user, raw: "body (edited four times)") }.to_not raise_error
expect do post_revisor.revise!(user, raw: "body (edited five times) ") end.to raise_error(
RateLimiter::LimitExceeded,
)
end
@ -839,7 +849,7 @@ RSpec.describe PostRevisor do
SiteSetting.newuser_max_embedded_media = 0
url = "http://i.imgur.com/wfn7rgU.jpg"
Oneboxer.stubs(:onebox).with(url, anything).returns("<img src='#{url}'>")
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("<img src='#{url}'>")
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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?",

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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"),
)

View File

@ -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

View File

@ -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"')

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More