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:
parent
8e1d049e6b
commit
0f4beab0fb
|
@ -191,6 +191,7 @@ GEM
|
||||||
simpleidn (~> 0.2)
|
simpleidn (~> 0.2)
|
||||||
jwt (2.7.1)
|
jwt (2.7.1)
|
||||||
kgio (2.11.4)
|
kgio (2.11.4)
|
||||||
|
language_server-protocol (3.17.0.3)
|
||||||
libv8-node (18.16.0.0)
|
libv8-node (18.16.0.0)
|
||||||
libv8-node (18.16.0.0-aarch64-linux)
|
libv8-node (18.16.0.0-aarch64-linux)
|
||||||
libv8-node (18.16.0.0-arm64-darwin)
|
libv8-node (18.16.0.0-arm64-darwin)
|
||||||
|
@ -409,8 +410,9 @@ GEM
|
||||||
rspec-core (>= 2.14)
|
rspec-core (>= 2.14)
|
||||||
rtlcss (0.2.1)
|
rtlcss (0.2.1)
|
||||||
mini_racer (>= 0.6.3)
|
mini_racer (>= 0.6.3)
|
||||||
rubocop (1.52.1)
|
rubocop (1.53.0)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.2.2.3)
|
parser (>= 3.2.2.3)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
|
@ -423,7 +425,7 @@ GEM
|
||||||
parser (>= 3.2.1.0)
|
parser (>= 3.2.1.0)
|
||||||
rubocop-capybara (2.18.0)
|
rubocop-capybara (2.18.0)
|
||||||
rubocop (~> 1.41)
|
rubocop (~> 1.41)
|
||||||
rubocop-discourse (3.2.0)
|
rubocop-discourse (3.3.0)
|
||||||
rubocop (>= 1.1.0)
|
rubocop (>= 1.1.0)
|
||||||
rubocop-rspec (>= 2.0.0)
|
rubocop-rspec (>= 2.0.0)
|
||||||
rubocop-factory_bot (2.23.1)
|
rubocop-factory_bot (2.23.1)
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Jobs::Chat::AutoJoinChannelBatch do
|
describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
describe "#execute" do
|
describe "#execute" do
|
||||||
fab!(:category) { Fabricate(:category) }
|
fab!(:category) { Fabricate(:category) }
|
||||||
let!(:user) { Fabricate(:user, last_seen_at: 15.minutes.ago) }
|
let!(:user) { Fabricate(:user, last_seen_at: 15.minutes.ago) }
|
||||||
let(:channel) { Fabricate(:chat_channel, auto_join_users: true, chatable: category) }
|
let(:channel) { Fabricate(:chat_channel, auto_join_users: true, chatable: category) }
|
||||||
|
|
||||||
it "joins all valid users in the batch" do
|
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])
|
assert_users_follows_channel(channel, [user])
|
||||||
end
|
end
|
||||||
|
@ -17,7 +19,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "doesn't join users outside the batch" do
|
it "doesn't join users outside the batch" do
|
||||||
another_user = Fabricate(:user, last_seen_at: 15.minutes.ago)
|
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_users_follows_channel(channel, [user])
|
||||||
assert_user_skipped(channel, another_user)
|
assert_user_skipped(channel, another_user)
|
||||||
|
@ -26,7 +28,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "doesn't join suspended users" do
|
it "doesn't join suspended users" do
|
||||||
user.update!(suspended_till: 1.year.from_now)
|
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)
|
assert_user_skipped(channel, user)
|
||||||
end
|
end
|
||||||
|
@ -34,7 +36,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "doesn't join users last_seen more than 3 months ago" do
|
it "doesn't join users last_seen more than 3 months ago" do
|
||||||
user.update!(last_seen_at: 4.months.ago)
|
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)
|
assert_user_skipped(channel, user)
|
||||||
end
|
end
|
||||||
|
@ -42,13 +44,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "joins users with last_seen set to null" do
|
it "joins users with last_seen set to null" do
|
||||||
user.update!(last_seen_at: nil)
|
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])
|
assert_users_follows_channel(channel, [user])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does nothing if the channel is invalid" do
|
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)
|
assert_user_skipped(channel, user)
|
||||||
end
|
end
|
||||||
|
@ -57,13 +59,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
direct_message = Fabricate(:direct_message)
|
direct_message = Fabricate(:direct_message)
|
||||||
channel.update!(chatable: 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)
|
assert_user_skipped(channel, user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the user count update job and marks the channel user count as stale" do
|
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(
|
expect_job_enqueued(
|
||||||
job: Jobs::Chat::UpdateChannelUserCount,
|
job: Jobs::Chat::UpdateChannelUserCount,
|
||||||
args: {
|
args: {
|
||||||
|
@ -81,7 +83,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
args: {
|
args: {
|
||||||
chat_channel_id: channel.id,
|
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)
|
expect(channel.reload.user_count_stale).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -89,13 +91,13 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "ignores users without chat_enabled" do
|
it "ignores users without chat_enabled" do
|
||||||
user.user_option.update!(chat_enabled: false)
|
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)
|
assert_user_skipped(channel, user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets the join reason to automatic" do
|
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)
|
new_membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel)
|
||||||
expect(new_membership.automatic?).to eq(true)
|
expect(new_membership.automatic?).to eq(true)
|
||||||
|
@ -104,7 +106,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "skips anonymous users" do
|
it "skips anonymous users" do
|
||||||
user_2 = Fabricate(:anonymous)
|
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_users_follows_channel(channel, [user])
|
||||||
assert_user_skipped(channel, user_2)
|
assert_user_skipped(channel, user_2)
|
||||||
|
@ -113,7 +115,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "skips non-active users" do
|
it "skips non-active users" do
|
||||||
user_2 = Fabricate(:user, active: false, last_seen_at: 15.minutes.ago)
|
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_users_follows_channel(channel, [user])
|
||||||
assert_user_skipped(channel, user_2)
|
assert_user_skipped(channel, user_2)
|
||||||
|
@ -122,7 +124,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "skips staged users" do
|
it "skips staged users" do
|
||||||
user_2 = Fabricate(:user, staged: true, last_seen_at: 15.minutes.ago)
|
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_users_follows_channel(channel, [user])
|
||||||
assert_user_skipped(channel, user_2)
|
assert_user_skipped(channel, user_2)
|
||||||
|
@ -131,7 +133,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "adds every user in the batch" do
|
it "adds every user in the batch" do
|
||||||
user_2 = Fabricate(:user, last_seen_at: 15.minutes.ago)
|
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])
|
assert_users_follows_channel(channel, [user, user_2])
|
||||||
end
|
end
|
||||||
|
@ -139,7 +141,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
it "publishes a message only to joined users" do
|
it "publishes a message only to joined users" do
|
||||||
messages =
|
messages =
|
||||||
MessageBus.track_publish("/chat/new-channel") do
|
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
|
end
|
||||||
|
|
||||||
expect(messages.size).to eq(1)
|
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
|
it "only joins group members with access to the category" do
|
||||||
another_user = Fabricate(:user, last_seen_at: 15.minutes.ago)
|
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_users_follows_channel(channel, [user])
|
||||||
assert_user_skipped(channel, another_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)
|
Fabricate(:category_group, category: category, group: second_chatters_group)
|
||||||
second_chatters_group.add(user)
|
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])
|
assert_users_follows_channel(channel, [user])
|
||||||
end
|
end
|
||||||
|
@ -176,7 +178,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
another_user = Fabricate(:user, last_seen_at: 15.minutes.ago)
|
another_user = Fabricate(:user, last_seen_at: 15.minutes.ago)
|
||||||
chatters_group.add(another_user)
|
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])
|
assert_users_follows_channel(channel, [user, another_user])
|
||||||
end
|
end
|
||||||
|
@ -195,7 +197,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
)
|
)
|
||||||
non_chatters_group.add(another_user)
|
non_chatters_group.add(another_user)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_channel_id: readonly_channel.id,
|
chat_channel_id: readonly_channel.id,
|
||||||
starts_at: another_user.id,
|
starts_at: another_user.id,
|
||||||
ends_at: another_user.id,
|
ends_at: another_user.id,
|
||||||
|
@ -227,7 +229,7 @@ describe Jobs::Chat::AutoJoinChannelBatch do
|
||||||
)
|
)
|
||||||
other_group.add(another_user)
|
other_group.add(another_user)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_channel_id: private_channel.id,
|
chat_channel_id: private_channel.id,
|
||||||
starts_at: another_user.id,
|
starts_at: another_user.id,
|
||||||
ends_at: another_user.id,
|
ends_at: another_user.id,
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
RSpec.describe Jobs::Chat::DeleteUserMessages do
|
RSpec.describe Jobs::Chat::DeleteUserMessages do
|
||||||
describe "#execute" do
|
describe "#execute" do
|
||||||
|
subject(:execute) { described_class.new.execute(user_id: user_1) }
|
||||||
|
|
||||||
fab!(:user_1) { Fabricate(:user) }
|
fab!(:user_1) { Fabricate(:user) }
|
||||||
fab!(:channel) { Fabricate(:chat_channel) }
|
fab!(:channel) { Fabricate(:chat_channel) }
|
||||||
fab!(:chat_message) { Fabricate(:chat_message, chat_channel: channel, user: user_1) }
|
fab!(:chat_message) { Fabricate(:chat_message, chat_channel: channel, user: user_1) }
|
||||||
|
|
||||||
it "deletes messages from the user" do
|
it "deletes messages from the user" do
|
||||||
subject.execute(user_id: user_1)
|
execute
|
||||||
|
|
||||||
expect { chat_message.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
expect { chat_message.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
|
@ -16,7 +18,7 @@ RSpec.describe Jobs::Chat::DeleteUserMessages do
|
||||||
user_2 = Fabricate(:user)
|
user_2 = Fabricate(:user)
|
||||||
user_2_message = Fabricate(:chat_message, chat_channel: channel, user: user_2)
|
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
|
expect(user_2_message.reload).to be_present
|
||||||
end
|
end
|
||||||
|
@ -24,7 +26,7 @@ RSpec.describe Jobs::Chat::DeleteUserMessages do
|
||||||
it "deletes trashed messages" do
|
it "deletes trashed messages" do
|
||||||
chat_message.trash!
|
chat_message.trash!
|
||||||
|
|
||||||
subject.execute(user_id: user_1)
|
execute
|
||||||
|
|
||||||
expect(Chat::Message.with_deleted.where(id: chat_message.id)).to be_empty
|
expect(Chat::Message.with_deleted.where(id: chat_message.id)).to be_empty
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Jobs::Chat::NotifyMentioned do
|
describe Jobs::Chat::NotifyMentioned do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:user_1) { Fabricate(:user) }
|
fab!(:user_1) { Fabricate(:user) }
|
||||||
fab!(:user_2) { Fabricate(:user) }
|
fab!(:user_2) { Fabricate(:user) }
|
||||||
fab!(:public_channel) { Fabricate(:category_channel) }
|
fab!(:public_channel) { Fabricate(:category_channel) }
|
||||||
|
@ -47,7 +49,7 @@ describe Jobs::Chat::NotifyMentioned do
|
||||||
)
|
)
|
||||||
MessageBus
|
MessageBus
|
||||||
.track_publish("/chat/notification-alert/#{user.id}") do
|
.track_publish("/chat/notification-alert/#{user.id}") do
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_message_id: message.id,
|
chat_message_id: message.id,
|
||||||
timestamp: message.created_at,
|
timestamp: message.created_at,
|
||||||
to_notify_ids_map: to_notify_ids_map,
|
to_notify_ids_map: to_notify_ids_map,
|
||||||
|
@ -58,7 +60,7 @@ describe Jobs::Chat::NotifyMentioned do
|
||||||
end
|
end
|
||||||
|
|
||||||
def track_core_notification(user: user_2, message:, to_notify_ids_map:)
|
def track_core_notification(user: user_2, message:, to_notify_ids_map:)
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_message_id: message.id,
|
chat_message_id: message.id,
|
||||||
timestamp: message.created_at,
|
timestamp: message.created_at,
|
||||||
to_notify_ids_map: to_notify_ids_map,
|
to_notify_ids_map: to_notify_ids_map,
|
||||||
|
@ -175,7 +177,7 @@ describe Jobs::Chat::NotifyMentioned do
|
||||||
|
|
||||||
PostAlerter.expects(:push_notification).never
|
PostAlerter.expects(:push_notification).never
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_message_id: message.id,
|
chat_message_id: message.id,
|
||||||
timestamp: message.created_at,
|
timestamp: message.created_at,
|
||||||
to_notify_ids_map: to_notify_ids_map,
|
to_notify_ids_map: to_notify_ids_map,
|
||||||
|
@ -204,7 +206,7 @@ describe Jobs::Chat::NotifyMentioned do
|
||||||
|
|
||||||
PostAlerter.expects(:push_notification).never
|
PostAlerter.expects(:push_notification).never
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
chat_message_id: message.id,
|
chat_message_id: message.id,
|
||||||
timestamp: message.created_at,
|
timestamp: message.created_at,
|
||||||
to_notify_ids_map: to_notify_ids_map,
|
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,
|
chat_message_id: message.id,
|
||||||
timestamp: message.created_at,
|
timestamp: message.created_at,
|
||||||
to_notify_ids_map: to_notify_ids_map,
|
to_notify_ids_map: to_notify_ids_map,
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::Chat::SendMessageNotifications do
|
RSpec.describe Jobs::Chat::SendMessageNotifications do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
describe "#execute" do
|
describe "#execute" do
|
||||||
context "when the message doesn't exist" do
|
context "when the message doesn't exist" do
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
Chat::Notifier.any_instance.expects(:notify_new).never
|
Chat::Notifier.any_instance.expects(:notify_new).never
|
||||||
Chat::Notifier.any_instance.expects(:notify_edit).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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -18,32 +20,28 @@ RSpec.describe Jobs::Chat::SendMessageNotifications do
|
||||||
Chat::Notifier.expects(:notify_new).never
|
Chat::Notifier.expects(:notify_new).never
|
||||||
Chat::Notifier.expects(:notify_edit).never
|
Chat::Notifier.expects(:notify_edit).never
|
||||||
|
|
||||||
subject.execute(
|
job.execute(chat_message_id: chat_message.id, reason: "invalid", timestamp: 1.minute.ago)
|
||||||
chat_message_id: chat_message.id,
|
|
||||||
reason: "invalid",
|
|
||||||
timestamp: 1.minute.ago,
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does nothing if there is no timestamp" do
|
it "does nothing if there is no timestamp" do
|
||||||
Chat::Notifier.any_instance.expects(:notify_new).never
|
Chat::Notifier.any_instance.expects(:notify_new).never
|
||||||
Chat::Notifier.any_instance.expects(:notify_edit).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
|
end
|
||||||
|
|
||||||
it "calls notify_new when the reason is 'new'" do
|
it "calls notify_new when the reason is 'new'" do
|
||||||
Chat::Notifier.any_instance.expects(:notify_new).once
|
Chat::Notifier.any_instance.expects(:notify_new).once
|
||||||
Chat::Notifier.any_instance.expects(:notify_edit).never
|
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
|
end
|
||||||
|
|
||||||
it "calls notify_edit when the reason is 'edit'" do
|
it "calls notify_edit when the reason is 'edit'" do
|
||||||
Chat::Notifier.any_instance.expects(:notify_new).never
|
Chat::Notifier.any_instance.expects(:notify_new).never
|
||||||
Chat::Notifier.any_instance.expects(:notify_edit).once
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Jobs::Chat::AutoJoinUsers do
|
describe Jobs::Chat::AutoJoinUsers do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
Jobs.run_immediately!
|
Jobs.run_immediately!
|
||||||
channel = Fabricate(:category_channel, auto_join_users: true)
|
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)
|
membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel)
|
||||||
expect(membership).to be_nil
|
expect(membership).to be_nil
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel)
|
membership = Chat::UserChatChannelMembership.find_by(user: user, chat_channel: channel)
|
||||||
expect(membership.following).to eq(true)
|
expect(membership.following).to eq(true)
|
||||||
|
|
|
@ -9,8 +9,8 @@ describe Chat::ChannelArchiveService do
|
||||||
fab!(:channel) { Fabricate(:category_channel) }
|
fab!(:channel) { Fabricate(:category_channel) }
|
||||||
fab!(:user) { Fabricate(:user, admin: true) }
|
fab!(:user) { Fabricate(:user, admin: true) }
|
||||||
fab!(:category) { Fabricate(:category) }
|
fab!(:category) { Fabricate(:category) }
|
||||||
|
|
||||||
let(:topic_params) { { topic_title: "This will be a new topic", category_id: category.id } }
|
let(:topic_params) { { topic_title: "This will be a new topic", category_id: category.id } }
|
||||||
subject { Chat::ChannelArchiveService }
|
|
||||||
|
|
||||||
before { SiteSetting.chat_enabled = true }
|
before { SiteSetting.chat_enabled = true }
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ describe Chat::ChannelArchiveService do
|
||||||
before { 3.times { Fabricate(:chat_message, chat_channel: channel) } }
|
before { 3.times { Fabricate(:chat_message, chat_channel: channel) } }
|
||||||
|
|
||||||
it "marks the channel as read_only" do
|
it "marks the channel as read_only" do
|
||||||
subject.create_archive_process(
|
described_class.create_archive_process(
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -27,7 +27,7 @@ describe Chat::ChannelArchiveService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates the chat channel archive record to save progress and topic params" do
|
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,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -42,7 +42,7 @@ describe Chat::ChannelArchiveService do
|
||||||
|
|
||||||
it "enqueues the archive job" do
|
it "enqueues the archive job" do
|
||||||
channel_archive =
|
channel_archive =
|
||||||
subject.create_archive_process(
|
described_class.create_archive_process(
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -58,13 +58,13 @@ describe Chat::ChannelArchiveService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does nothing if there is already an archive record for the channel" do
|
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,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
)
|
)
|
||||||
expect {
|
expect {
|
||||||
subject.create_archive_process(
|
described_class.create_archive_process(
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -76,7 +76,7 @@ describe Chat::ChannelArchiveService do
|
||||||
new_message = Fabricate(:chat_message, chat_channel: channel)
|
new_message = Fabricate(:chat_message, chat_channel: channel)
|
||||||
new_message.trash!
|
new_message.trash!
|
||||||
channel_archive =
|
channel_archive =
|
||||||
subject.create_archive_process(
|
described_class.create_archive_process(
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -92,7 +92,7 @@ describe Chat::ChannelArchiveService do
|
||||||
|
|
||||||
def start_archive
|
def start_archive
|
||||||
@channel_archive =
|
@channel_archive =
|
||||||
subject.create_archive_process(
|
described_class.create_archive_process(
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
acting_user: user,
|
acting_user: user,
|
||||||
topic_params: topic_params,
|
topic_params: topic_params,
|
||||||
|
@ -113,7 +113,7 @@ describe Chat::ChannelArchiveService do
|
||||||
emoji: "+1",
|
emoji: "+1",
|
||||||
)
|
)
|
||||||
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
end
|
end
|
||||||
|
|
||||||
@channel_archive.reload
|
@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
|
it "does not stop the process if the post length is too high (validations disabled)" do
|
||||||
create_messages(50) && start_archive
|
create_messages(50) && start_archive
|
||||||
SiteSetting.max_post_length = 1
|
SiteSetting.max_post_length = 1
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
expect(@channel_archive.reload.complete?).to eq(true)
|
expect(@channel_archive.reload.complete?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "successfully links uploads from messages to the post" do
|
it "successfully links uploads from messages to the post" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
UploadReference.create!(target: Chat::Message.last, upload: Fabricate(:upload))
|
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.reload.complete?).to eq(true)
|
||||||
expect(@channel_archive.destination_topic.posts.last.upload_references.count).to eq(1)
|
expect(@channel_archive.destination_topic.posts.last.upload_references.count).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "successfully sends a private message to the archiving user" do
|
it "successfully sends a private message to the archiving user" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
expect(@channel_archive.reload.complete?).to eq(true)
|
expect(@channel_archive.reload.complete?).to eq(true)
|
||||||
pm_topic = Topic.private_messages.last
|
pm_topic = Topic.private_messages.last
|
||||||
expect(pm_topic.topic_allowed_users.first.user).to eq(@channel_archive.archived_by)
|
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
|
create_messages(3) && start_archive
|
||||||
@channel_archive.update!(destination_topic_title: "Wow this is the new title :tada: :joy:")
|
@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.complete?).to eq(false)
|
||||||
expect(@channel_archive.reload.failed?).to eq(true)
|
expect(@channel_archive.reload.failed?).to eq(true)
|
||||||
expect(@channel_archive.archive_error).to eq("Title can't have more than 1 emoji")
|
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
|
it "uses the channel slug to autolink a hashtag for the channel in the PM" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
expect(@channel_archive.reload.complete?).to eq(true)
|
expect(@channel_archive.reload.complete?).to eq(true)
|
||||||
pm_topic = Topic.private_messages.last
|
pm_topic = Topic.private_messages.last
|
||||||
expect(pm_topic.first_post.cooked).to have_tag(
|
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,
|
Chat::UserChatChannelMembership.where(chat_channel: channel, following: true).count,
|
||||||
).to eq(3)
|
).to eq(3)
|
||||||
start_archive
|
start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
expect(@channel_archive.reload.complete?).to eq(true)
|
expect(@channel_archive.reload.complete?).to eq(true)
|
||||||
expect(
|
expect(
|
||||||
Chat::UserChatChannelMembership.where(chat_channel: channel, following: true).count,
|
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,
|
last_read_message_id: channel.chat_messages.first.id,
|
||||||
)
|
)
|
||||||
start_archive
|
start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
expect(@channel_archive.reload.complete?).to eq(true)
|
expect(@channel_archive.reload.complete?).to eq(true)
|
||||||
expect(Chat::UserChatChannelMembership.last.last_read_message_id).to eq(
|
expect(Chat::UserChatChannelMembership.last.last_read_message_id).to eq(
|
||||||
channel.chat_messages.last.id,
|
channel.chat_messages.last.id,
|
||||||
|
@ -257,7 +257,7 @@ describe Chat::ChannelArchiveService do
|
||||||
|
|
||||||
it "archives the topic" do
|
it "archives the topic" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
topic = @channel_archive.destination_topic
|
topic = @channel_archive.destination_topic
|
||||||
topic.reload
|
topic.reload
|
||||||
expect(topic.archived).to eq(true)
|
expect(topic.archived).to eq(true)
|
||||||
|
@ -269,7 +269,7 @@ describe Chat::ChannelArchiveService do
|
||||||
|
|
||||||
it "leaves the topic open" do
|
it "leaves the topic open" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
topic = @channel_archive.destination_topic
|
topic = @channel_archive.destination_topic
|
||||||
topic.reload
|
topic.reload
|
||||||
expect(topic.archived).to eq(false)
|
expect(topic.archived).to eq(false)
|
||||||
|
@ -282,7 +282,7 @@ describe Chat::ChannelArchiveService do
|
||||||
|
|
||||||
it "closes the topic" do
|
it "closes the topic" do
|
||||||
create_messages(3) && start_archive
|
create_messages(3) && start_archive
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
topic = @channel_archive.destination_topic
|
topic = @channel_archive.destination_topic
|
||||||
topic.reload
|
topic.reload
|
||||||
expect(topic.archived).to eq(false)
|
expect(topic.archived).to eq(false)
|
||||||
|
@ -297,7 +297,7 @@ describe Chat::ChannelArchiveService do
|
||||||
destination_topic_title: nil,
|
destination_topic_title: nil,
|
||||||
destination_topic_id: Fabricate(:topic).id,
|
destination_topic_id: Fabricate(:topic).id,
|
||||||
)
|
)
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
topic = @channel_archive.destination_topic
|
topic = @channel_archive.destination_topic
|
||||||
topic.reload
|
topic.reload
|
||||||
expect(topic.archived).to eq(false)
|
expect(topic.archived).to eq(false)
|
||||||
|
@ -322,7 +322,7 @@ describe Chat::ChannelArchiveService do
|
||||||
emoji: "+1",
|
emoji: "+1",
|
||||||
)
|
)
|
||||||
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
end
|
end
|
||||||
|
|
||||||
@channel_archive.reload
|
@channel_archive.reload
|
||||||
|
@ -363,7 +363,7 @@ describe Chat::ChannelArchiveService do
|
||||||
.raises(FakeArchiveError.new("this is a test error"))
|
.raises(FakeArchiveError.new("this is a test error"))
|
||||||
|
|
||||||
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
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
|
end
|
||||||
|
|
||||||
expect(@channel_archive.reload.archive_error).to eq("this is a test error")
|
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)
|
Chat::ChannelArchiveService.any_instance.unstub(:create_post)
|
||||||
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
stub_const(Chat::ChannelArchiveService, "ARCHIVED_MESSAGES_PER_POST", 5) do
|
||||||
subject.new(@channel_archive).execute
|
described_class.new(@channel_archive).execute
|
||||||
end
|
end
|
||||||
|
|
||||||
@channel_archive.reload
|
@channel_archive.reload
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::MessageBookmarkable do
|
describe Chat::MessageBookmarkable do
|
||||||
|
subject(:registered_bookmarkable) { RegisteredBookmarkable.new(described_class) }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
fab!(:guardian) { Guardian.new(user) }
|
fab!(:guardian) { Guardian.new(user) }
|
||||||
fab!(:other_category) { Fabricate(:private_category, group: Fabricate(:group)) }
|
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!(:bookmark2) { Fabricate(:bookmark, user: user, bookmarkable: message2) }
|
||||||
let!(:bookmark3) { Fabricate(:bookmark) }
|
let!(:bookmark3) { Fabricate(:bookmark) }
|
||||||
|
|
||||||
subject { RegisteredBookmarkable.new(described_class) }
|
|
||||||
|
|
||||||
describe "#perform_list_query" do
|
describe "#perform_list_query" do
|
||||||
it "returns all the user's bookmarks" 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],
|
[bookmark1.id, bookmark2.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not return bookmarks for messages inside category chat channels the user cannot access" do
|
it "does not return bookmarks for messages inside category chat channels the user cannot access" do
|
||||||
channel.update(chatable: other_category)
|
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)
|
other_category.groups.last.add(user)
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
user.reload
|
user.reload
|
||||||
guardian = Guardian.new(user)
|
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],
|
[bookmark1.id, bookmark2.id],
|
||||||
)
|
)
|
||||||
end
|
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
|
it "does not return bookmarks for messages inside direct message chat channels the user cannot access" do
|
||||||
direct_message = Fabricate(:direct_message)
|
direct_message = Fabricate(:direct_message)
|
||||||
channel.update(chatable: 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)
|
Chat::DirectMessageUser.create(user: user, direct_message: direct_message)
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
user.reload
|
user.reload
|
||||||
guardian = Guardian.new(user)
|
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],
|
[bookmark1.id, bookmark2.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -62,7 +62,9 @@ describe Chat::MessageBookmarkable do
|
||||||
it "does not return bookmarks for deleted messages" do
|
it "does not return bookmarks for deleted messages" do
|
||||||
message1.trash!
|
message1.trash!
|
||||||
guardian = Guardian.new(user)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -72,8 +74,8 @@ describe Chat::MessageBookmarkable do
|
||||||
it "returns bookmarks that match by name" do
|
it "returns bookmarks that match by name" do
|
||||||
ts_query = Search.ts_query(term: "gotta", ts_config: "simple")
|
ts_query = Search.ts_query(term: "gotta", ts_config: "simple")
|
||||||
expect(
|
expect(
|
||||||
subject.perform_search_query(
|
registered_bookmarkable.perform_search_query(
|
||||||
subject.perform_list_query(user, guardian),
|
registered_bookmarkable.perform_list_query(user, guardian),
|
||||||
"%gotta%",
|
"%gotta%",
|
||||||
ts_query,
|
ts_query,
|
||||||
).map(&:id),
|
).map(&:id),
|
||||||
|
@ -85,8 +87,8 @@ describe Chat::MessageBookmarkable do
|
||||||
|
|
||||||
ts_query = Search.ts_query(term: "good soup", ts_config: "simple")
|
ts_query = Search.ts_query(term: "good soup", ts_config: "simple")
|
||||||
expect(
|
expect(
|
||||||
subject.perform_search_query(
|
registered_bookmarkable.perform_search_query(
|
||||||
subject.perform_list_query(user, guardian),
|
registered_bookmarkable.perform_list_query(user, guardian),
|
||||||
"%good soup%",
|
"%good soup%",
|
||||||
ts_query,
|
ts_query,
|
||||||
).map(&:id),
|
).map(&:id),
|
||||||
|
@ -94,8 +96,8 @@ describe Chat::MessageBookmarkable do
|
||||||
|
|
||||||
ts_query = Search.ts_query(term: "blah", ts_config: "simple")
|
ts_query = Search.ts_query(term: "blah", ts_config: "simple")
|
||||||
expect(
|
expect(
|
||||||
subject.perform_search_query(
|
registered_bookmarkable.perform_search_query(
|
||||||
subject.perform_list_query(user, guardian),
|
registered_bookmarkable.perform_list_query(user, guardian),
|
||||||
"%blah%",
|
"%blah%",
|
||||||
ts_query,
|
ts_query,
|
||||||
).map(&:id),
|
).map(&:id),
|
||||||
|
@ -105,23 +107,23 @@ describe Chat::MessageBookmarkable do
|
||||||
|
|
||||||
describe "#can_send_reminder?" do
|
describe "#can_send_reminder?" do
|
||||||
it "cannot send the reminder if the message or channel is deleted" 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.bookmarkable.trash!
|
||||||
bookmark1.reload
|
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!
|
Chat::Message.with_deleted.find_by(id: bookmark1.bookmarkable_id).recover!
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
bookmark1.bookmarkable.chat_channel.trash!
|
bookmark1.bookmarkable.chat_channel.trash!
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
expect(subject.can_send_reminder?(bookmark1)).to eq(false)
|
expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#reminder_handler" do
|
describe "#reminder_handler" do
|
||||||
it "creates a notification for the user with the correct details" do
|
it "creates a notification for the user with the correct details" do
|
||||||
expect { subject.send_reminder_notification(bookmark1) }.to change { Notification.count }.by(
|
expect { registered_bookmarkable.send_reminder_notification(bookmark1) }.to change {
|
||||||
1,
|
Notification.count
|
||||||
)
|
}.by(1)
|
||||||
notification = user.notifications.last
|
notification = user.notifications.last
|
||||||
expect(notification.notification_type).to eq(Notification.types[:bookmark_reminder])
|
expect(notification.notification_type).to eq(Notification.types[:bookmark_reminder])
|
||||||
expect(notification.data).to eq(
|
expect(notification.data).to eq(
|
||||||
|
@ -142,38 +144,44 @@ describe Chat::MessageBookmarkable do
|
||||||
|
|
||||||
describe "#can_see?" do
|
describe "#can_see?" do
|
||||||
it "returns false if the chat message is in a channel the user cannot 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)
|
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)
|
private_category.groups.last.add(user)
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
user.reload
|
user.reload
|
||||||
guardian = Guardian.new(user)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#validate_before_create" do
|
describe "#validate_before_create" do
|
||||||
it "raises InvalidAccess if the user cannot see the chat channel" 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)
|
bookmark1.bookmarkable.chat_channel.update!(chatable: private_category)
|
||||||
expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.to raise_error(
|
expect {
|
||||||
Discourse::InvalidAccess,
|
registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable)
|
||||||
)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
private_category.groups.last.add(user)
|
private_category.groups.last.add(user)
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
user.reload
|
user.reload
|
||||||
guardian = Guardian.new(user)
|
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
|
end
|
||||||
|
|
||||||
it "raises InvalidAccess if the chat message is deleted" do
|
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.bookmarkable.trash!
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
expect { subject.validate_before_create(guardian, bookmark1.bookmarkable) }.to raise_error(
|
expect {
|
||||||
Discourse::InvalidAccess,
|
registered_bookmarkable.validate_before_create(guardian, bookmark1.bookmarkable)
|
||||||
)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -182,7 +190,7 @@ describe Chat::MessageBookmarkable do
|
||||||
bookmark_post = Fabricate(:bookmark, bookmarkable: Fabricate(:post))
|
bookmark_post = Fabricate(:bookmark, bookmarkable: Fabricate(:post))
|
||||||
bookmark1.bookmarkable.trash!
|
bookmark1.bookmarkable.trash!
|
||||||
bookmark1.bookmarkable.update!(deleted_at: 4.days.ago)
|
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: bookmark1.id)).to eq(false)
|
||||||
expect(Bookmark.exists?(id: bookmark2.id)).to eq(true)
|
expect(Bookmark.exists?(id: bookmark2.id)).to eq(true)
|
||||||
expect(Bookmark.exists?(id: bookmark_post.id)).to eq(true)
|
expect(Bookmark.exists?(id: bookmark_post.id)).to eq(true)
|
||||||
|
|
|
@ -3,39 +3,40 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::MessageReactor do
|
describe Chat::MessageReactor do
|
||||||
|
subject(:message_reactor) { described_class.new(reacting_user, channel) }
|
||||||
|
|
||||||
fab!(:reacting_user) { Fabricate(:user) }
|
fab!(:reacting_user) { Fabricate(:user) }
|
||||||
fab!(:channel) { Fabricate(:category_channel) }
|
fab!(:channel) { Fabricate(:category_channel) }
|
||||||
fab!(:reactor) { described_class.new(reacting_user, channel) }
|
fab!(:reactor) { described_class.new(reacting_user, channel) }
|
||||||
fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel, user: reacting_user) }
|
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
|
it "calls guardian ensure_can_join_chat_channel!" do
|
||||||
Guardian.any_instance.expects(:ensure_can_join_chat_channel!).once
|
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
|
end
|
||||||
|
|
||||||
it "raises an error if the user cannot see the channel" do
|
it "raises an error if the user cannot see the channel" do
|
||||||
channel.update!(chatable: Fabricate(:private_category, group: Group[:staff]))
|
channel.update!(chatable: Fabricate(:private_category, group: Group[:staff]))
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error if the user cannot react" do
|
it "raises an error if the user cannot react" do
|
||||||
SpamRule::AutoSilence.new(reacting_user).silence_user
|
SpamRule::AutoSilence.new(reacting_user).silence_user
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error if the channel status is not open" do
|
it "raises an error if the channel status is not open" do
|
||||||
channel.update!(status: Chat::Channel.statuses[:archived])
|
channel.update!(status: Chat::Channel.statuses[:archived])
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
channel.update!(status: Chat::Channel.statuses[:open])
|
channel.update!(status: Chat::Channel.statuses[:open])
|
||||||
expect {
|
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)
|
}.to change(Chat::MessageReaction, :count).by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::PostNotificationHandler do
|
describe Chat::PostNotificationHandler do
|
||||||
|
subject(:handler) { described_class.new(post, notified_users) }
|
||||||
|
|
||||||
let(:acting_user) { Fabricate(:user) }
|
let(:acting_user) { Fabricate(:user) }
|
||||||
let(:post) { Fabricate(:post) }
|
let(:post) { Fabricate(:post) }
|
||||||
let(:notified_users) { [] }
|
let(:notified_users) { [] }
|
||||||
let(:subject) { described_class.new(post, notified_users) }
|
|
||||||
|
|
||||||
fab!(:channel) { Fabricate(:category_channel) }
|
fab!(:channel) { Fabricate(:category_channel) }
|
||||||
fab!(:message1) do
|
fab!(:message1) do
|
||||||
|
@ -24,7 +25,7 @@ describe Chat::PostNotificationHandler do
|
||||||
|
|
||||||
def expect_no_notification
|
def expect_no_notification
|
||||||
return_val = nil
|
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)
|
expect(return_val).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ describe Chat::PostNotificationHandler do
|
||||||
|
|
||||||
it "sends notifications to all of the quoted users" do
|
it "sends notifications to all of the quoted users" do
|
||||||
update_post_with_chat_quote([message1, message2])
|
update_post_with_chat_quote([message1, message2])
|
||||||
subject.handle
|
handler.handle
|
||||||
expect(
|
expect(
|
||||||
Notification.where(
|
Notification.where(
|
||||||
user: message1.user,
|
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
|
it "does not send the same chat_quoted notification twice to the same post and user" do
|
||||||
update_post_with_chat_quote([message1, message2])
|
update_post_with_chat_quote([message1, message2])
|
||||||
subject.handle
|
handler.handle
|
||||||
subject.handle
|
handler.handle
|
||||||
expect(
|
expect(
|
||||||
Notification.where(
|
Notification.where(
|
||||||
user: message1.user,
|
user: message1.user,
|
||||||
|
@ -87,7 +88,7 @@ describe Chat::PostNotificationHandler do
|
||||||
topic: post.topic,
|
topic: post.topic,
|
||||||
user: message1.user,
|
user: message1.user,
|
||||||
)
|
)
|
||||||
subject.handle
|
handler.handle
|
||||||
expect(
|
expect(
|
||||||
Notification.where(
|
Notification.where(
|
||||||
user: message1.user,
|
user: message1.user,
|
||||||
|
@ -101,7 +102,7 @@ describe Chat::PostNotificationHandler do
|
||||||
|
|
||||||
it "does not send notifications to those users" do
|
it "does not send notifications to those users" do
|
||||||
update_post_with_chat_quote([message1, message2])
|
update_post_with_chat_quote([message1, message2])
|
||||||
subject.handle
|
handler.handle
|
||||||
expect(
|
expect(
|
||||||
Notification.where(
|
Notification.where(
|
||||||
user: message1.user,
|
user: message1.user,
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::ReviewQueue do
|
describe Chat::ReviewQueue do
|
||||||
|
subject(:queue) { described_class.new }
|
||||||
|
|
||||||
fab!(:message_poster) { Fabricate(:user) }
|
fab!(:message_poster) { Fabricate(:user) }
|
||||||
fab!(:flagger) { Fabricate(:user) }
|
fab!(:flagger) { Fabricate(:user) }
|
||||||
fab!(:chat_channel) { Fabricate(:category_channel) }
|
fab!(:chat_channel) { Fabricate(:category_channel) }
|
||||||
fab!(:message) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) }
|
fab!(:message) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) }
|
||||||
|
|
||||||
fab!(:admin) { Fabricate(:admin) }
|
fab!(:admin) { Fabricate(:admin) }
|
||||||
|
|
||||||
let(:guardian) { Guardian.new(flagger) }
|
let(:guardian) { Guardian.new(flagger) }
|
||||||
let(:admin_guardian) { Guardian.new(admin) }
|
let(:admin_guardian) { Guardian.new(admin) }
|
||||||
|
|
||||||
subject(:queue) { described_class.new }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
chat_channel.add(message_poster)
|
chat_channel.add(message_poster)
|
||||||
chat_channel.add(flagger)
|
chat_channel.add(flagger)
|
||||||
|
|
|
@ -3,15 +3,19 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::DeletedUser do
|
describe Chat::DeletedUser do
|
||||||
|
subject(:deleted_user) { described_class.new }
|
||||||
|
|
||||||
describe "#username" do
|
describe "#username" do
|
||||||
it "returns a default 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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#avatar_template" do
|
describe "#avatar_template" do
|
||||||
it "returns a default path" 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,15 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::ChannelUnreadsQuery do
|
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!(:channel_1) { Fabricate(:category_channel) }
|
||||||
fab!(:current_user) { Fabricate(:user) }
|
fab!(:current_user) { Fabricate(:user) }
|
||||||
let(:include_missing_memberships) { false }
|
let(:include_missing_memberships) { false }
|
||||||
|
@ -15,20 +24,11 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
channel_1.add(current_user)
|
channel_1.add(current_user)
|
||||||
end
|
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
|
context "with unread message" do
|
||||||
before { Fabricate(:chat_message, chat_channel: channel_1) }
|
before { Fabricate(:chat_message, chat_channel: channel_1) }
|
||||||
|
|
||||||
it "returns a correct unread count" do
|
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
|
end
|
||||||
|
|
||||||
context "when the membership has been muted" do
|
context "when the membership has been muted" do
|
||||||
|
@ -40,7 +40,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a zeroed unread count" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,13 +49,13 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
fab!(:thread) { Fabricate(:chat_thread, channel: channel_1, original_message: thread_om) }
|
fab!(:thread) { Fabricate(:chat_thread, channel: channel_1, original_message: thread_om) }
|
||||||
|
|
||||||
it "does include the original message in the unread count" do
|
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
|
end
|
||||||
|
|
||||||
it "does not include other thread messages in the unread count" do
|
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)
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns accurate counts" do
|
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: 1, channel_id: channel_1.id },
|
||||||
{ mention_count: 0, unread_count: 2, channel_id: channel_2.id },
|
{ mention_count: 0, unread_count: 2, channel_id: channel_2.id },
|
||||||
|
@ -87,7 +87,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not return counts for the channels" do
|
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 }],
|
[{ mention_count: 0, unread_count: 1, channel_id: channel_1.id }],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -96,7 +96,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
let(:include_missing_memberships) { true }
|
let(:include_missing_memberships) { true }
|
||||||
|
|
||||||
it "does return zeroed counts for the channels" do
|
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: 1, channel_id: channel_1.id },
|
||||||
{ mention_count: 0, unread_count: 0, channel_id: channel_2.id },
|
{ mention_count: 0, unread_count: 0, channel_id: channel_2.id },
|
||||||
|
@ -108,7 +108,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
let(:include_read) { false }
|
let(:include_read) { false }
|
||||||
|
|
||||||
it "does not return counts for the channels" do
|
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 }],
|
[{ mention_count: 0, unread_count: 1, channel_id: channel_1.id }],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -135,7 +135,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
message = Fabricate(:chat_message, chat_channel: channel_1)
|
message = Fabricate(:chat_message, chat_channel: channel_1)
|
||||||
create_mention(message, 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
|
end
|
||||||
|
|
||||||
context "for unread mentions in a thread" do
|
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
|
it "does include the original message in the mention count" do
|
||||||
create_mention(thread_om, channel_1)
|
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
|
end
|
||||||
|
|
||||||
it "does not include other thread messages in the mention count" do
|
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)
|
thread_message_2 = Fabricate(:chat_message, chat_channel: channel_1, thread: thread)
|
||||||
create_mention(thread_message_1, channel_1)
|
create_mention(thread_message_1, channel_1)
|
||||||
create_mention(thread_message_2, 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ describe Chat::ChannelUnreadsQuery do
|
||||||
message_2 = Fabricate(:chat_message, chat_channel: channel_2)
|
message_2 = Fabricate(:chat_message, chat_channel: channel_2)
|
||||||
create_mention(message_2, 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: 1, channel_id: channel_1.id },
|
||||||
{ mention_count: 1, unread_count: 2, channel_id: channel_2.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
|
context "with nothing unread" do
|
||||||
it "returns a correct state" 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
|
end
|
||||||
|
|
||||||
context "when include_read is false" do
|
context "when include_read is false" do
|
||||||
let(:include_read) { false }
|
let(:include_read) { false }
|
||||||
|
|
||||||
it "returns nothing" do
|
it "returns nothing" do
|
||||||
expect(subject).to eq([])
|
expect(query).to eq([])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Chat::MessagesQuery do
|
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!(:channel) { Fabricate(:category_channel) }
|
||||||
fab!(:current_user) { Fabricate(:user) }
|
fab!(:current_user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
@ -21,10 +25,6 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:subject) do
|
|
||||||
described_class.call(guardian: current_user.guardian, channel: channel, **options)
|
|
||||||
end
|
|
||||||
|
|
||||||
fab!(:message_1) do
|
fab!(:message_1) do
|
||||||
message = Fabricate(:chat_message, chat_channel: channel)
|
message = Fabricate(:chat_message, chat_channel: channel)
|
||||||
message.update!(created_at: 2.days.ago)
|
message.update!(created_at: 2.days.ago)
|
||||||
|
@ -42,7 +42,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
let(:target_message_id) { target_message.id }
|
let(:target_message_id) { target_message.id }
|
||||||
|
|
||||||
it "queries messages in the channel and finds the past and future messages" do
|
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],
|
past_messages: [message_1],
|
||||||
future_messages: [message_3],
|
future_messages: [message_3],
|
||||||
target_message: target_message,
|
target_message: target_message,
|
||||||
|
@ -53,29 +53,29 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
|
|
||||||
it "does not include deleted messages" do
|
it "does not include deleted messages" do
|
||||||
message_3.trash!
|
message_3.trash!
|
||||||
expect(subject[:future_messages]).to eq([])
|
expect(query[:future_messages]).to eq([])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "still includes the target message if it is deleted" do
|
it "still includes the target message if it is deleted" do
|
||||||
target_message.trash!
|
target_message.trash!
|
||||||
expect(subject[:target_message]).to eq(target_message)
|
expect(query[:target_message]).to eq(target_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can_load_more_past is true when the past messages reach the limit" do
|
it "can_load_more_past is true when the past messages reach the limit" do
|
||||||
stub_const(described_class, "PAST_MESSAGE_LIMIT", 1) 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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can_load_more_future is true when the future messages reach the limit" do
|
it "can_load_more_future is true when the future messages reach the limit" do
|
||||||
stub_const(described_class, "FUTURE_MESSAGE_LIMIT", 1) 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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "limits results of paginated query when page_size is not set" do
|
it "limits results of paginated query when page_size is not set" do
|
||||||
options[:target_message_id] = nil
|
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
|
end
|
||||||
|
|
||||||
describe "when some messages are in threads" do
|
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
|
it "does not include messages which are thread replies but does include thread original messages" do
|
||||||
message_3.update!(thread: thread)
|
message_3.update!(thread: thread)
|
||||||
expect(subject[:future_messages]).to eq([thread.original_message])
|
expect(query[:future_messages]).to eq([thread.original_message])
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when include_thread_messages is true" do
|
context "when include_thread_messages is true" do
|
||||||
|
@ -94,7 +94,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
thread: thread,
|
thread: thread,
|
||||||
created_at: thread.original_message.created_at + 1.minute,
|
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
|
end
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
thread: thread,
|
thread: thread,
|
||||||
created_at: thread.original_message.created_at + 1.minute,
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -115,7 +115,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
|
|
||||||
it "does include deleted messages" do
|
it "does include deleted messages" do
|
||||||
message_3.trash!
|
message_3.trash!
|
||||||
expect(subject[:future_messages]).to eq([message_3])
|
expect(query[:future_messages]).to eq([message_3])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -124,7 +124,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
let(:target_date) { 1.day.ago }
|
let(:target_date) { 1.day.ago }
|
||||||
|
|
||||||
it "queries messages in the channel and finds the past and future messages" do
|
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],
|
past_messages: [message_1],
|
||||||
future_messages: [message_2, message_3],
|
future_messages: [message_2, message_3],
|
||||||
target_date: target_date,
|
target_date: target_date,
|
||||||
|
@ -136,7 +136,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
|
|
||||||
context "when target_message_id not provided" do
|
context "when target_message_id not provided" do
|
||||||
it "queries messages in the channel" do
|
it "queries messages in the channel" do
|
||||||
expect(subject).to eq(
|
expect(query).to eq(
|
||||||
messages: [message_1, message_2, message_3],
|
messages: [message_1, message_2, message_3],
|
||||||
can_load_more_past: false,
|
can_load_more_past: false,
|
||||||
can_load_more_future: false,
|
can_load_more_future: false,
|
||||||
|
@ -147,7 +147,7 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
let(:page_size) { 3 }
|
let(:page_size) { 3 }
|
||||||
|
|
||||||
it "can_load_more_past is true" do
|
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
|
end
|
||||||
|
|
||||||
|
@ -155,14 +155,14 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
let(:direction) { described_class::FUTURE }
|
let(:direction) { described_class::FUTURE }
|
||||||
|
|
||||||
it "returns messages in ascending order by created_at" do
|
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
|
end
|
||||||
|
|
||||||
context "when the messages length is equal to the page_size" do
|
context "when the messages length is equal to the page_size" do
|
||||||
let(:page_size) { 3 }
|
let(:page_size) { 3 }
|
||||||
|
|
||||||
it "can_load_more_future is true" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -171,14 +171,14 @@ RSpec.describe Chat::MessagesQuery do
|
||||||
let(:direction) { described_class::PAST }
|
let(:direction) { described_class::PAST }
|
||||||
|
|
||||||
it "returns messages in ascending order by created_at" do
|
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
|
end
|
||||||
|
|
||||||
context "when the messages length is equal to the page_size" do
|
context "when the messages length is equal to the page_size" do
|
||||||
let(:page_size) { 3 }
|
let(:page_size) { 3 }
|
||||||
|
|
||||||
it "can_load_more_past is true" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,16 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::ThreadUnreadsQuery do
|
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_1) { Fabricate(:category_channel, threading_enabled: true) }
|
||||||
fab!(:channel_2) { Fabricate(:category_channel, threading_enabled: true) }
|
fab!(:channel_2) { Fabricate(:category_channel, threading_enabled: true) }
|
||||||
fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1) }
|
fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1) }
|
||||||
|
@ -16,15 +26,6 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:include_read) { true }
|
let(:include_read) { true }
|
||||||
let(:channel_ids) { [] }
|
let(:channel_ids) { [] }
|
||||||
let(:thread_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
|
before do
|
||||||
SiteSetting.chat_enabled = true
|
SiteSetting.chat_enabled = true
|
||||||
|
@ -47,7 +48,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:channel_ids) { [channel_1.id, channel_2.id] }
|
let(:channel_ids) { [channel_1.id, channel_2.id] }
|
||||||
|
|
||||||
it "gets a count of all the thread unreads across the channels" do
|
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_1.id, unread_count: 1 },
|
||||||
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_2.id, unread_count: 0 },
|
{ 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
|
it "does not count deleted messages" do
|
||||||
message_1.trash!
|
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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not messages in threads where threading_enabled is false on the channel" do
|
it "does not messages in threads where threading_enabled is false on the channel" do
|
||||||
channel_1.update!(threading_enabled: false)
|
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 },
|
{ 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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_2.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -79,7 +80,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
.user_chat_thread_memberships
|
.user_chat_thread_memberships
|
||||||
.find_by(user: current_user)
|
.find_by(user: current_user)
|
||||||
.update!(last_read_message_id: message_1.id)
|
.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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -87,7 +88,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
it "does not count the original message ID as unread" do
|
it "does not count the original message ID as unread" do
|
||||||
thread_1.original_message.destroy
|
thread_1.original_message.destroy
|
||||||
thread_1.update!(original_message: message_1)
|
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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -96,7 +97,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:include_read) { false }
|
let(:include_read) { false }
|
||||||
|
|
||||||
it "does not get threads with no unread messages" do
|
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,
|
channel_id: channel_1.id,
|
||||||
|
@ -114,7 +115,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:thread_ids) { [thread_1.id, thread_3.id] }
|
let(:thread_ids) { [thread_1.id, thread_3.id] }
|
||||||
|
|
||||||
it "gets a count of all the thread unreads for the specified threads" do
|
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_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 },
|
{ 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
|
end
|
||||||
|
|
||||||
it "gets a zeroed out count for the thread" do
|
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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -146,7 +147,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "gets a zeroed out count for the thread" do
|
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 },
|
{ channel_id: channel_1.id, mention_count: 0, thread_id: thread_1.id, unread_count: 0 },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -156,7 +157,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
before { thread_1.user_chat_thread_memberships.find_by(user: current_user).destroy! }
|
before { thread_1.user_chat_thread_memberships.find_by(user: current_user).destroy! }
|
||||||
|
|
||||||
it "does not get that thread unread count by default" do
|
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,
|
channel_id: channel_2.id,
|
||||||
|
@ -172,7 +173,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:include_missing_memberships) { true }
|
let(:include_missing_memberships) { true }
|
||||||
|
|
||||||
it "includes the thread that the user is not a member of with zeroed out counts" do
|
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,
|
channel_id: channel_1.id,
|
||||||
|
@ -194,7 +195,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:include_read) { false }
|
let(:include_read) { false }
|
||||||
|
|
||||||
it "does not include the thread that the user is not a member of with zeroed out counts" do
|
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,
|
channel_id: channel_2.id,
|
||||||
|
@ -215,7 +216,7 @@ describe Chat::ThreadUnreadsQuery do
|
||||||
let(:thread_ids) { [thread_1.id, thread_3.id] }
|
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
|
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_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 },
|
{ channel_id: channel_2.id, mention_count: 0, thread_id: thread_3.id, unread_count: 1 },
|
||||||
|
|
|
@ -1,15 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Chat::TrackingStateReportQuery do
|
RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
fab!(:current_user) { Fabricate(:user) }
|
subject(:query) do
|
||||||
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
|
|
||||||
described_class.call(
|
described_class.call(
|
||||||
guardian: guardian,
|
guardian: guardian,
|
||||||
channel_ids: channel_ids,
|
channel_ids: channel_ids,
|
||||||
|
@ -20,9 +12,17 @@ RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
)
|
)
|
||||||
end
|
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
|
context "when channel_ids empty" do
|
||||||
it "returns empty object for channel_tracking" do
|
it "returns empty object for channel_tracking" do
|
||||||
expect(subject.channel_tracking).to eq({})
|
expect(query.channel_tracking).to eq({})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
include_read: include_read,
|
include_read: include_read,
|
||||||
)
|
)
|
||||||
.returns([])
|
.returns([])
|
||||||
subject
|
query
|
||||||
end
|
end
|
||||||
|
|
||||||
it "generates a correct unread report for the channels the user is a member of" do
|
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_1)
|
||||||
Fabricate(:chat_message, chat_channel: channel_2)
|
Fabricate(:chat_message, chat_channel: channel_2)
|
||||||
|
|
||||||
expect(subject.channel_tracking).to eq(
|
expect(query.channel_tracking).to eq(
|
||||||
{
|
{
|
||||||
channel_1.id => {
|
channel_1.id => {
|
||||||
unread_count: 1,
|
unread_count: 1,
|
||||||
|
@ -66,7 +66,7 @@ RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
|
|
||||||
it "does not include threads by default" do
|
it "does not include threads by default" do
|
||||||
Chat::ThreadUnreadsQuery.expects(:call).never
|
Chat::ThreadUnreadsQuery.expects(:call).never
|
||||||
expect(subject.thread_tracking).to eq({})
|
expect(query.thread_tracking).to eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when include_threads is true" do
|
context "when include_threads is true" do
|
||||||
|
@ -90,7 +90,7 @@ RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
include_read: include_read,
|
include_read: include_read,
|
||||||
)
|
)
|
||||||
.returns([])
|
.returns([])
|
||||||
subject
|
query
|
||||||
end
|
end
|
||||||
|
|
||||||
it "generates a correct unread for the threads the user is a member of in the channels" do
|
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_1, thread: thread_1)
|
||||||
Fabricate(:chat_message, chat_channel: channel_2, thread: thread_2)
|
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 => {
|
channel_1.id => {
|
||||||
unread_count: 1,
|
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 => {
|
thread_1.id => {
|
||||||
unread_count: 1,
|
unread_count: 1,
|
||||||
|
@ -135,7 +135,7 @@ RSpec.describe Chat::TrackingStateReportQuery do
|
||||||
|
|
||||||
it "does not query threads" do
|
it "does not query threads" do
|
||||||
Chat::ThreadUnreadsQuery.expects(:call).never
|
Chat::ThreadUnreadsQuery.expects(:call).never
|
||||||
expect(subject.thread_tracking).to eq({})
|
expect(query.thread_tracking).to eq({})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,23 +3,25 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::ChannelSerializer do
|
describe Chat::ChannelSerializer do
|
||||||
|
subject(:serializer) { described_class.new(chat_channel, scope: guardian, root: nil) }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
fab!(:admin) { Fabricate(:admin) }
|
fab!(:admin) { Fabricate(:admin) }
|
||||||
fab!(:chat_channel) { Fabricate(:chat_channel) }
|
fab!(:chat_channel) { Fabricate(:chat_channel) }
|
||||||
|
|
||||||
let(:guardian_user) { user }
|
let(:guardian_user) { user }
|
||||||
let(:guardian) { Guardian.new(guardian_user) }
|
let(:guardian) { Guardian.new(guardian_user) }
|
||||||
subject { described_class.new(chat_channel, scope: guardian, root: nil) }
|
|
||||||
|
|
||||||
describe "archive status" do
|
describe "archive status" do
|
||||||
context "when user is not staff" do
|
context "when user is not staff" do
|
||||||
let(:guardian_user) { user }
|
let(:guardian_user) { user }
|
||||||
|
|
||||||
it "does not return any sort of archive status" do
|
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
|
end
|
||||||
|
|
||||||
it "includes allow_channel_wide_mentions" do
|
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
|
end
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ describe Chat::ChannelSerializer do
|
||||||
let(:guardian_user) { admin }
|
let(:guardian_user) { admin }
|
||||||
|
|
||||||
it "includes the archive status if the channel is archived and the archive record exists" do
|
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])
|
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::ChannelArchive.create!(
|
||||||
chat_channel: chat_channel,
|
chat_channel: chat_channel,
|
||||||
|
@ -39,11 +41,11 @@ describe Chat::ChannelSerializer do
|
||||||
total_messages: 10,
|
total_messages: 10,
|
||||||
)
|
)
|
||||||
chat_channel.reload
|
chat_channel.reload
|
||||||
expect(subject.as_json.key?(:archive_completed)).to eq(true)
|
expect(serializer.as_json.key?(:archive_completed)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes allow_channel_wide_mentions" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,7 +65,7 @@ describe Chat::ChannelSerializer do
|
||||||
MessageBus.expects(:last_id).with(
|
MessageBus.expects(:last_id).with(
|
||||||
Chat::Publisher.kick_users_message_bus_channel(chat_channel.id),
|
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],
|
%i[channel_message_bus_last_id new_messages new_mentions kick],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -73,7 +75,7 @@ describe Chat::ChannelSerializer do
|
||||||
MessageBus.expects(:last_id).with(
|
MessageBus.expects(:last_id).with(
|
||||||
Chat::Publisher.kick_users_message_bus_channel(chat_channel.id),
|
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
|
end
|
||||||
|
|
||||||
it "does not call MessageBus for last_id if all the last IDs are already passed in" do
|
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(
|
MessageBus.expects(:last_id).with(
|
||||||
Chat::Publisher.new_mentions_message_bus_channel(chat_channel.id),
|
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],
|
%i[channel_message_bus_last_id new_messages new_mentions],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -109,7 +111,7 @@ describe Chat::ChannelSerializer do
|
||||||
it "does not get the kick_message_bus_last_id" do
|
it "does not get the kick_message_bus_last_id" do
|
||||||
MessageBus.expects(:last_id).at_least_once
|
MessageBus.expects(:last_id).at_least_once
|
||||||
MessageBus.expects(:last_id).never
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Chat::MessageSerializer do
|
describe Chat::MessageSerializer do
|
||||||
|
subject(:serializer) { described_class.new(message_1, scope: guardian, root: nil) }
|
||||||
|
|
||||||
fab!(:chat_channel) { Fabricate(:category_channel) }
|
fab!(:chat_channel) { Fabricate(:category_channel) }
|
||||||
fab!(:message_poster) { Fabricate(:user) }
|
fab!(:message_poster) { Fabricate(:user) }
|
||||||
fab!(:message_1) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) }
|
fab!(:message_1) { Fabricate(:chat_message, user: message_poster, chat_channel: chat_channel) }
|
||||||
fab!(:guardian_user) { Fabricate(:user) }
|
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
|
describe "#reactions" do
|
||||||
fab!(:custom_emoji) { CustomEmoji.create!(name: "trout", upload: Fabricate(:upload)) }
|
fab!(:custom_emoji) { CustomEmoji.create!(name: "trout", upload: Fabricate(:upload)) }
|
||||||
|
@ -21,13 +22,13 @@ describe Chat::MessageSerializer do
|
||||||
it "doesn’t return the reaction" do
|
it "doesn’t return the reaction" do
|
||||||
Emoji.clear_cache
|
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
|
expect(trout_reaction).to be_present
|
||||||
|
|
||||||
custom_emoji.destroy!
|
custom_emoji.destroy!
|
||||||
Emoji.clear_cache
|
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
|
expect(trout_reaction).to_not be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,7 +50,7 @@ describe Chat::MessageSerializer do
|
||||||
message_1.user.destroy!
|
message_1.user.destroy!
|
||||||
message_1.reload
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -60,14 +61,14 @@ describe Chat::MessageSerializer do
|
||||||
message_1.user.destroy!
|
message_1.user.destroy!
|
||||||
message_1.reload
|
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
|
end
|
||||||
|
|
||||||
it "is marked as deleted by system user" do
|
it "is marked as deleted by system user" do
|
||||||
message_1.user.destroy!
|
message_1.user.destroy!
|
||||||
message_1.reload
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
RSpec.describe Chat::MessageUserSerializer do
|
RSpec.describe Chat::MessageUserSerializer do
|
||||||
subject do
|
subject(:serializer) do
|
||||||
user = Fabricate(:user, **params)
|
user = Fabricate(:user, **params)
|
||||||
guardian = Guardian.new(user)
|
guardian = Guardian.new(user)
|
||||||
described_class.new(user, scope: guardian, root: nil).as_json
|
described_class.new(user, scope: guardian, root: nil).as_json
|
||||||
|
@ -15,11 +15,11 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
|
|
||||||
context "with default user" do
|
context "with default user" do
|
||||||
it "displays user as regular" do
|
it "displays user as regular" do
|
||||||
expect(subject[:new_user]).to eq(false)
|
expect(serializer[:new_user]).to eq(false)
|
||||||
expect(subject[:staff]).to eq(false)
|
expect(serializer[:staff]).to eq(false)
|
||||||
expect(subject[:admin]).to eq(false)
|
expect(serializer[:admin]).to eq(false)
|
||||||
expect(subject[:moderator]).to eq(false)
|
expect(serializer[:moderator]).to eq(false)
|
||||||
expect(subject[:primary_group_name]).to be_blank
|
expect(serializer[:primary_group_name]).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
before { params[:trust_level] = TrustLevel[0] }
|
before { params[:trust_level] = TrustLevel[0] }
|
||||||
|
|
||||||
it "displays user as new" do
|
it "displays user as new" do
|
||||||
expect(subject[:new_user]).to eq(true)
|
expect(serializer[:new_user]).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
before { params[:admin] = true }
|
before { params[:admin] = true }
|
||||||
|
|
||||||
it "displays user as staff" do
|
it "displays user as staff" do
|
||||||
expect(subject[:staff]).to eq(true)
|
expect(serializer[:staff]).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
before { params[:admin] = true }
|
before { params[:admin] = true }
|
||||||
|
|
||||||
it "displays user as admin" do
|
it "displays user as admin" do
|
||||||
expect(subject[:admin]).to eq(true)
|
expect(serializer[:admin]).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
before { params[:moderator] = true }
|
before { params[:moderator] = true }
|
||||||
|
|
||||||
it "displays user as moderator" do
|
it "displays user as moderator" do
|
||||||
expect(subject[:moderator]).to eq(true)
|
expect(serializer[:moderator]).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ RSpec.describe Chat::MessageUserSerializer do
|
||||||
before { params[:primary_group_id] = group.id }
|
before { params[:primary_group_id] = group.id }
|
||||||
|
|
||||||
it "displays user as moderator" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,8 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".call" do
|
describe ".call" do
|
||||||
|
subject(:result) { described_class.call(params) }
|
||||||
|
|
||||||
fab!(:current_user) { Fabricate(:user) }
|
fab!(:current_user) { Fabricate(:user) }
|
||||||
fab!(:channel) { Fabricate(:category_channel) }
|
fab!(:channel) { Fabricate(:category_channel) }
|
||||||
|
|
||||||
|
@ -35,14 +37,12 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:result) { described_class.call(params) }
|
|
||||||
|
|
||||||
it "threads_enabled is false by default" do
|
it "threads_enabled is false by default" do
|
||||||
expect(subject.threads_enabled).to eq(false)
|
expect(result.threads_enabled).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "include_thread_messages is true by default" do
|
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
|
end
|
||||||
|
|
||||||
it "queries messages" do
|
it "queries messages" do
|
||||||
|
@ -59,7 +59,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
target_date: target_date,
|
target_date: target_date,
|
||||||
)
|
)
|
||||||
.returns({ messages: [] })
|
.returns({ messages: [] })
|
||||||
subject
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns channel messages and thread replies" do
|
it "returns channel messages and thread replies" do
|
||||||
|
@ -71,23 +71,23 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
thread: Fabricate(:chat_thread, 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],
|
[message_1, message_2, message_3.thread.original_message, message_3],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not query thread tracking overview or state by default" do
|
it "does not query thread tracking overview or state by default" do
|
||||||
Chat::TrackingStateReportQuery.expects(:call).never
|
Chat::TrackingStateReportQuery.expects(:call).never
|
||||||
subject
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not query threads by default" do
|
it "does not query threads by default" do
|
||||||
Chat::Thread.expects(:where).never
|
Chat::Thread.expects(:where).never
|
||||||
subject
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a Chat::View" do
|
it "returns a Chat::View" do
|
||||||
expect(subject.view).to be_a(Chat::View)
|
expect(result.view).to be_a(Chat::View)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when page_size is null" do
|
context "when page_size is null" do
|
||||||
|
@ -109,11 +109,11 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "threads_enabled is true" do
|
it "threads_enabled is true" do
|
||||||
expect(subject.threads_enabled).to eq(true)
|
expect(result.threads_enabled).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "include_thread_messages is false" do
|
it "include_thread_messages is false" do
|
||||||
expect(subject.include_thread_messages).to eq(false)
|
expect(result.include_thread_messages).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns channel messages but not thread replies" do
|
it "returns channel messages but not thread replies" do
|
||||||
|
@ -125,7 +125,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
thread: Fabricate(:chat_thread, 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_1, message_2, message_3.thread.original_message],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -137,7 +137,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
chat_channel: channel,
|
chat_channel: channel,
|
||||||
thread: Fabricate(:chat_thread, 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
|
end
|
||||||
|
|
||||||
it "fetches thread memberships for the current user for fetched threads" do
|
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),
|
thread: Fabricate(:chat_thread, channel: channel),
|
||||||
)
|
)
|
||||||
message_1.thread.add(current_user)
|
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)],
|
[message_1.thread.membership_for(current_user)],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -171,21 +171,21 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
.with(guardian: guardian, thread_ids: [thread.id], include_threads: true)
|
.with(guardian: guardian, thread_ids: [thread.id], include_threads: true)
|
||||||
.returns(Chat::TrackingStateReport.new)
|
.returns(Chat::TrackingStateReport.new)
|
||||||
.once
|
.once
|
||||||
subject
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fetches an overview of threads with unread messages in the channel" do
|
it "fetches an overview of threads with unread messages in the channel" do
|
||||||
thread = Fabricate(:chat_thread, channel: channel)
|
thread = Fabricate(:chat_thread, channel: channel)
|
||||||
thread.add(current_user)
|
thread.add(current_user)
|
||||||
message_1 = Fabricate(:chat_message, chat_channel: channel, thread: thread)
|
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
|
end
|
||||||
|
|
||||||
it "fetches the tracking state of threads in the channel" do
|
it "fetches the tracking state of threads in the channel" do
|
||||||
thread = Fabricate(:chat_thread, channel: channel)
|
thread = Fabricate(:chat_thread, channel: channel)
|
||||||
thread.add(current_user)
|
thread.add(current_user)
|
||||||
Fabricate(:chat_message, chat_channel: channel, thread: thread)
|
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 } },
|
{ thread.id => { channel_id: channel.id, unread_count: 1, mention_count: 0 } },
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -194,7 +194,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
let(:thread_id) { Fabricate(:chat_thread, channel: channel).id }
|
let(:thread_id) { Fabricate(:chat_thread, channel: channel).id }
|
||||||
|
|
||||||
it "include_thread_messages is true" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -233,7 +233,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
|
|
||||||
context "if the user is not a member of the channel" do
|
context "if the user is not a member of the channel" do
|
||||||
it "does not error and still returns messages" 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
before { membership.update!(last_read_message_id: past_message_1.id) }
|
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
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
before { membership.update!(last_read_message_id: nil) }
|
before { membership.update!(last_read_message_id: nil) }
|
||||||
|
|
||||||
it "does not error and still returns messages" 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
|
||||||
|
|
||||||
context "if page_size is nil" do
|
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))
|
.with(has_entries(page_size: Chat::MessagesQuery::MAX_PAGE_SIZE))
|
||||||
.once
|
.once
|
||||||
.returns({ messages: [] })
|
.returns({ messages: [] })
|
||||||
subject
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -288,7 +288,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
let(:target_message_id) { message.id }
|
let(:target_message_id) { message.id }
|
||||||
|
|
||||||
it "includes the target message as well as past and future messages" do
|
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
|
end
|
||||||
|
|
||||||
context "when page_size is null" do
|
context "when page_size is null" do
|
||||||
|
@ -303,7 +303,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
before { message.update!(thread: thread) }
|
before { message.update!(thread: thread) }
|
||||||
|
|
||||||
it "includes it by default" do
|
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],
|
[past_message, message, thread.original_message, future_message],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -315,7 +315,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not include the target message" do
|
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],
|
[past_message, thread.original_message, future_message],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -356,7 +356,7 @@ RSpec.describe Chat::ChannelViewBuilder do
|
||||||
let(:target_date) { 2.days.ago }
|
let(:target_date) { 2.days.ago }
|
||||||
|
|
||||||
it "includes past and future messages" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
RSpec.describe ::DiscoursePoll::PollsValidator do
|
RSpec.describe ::DiscoursePoll::PollsValidator do
|
||||||
|
subject(:validator) { described_class.new(post) }
|
||||||
|
|
||||||
let(:post) { Fabricate(:post) }
|
let(:post) { Fabricate(:post) }
|
||||||
subject { described_class.new(post) }
|
|
||||||
|
|
||||||
describe "#validate_polls" do
|
describe "#validate_polls" do
|
||||||
it "ensures that polls have valid arguments" do
|
it "ensures that polls have valid arguments" do
|
||||||
|
|
|
@ -23,11 +23,12 @@ RSpec.describe EmailStyle do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with invite" do
|
context "with invite" do
|
||||||
fab!(:invite) { Fabricate(:invite) }
|
|
||||||
let(:invite_mail) { InviteMailer.send_invite(invite) }
|
|
||||||
|
|
||||||
subject(:mail_html) { Email::Renderer.new(invite_mail).html }
|
subject(:mail_html) { Email::Renderer.new(invite_mail).html }
|
||||||
|
|
||||||
|
fab!(:invite) { Fabricate(:invite) }
|
||||||
|
|
||||||
|
let(:invite_mail) { InviteMailer.send_invite(invite) }
|
||||||
|
|
||||||
it "applies customizations" do
|
it "applies customizations" do
|
||||||
expect(mail_html.scan('<h1 style="color: red;">FOR YOU</h1>').count).to eq(1)
|
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}")
|
expect(mail_html).to match("#{Discourse.base_url}/invites/#{invite.invite_key}")
|
||||||
|
@ -48,6 +49,8 @@ RSpec.describe EmailStyle do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when user_replied" do
|
context "when user_replied" do
|
||||||
|
subject(:mail_html) { Email::Renderer.new(mail).html }
|
||||||
|
|
||||||
let(:response_by_user) { Fabricate(:user, name: "John Doe") }
|
let(:response_by_user) { Fabricate(:user, name: "John Doe") }
|
||||||
let(:category) { Fabricate(:category, name: "India") }
|
let(:category) { Fabricate(:category, name: "India") }
|
||||||
let(:topic) { Fabricate(:topic, category: category, title: "Super cool topic") }
|
let(:topic) { Fabricate(:topic, category: category, title: "Super cool topic") }
|
||||||
|
@ -65,8 +68,6 @@ RSpec.describe EmailStyle do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:mail_html) { Email::Renderer.new(mail).html }
|
|
||||||
|
|
||||||
it "customizations are applied to html part of emails" do
|
it "customizations are applied to html part of emails" do
|
||||||
SiteSetting.default_email_in_reply_to = true
|
SiteSetting.default_email_in_reply_to = true
|
||||||
|
|
||||||
|
@ -80,9 +81,10 @@ RSpec.describe EmailStyle do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with signup" do
|
context "with signup" do
|
||||||
let(:signup_mail) { UserNotifications.signup(Fabricate(:user)) }
|
|
||||||
subject(:mail_html) { Email::Renderer.new(signup_mail).html }
|
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
|
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.scan('<h1 style="color: red;">FOR YOU</h1>').count).to eq(1)
|
||||||
expect(mail_html).to include("activate-account")
|
expect(mail_html).to include("activate-account")
|
||||||
|
@ -124,11 +126,13 @@ RSpec.describe EmailStyle do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with digest" do
|
context "with digest" do
|
||||||
|
subject(:mail_html) { Email::Renderer.new(summary_email).html }
|
||||||
|
|
||||||
fab!(:popular_topic) do
|
fab!(:popular_topic) do
|
||||||
Fabricate(:topic, user: Fabricate(:coding_horror), created_at: 1.hour.ago)
|
Fabricate(:topic, user: Fabricate(:coding_horror), created_at: 1.hour.ago)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:summary_email) { UserNotifications.digest(Fabricate(:user)) }
|
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
|
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.scan('<h1 style="color: red;">FOR YOU</h1>').count).to eq(1)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::AutoQueueHandler do
|
RSpec.describe Jobs::AutoQueueHandler do
|
||||||
subject { Jobs::AutoQueueHandler.new.execute({}) }
|
subject(:job) { Jobs::AutoQueueHandler.new.execute({}) }
|
||||||
|
|
||||||
describe "old flagged post" do
|
describe "old flagged post" do
|
||||||
fab!(:spam_result) 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
|
it "defers the old flag if auto_handle_queued_age is 60" do
|
||||||
SiteSetting.auto_handle_queued_age = 60
|
SiteSetting.auto_handle_queued_age = 60
|
||||||
subject
|
job
|
||||||
expect(not_old.reload).to be_pending
|
expect(not_old.reload).to be_pending
|
||||||
expect(old.reload).not_to be_pending
|
expect(old.reload).not_to be_pending
|
||||||
expect(post_action.related_post.topic.posts_count).to eq(1)
|
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
|
it "doesn't defer the old flag if auto_handle_queued_age is 0" do
|
||||||
SiteSetting.auto_handle_queued_age = 0
|
SiteSetting.auto_handle_queued_age = 0
|
||||||
subject
|
job
|
||||||
expect(not_old.reload).to be_pending
|
expect(not_old.reload).to be_pending
|
||||||
expect(old.reload).to be_pending
|
expect(old.reload).to be_pending
|
||||||
end
|
end
|
||||||
|
@ -45,7 +45,7 @@ RSpec.describe Jobs::AutoQueueHandler do
|
||||||
|
|
||||||
it "rejects the post when auto_handle_queued_age is 60" do
|
it "rejects the post when auto_handle_queued_age is 60" do
|
||||||
SiteSetting.auto_handle_queued_age = 60
|
SiteSetting.auto_handle_queued_age = 60
|
||||||
subject
|
job
|
||||||
expect(new_post.reload.pending?).to eq(true)
|
expect(new_post.reload.pending?).to eq(true)
|
||||||
expect(old_post.reload.rejected?).to eq(true)
|
expect(old_post.reload.rejected?).to eq(true)
|
||||||
expect(new_user.reload.pending?).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
|
it "leaves reviewables as pending auto_handle_queued_age is 0" do
|
||||||
SiteSetting.auto_handle_queued_age = 0
|
SiteSetting.auto_handle_queued_age = 0
|
||||||
subject
|
job
|
||||||
expect(new_post.reload.pending?).to eq(true)
|
expect(new_post.reload.pending?).to eq(true)
|
||||||
expect(new_user.reload.pending?).to eq(true)
|
expect(new_user.reload.pending?).to eq(true)
|
||||||
expect(old_post.reload.pending?).to eq(true)
|
expect(old_post.reload.pending?).to eq(true)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::BookmarkReminderNotifications do
|
RSpec.describe Jobs::BookmarkReminderNotifications do
|
||||||
subject { described_class.new }
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
let(:five_minutes_ago) { Time.zone.now - 5.minutes }
|
let(:five_minutes_ago) { Time.zone.now - 5.minutes }
|
||||||
|
@ -19,7 +19,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends every reminder and sets the reminder_last_sent_at" do
|
it "sends every reminder and sets the reminder_last_sent_at" do
|
||||||
subject.execute
|
job.execute
|
||||||
bookmark1.reload
|
bookmark1.reload
|
||||||
bookmark2.reload
|
bookmark2.reload
|
||||||
bookmark3.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
|
it "will not send a reminder for a bookmark in the future" do
|
||||||
freeze_time
|
freeze_time
|
||||||
bookmark4 = Fabricate(:bookmark, reminder_at: Time.zone.now + 1.day)
|
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(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(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)
|
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 = Fabricate(:bookmark, user: bookmark1.user)
|
||||||
other_bookmark.update_column(:reminder_at, five_minutes_ago)
|
other_bookmark.update_column(:reminder_at, five_minutes_ago)
|
||||||
SiteSetting.max_bookmarks_per_user = 2
|
SiteSetting.max_bookmarks_per_user = 2
|
||||||
expect { subject.execute }.not_to raise_error
|
expect { job.execute }.not_to raise_error
|
||||||
end
|
end
|
||||||
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
|
it "does not send them in the current run, but will send them in the next" do
|
||||||
begin
|
begin
|
||||||
Jobs::BookmarkReminderNotifications.max_reminder_notifications_per_run = 2
|
Jobs::BookmarkReminderNotifications.max_reminder_notifications_per_run = 2
|
||||||
subject.execute
|
job.execute
|
||||||
expect(bookmark1.reload.reminder_last_sent_at).not_to eq(nil)
|
expect(bookmark1.reload.reminder_last_sent_at).not_to eq(nil)
|
||||||
expect(bookmark2.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)
|
expect(bookmark3.reload.reminder_last_sent_at).to eq(nil)
|
||||||
|
@ -64,7 +64,7 @@ RSpec.describe Jobs::BookmarkReminderNotifications do
|
||||||
bookmark1.bookmarkable.topic.destroy
|
bookmark1.bookmarkable.topic.destroy
|
||||||
bookmark2.bookmarkable.topic.destroy
|
bookmark2.bookmarkable.topic.destroy
|
||||||
bookmark3.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
|
Notification.where(notification_type: Notification.types[:bookmark_reminder]).count
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::CleanUpAssociatedAccounts do
|
RSpec.describe Jobs::CleanUpAssociatedAccounts do
|
||||||
subject { Jobs::CleanUpAssociatedAccounts.new.execute({}) }
|
subject(:job) { Jobs::CleanUpAssociatedAccounts.new.execute({}) }
|
||||||
|
|
||||||
it "deletes the correct records" do
|
it "deletes the correct records" do
|
||||||
freeze_time
|
freeze_time
|
||||||
|
@ -26,7 +26,7 @@ RSpec.describe Jobs::CleanUpAssociatedAccounts do
|
||||||
updated_at: 12.hours.ago,
|
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)
|
expect(UserAssociatedAccount.all).to contain_exactly(today, connected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::CleanUpCrawlerStats do
|
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
|
it "deletes records older than 30 days old" do
|
||||||
freeze_time
|
freeze_time
|
||||||
|
@ -10,7 +10,7 @@ RSpec.describe Jobs::CleanUpCrawlerStats do
|
||||||
yesterday = Fabricate(:web_crawler_request, date: 1.day.ago.to_date)
|
yesterday = Fabricate(:web_crawler_request, date: 1.day.ago.to_date)
|
||||||
too_old = Fabricate(:web_crawler_request, date: 31.days.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
|
expect(WebCrawlerRequest.where(id: too_old.id)).to_not exist
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ RSpec.describe Jobs::CleanUpCrawlerStats do
|
||||||
req2 = Fabricate(:web_crawler_request, date: 1.day.ago.to_date, count: 50)
|
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)
|
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)
|
expect(WebCrawlerRequest.all).to contain_exactly(req1, req2, req3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::CreateRecentPostSearchIndexes do
|
RSpec.describe Jobs::CreateRecentPostSearchIndexes do
|
||||||
subject { described_class.new }
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:post) { with_search_indexer_enabled { Fabricate(:post) } }
|
fab!(:post) { with_search_indexer_enabled { Fabricate(:post) } }
|
||||||
fab!(:post_2) { 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_recent_posts_size = 1
|
||||||
SiteSetting.search_enable_recent_regular_posts_offset_size = 3
|
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
|
SiteSetting.search_recent_regular_posts_offset_post_id
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -22,7 +22,7 @@ RSpec.describe Jobs::CreateRecentPostSearchIndexes do
|
||||||
SiteSetting.search_recent_posts_size = 1
|
SiteSetting.search_recent_posts_size = 1
|
||||||
SiteSetting.search_enable_recent_regular_posts_offset_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)
|
expect(SiteSetting.search_recent_regular_posts_offset_post_id).to eq(post_2.id)
|
||||||
|
|
||||||
|
|
|
@ -3,25 +3,27 @@
|
||||||
require "excon"
|
require "excon"
|
||||||
|
|
||||||
RSpec.describe Jobs::EmitWebHookEvent do
|
RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:post_hook) { Fabricate(:web_hook) }
|
fab!(:post_hook) { Fabricate(:web_hook) }
|
||||||
fab!(:inactive_hook) { Fabricate(:inactive_web_hook) }
|
fab!(:inactive_hook) { Fabricate(:inactive_web_hook) }
|
||||||
fab!(:post) { Fabricate(:post) }
|
fab!(:post) { Fabricate(:post) }
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
it "raises an error when there is no web hook record" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when there is no event type" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when there is no payload" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -29,7 +31,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
it "should not destroy webhook event in case of error" do
|
it "should not destroy webhook event in case of error" do
|
||||||
stub_request(:post, post_hook.payload_url).to_return(status: 500)
|
stub_request(:post, post_hook.payload_url).to_return(status: 500)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
payload: { id: post.id }.to_json,
|
payload: { id: post.id }.to_json,
|
||||||
event_type: WebHookEventType::POST,
|
event_type: WebHookEventType::POST,
|
||||||
|
@ -53,7 +55,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
|
|
||||||
it "disables the webhook" do
|
it "disables the webhook" do
|
||||||
expect do
|
expect do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: described_class::PING_EVENT,
|
event_type: described_class::PING_EVENT,
|
||||||
retry_count: described_class::MAX_RETRY_COUNT,
|
retry_count: described_class::MAX_RETRY_COUNT,
|
||||||
|
@ -62,7 +64,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "logs webhook deactivation reason" do
|
it "logs webhook deactivation reason" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: described_class::PING_EVENT,
|
event_type: described_class::PING_EVENT,
|
||||||
retry_count: described_class::MAX_RETRY_COUNT,
|
retry_count: described_class::MAX_RETRY_COUNT,
|
||||||
|
@ -86,7 +88,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
|
|
||||||
it "retry if site setting is enabled" do
|
it "retry if site setting is enabled" do
|
||||||
expect 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.to change { Jobs::EmitWebHookEvent.jobs.size }.by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,13 +98,13 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
expect(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1).to eq(5)
|
expect(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1).to eq(5)
|
||||||
|
|
||||||
expect 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 { WebHookEvent.count }.by(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1)
|
end.to change { WebHookEvent.count }.by(Jobs::EmitWebHookEvent::MAX_RETRY_COUNT + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not retry for more than maximum allowed times" do
|
it "does not retry for more than maximum allowed times" do
|
||||||
expect do
|
expect do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: described_class::PING_EVENT,
|
event_type: described_class::PING_EVENT,
|
||||||
retry_count: described_class::MAX_RETRY_COUNT,
|
retry_count: described_class::MAX_RETRY_COUNT,
|
||||||
|
@ -114,13 +116,13 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
SiteSetting.retry_web_hook_events = false
|
SiteSetting.retry_web_hook_events = false
|
||||||
|
|
||||||
expect 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.not_to change { Jobs::EmitWebHookEvent.jobs.size }
|
end.not_to change { Jobs::EmitWebHookEvent.jobs.size }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "properly logs error on rescue" do
|
it "properly logs error on rescue" do
|
||||||
stub_request(:post, post_hook.payload_url).to_raise("connection error")
|
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
|
event = WebHookEvent.last
|
||||||
expect(event.payload).to eq(MultiJson.dump(ping: "OK"))
|
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
|
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)
|
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
|
end
|
||||||
|
|
||||||
it "doesn't emit when the hook is inactive" do
|
it "doesn't emit when the hook is inactive" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: inactive_hook.id,
|
web_hook_id: inactive_hook.id,
|
||||||
event_type: "post",
|
event_type: "post",
|
||||||
payload: { test: "some payload" }.to_json,
|
payload: { test: "some payload" }.to_json,
|
||||||
|
@ -149,7 +151,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
body: "{\"post\":{\"test\":\"some payload\"}}",
|
body: "{\"post\":{\"test\":\"some payload\"}}",
|
||||||
).to_return(body: "OK", status: 200)
|
).to_return(body: "OK", status: 200)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: "post",
|
event_type: "post",
|
||||||
payload: { test: "some payload" }.to_json,
|
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
|
it "doesn't emit if the payload URL resolves to a disallowed IP" do
|
||||||
FinalDestination::TestHelper.stub_to_fail do
|
FinalDestination::TestHelper.stub_to_fail do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: "post",
|
event_type: "post",
|
||||||
payload: { test: "some payload" }.to_json,
|
payload: { test: "some payload" }.to_json,
|
||||||
|
@ -179,7 +181,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
fab!(:topic_hook) { Fabricate(:topic_web_hook, categories: [category]) }
|
fab!(:topic_hook) { Fabricate(:topic_web_hook, categories: [category]) }
|
||||||
|
|
||||||
it "doesn't emit when event is not related with defined categories" do
|
it "doesn't emit when event is not related with defined categories" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: topic_hook.id,
|
web_hook_id: topic_hook.id,
|
||||||
event_type: "topic",
|
event_type: "topic",
|
||||||
category_id: topic.category.id,
|
category_id: topic.category.id,
|
||||||
|
@ -192,7 +194,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
body: "{\"topic\":{\"test\":\"some payload\"}}",
|
body: "{\"topic\":{\"test\":\"some payload\"}}",
|
||||||
).to_return(body: "OK", status: 200)
|
).to_return(body: "OK", status: 200)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: topic_hook.id,
|
web_hook_id: topic_hook.id,
|
||||||
event_type: "topic",
|
event_type: "topic",
|
||||||
category_id: topic_with_category.category.id,
|
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]) }
|
fab!(:topic_hook) { Fabricate(:topic_web_hook, tags: [tag]) }
|
||||||
|
|
||||||
it "doesn't emit when event is not included any tags" do
|
it "doesn't emit when event is not included any tags" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: topic_hook.id,
|
web_hook_id: topic_hook.id,
|
||||||
event_type: "topic",
|
event_type: "topic",
|
||||||
payload: { test: "some payload" }.to_json,
|
payload: { test: "some payload" }.to_json,
|
||||||
|
@ -215,7 +217,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't emit when event is not related with defined tags" do
|
it "doesn't emit when event is not related with defined tags" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: topic_hook.id,
|
web_hook_id: topic_hook.id,
|
||||||
event_type: "topic",
|
event_type: "topic",
|
||||||
tag_ids: [Fabricate(:tag).id],
|
tag_ids: [Fabricate(:tag).id],
|
||||||
|
@ -228,7 +230,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
body: "{\"topic\":{\"test\":\"some payload\"}}",
|
body: "{\"topic\":{\"test\":\"some payload\"}}",
|
||||||
).to_return(body: "OK", status: 200)
|
).to_return(body: "OK", status: 200)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: topic_hook.id,
|
web_hook_id: topic_hook.id,
|
||||||
event_type: "topic",
|
event_type: "topic",
|
||||||
tag_ids: topic.tags.pluck(:id),
|
tag_ids: topic.tags.pluck(:id),
|
||||||
|
@ -243,7 +245,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
fab!(:like_hook) { Fabricate(:like_web_hook, groups: [group]) }
|
fab!(:like_hook) { Fabricate(:like_web_hook, groups: [group]) }
|
||||||
|
|
||||||
it "doesn't emit when event is not included any groups" do
|
it "doesn't emit when event is not included any groups" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: like_hook.id,
|
web_hook_id: like_hook.id,
|
||||||
event_type: "like",
|
event_type: "like",
|
||||||
payload: { test: "some payload" }.to_json,
|
payload: { test: "some payload" }.to_json,
|
||||||
|
@ -251,7 +253,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't emit when event is not related with defined groups" do
|
it "doesn't emit when event is not related with defined groups" do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: like_hook.id,
|
web_hook_id: like_hook.id,
|
||||||
event_type: "like",
|
event_type: "like",
|
||||||
group_ids: [Fabricate(:group).id],
|
group_ids: [Fabricate(:group).id],
|
||||||
|
@ -264,7 +266,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
body: "{\"like\":{\"test\":\"some payload\"}}",
|
body: "{\"like\":{\"test\":\"some payload\"}}",
|
||||||
).to_return(body: "OK", status: 200)
|
).to_return(body: "OK", status: 200)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: like_hook.id,
|
web_hook_id: like_hook.id,
|
||||||
event_type: "like",
|
event_type: "like",
|
||||||
group_ids: user.groups.pluck(:id),
|
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
|
web_hook_id = Fabricate("#{topic_event_type.name}_web_hook").id
|
||||||
|
|
||||||
expect do
|
expect do
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: web_hook_id,
|
web_hook_id: web_hook_id,
|
||||||
event_type: topic_event_type.name,
|
event_type: topic_event_type.name,
|
||||||
payload: { test: "some payload" }.to_json,
|
payload: { test: "some payload" }.to_json,
|
||||||
|
@ -298,7 +300,7 @@ RSpec.describe Jobs::EmitWebHookEvent do
|
||||||
status: 200,
|
status: 200,
|
||||||
)
|
)
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: described_class::PING_EVENT,
|
event_type: described_class::PING_EVENT,
|
||||||
event_name: 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
|
it "sets up proper request headers when an error raised" do
|
||||||
stub_request(:post, post_hook.payload_url).to_raise("error")
|
stub_request(:post, post_hook.payload_url).to_raise("error")
|
||||||
|
|
||||||
subject.execute(
|
job.execute(
|
||||||
web_hook_id: post_hook.id,
|
web_hook_id: post_hook.id,
|
||||||
event_type: described_class::PING_EVENT,
|
event_type: described_class::PING_EVENT,
|
||||||
event_name: described_class::PING_EVENT,
|
event_name: described_class::PING_EVENT,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::EnqueueSuspectUsers do
|
RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
before { SiteSetting.approve_suspect_users = true }
|
before { SiteSetting.approve_suspect_users = true }
|
||||||
|
|
||||||
it "does nothing when there are no suspect users" do
|
it "does nothing when there are no suspect users" do
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.count).to be_zero
|
expect(ReviewableUser.count).to be_zero
|
||||||
end
|
end
|
||||||
|
@ -13,7 +15,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
let!(:suspect_user) { Fabricate(:active_user, created_at: 1.day.ago) }
|
let!(:suspect_user) { Fabricate(:active_user, created_at: 1.day.ago) }
|
||||||
|
|
||||||
it "creates a reviewable when there is a suspect user" do
|
it "creates a reviewable when there is a suspect user" do
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.count).to eq(1)
|
expect(ReviewableUser.count).to eq(1)
|
||||||
end
|
end
|
||||||
|
@ -26,14 +28,14 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
reviewable_by_moderator: true,
|
reviewable_by_moderator: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.count).to eq(1)
|
expect(ReviewableUser.count).to eq(1)
|
||||||
expect(ReviewableUser.last).to eq(review_user)
|
expect(ReviewableUser.last).to eq(review_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "adds a score" do
|
it "adds a score" do
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
score = ReviewableScore.last
|
score = ReviewableScore.last
|
||||||
|
|
||||||
expect(score.reason).to eq("suspect_user")
|
expect(score.reason).to eq("suspect_user")
|
||||||
|
@ -42,7 +44,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
it "only enqueues non-approved users" do
|
it "only enqueues non-approved users" do
|
||||||
suspect_user.update!(approved: true)
|
suspect_user.update!(approved: true)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -51,7 +53,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
SiteSetting.must_approve_users = true
|
SiteSetting.must_approve_users = true
|
||||||
suspect_user.update!(approved: false)
|
suspect_user.update!(approved: false)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -59,7 +61,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
it "ignores users created more than six months ago" do
|
it "ignores users created more than six months ago" do
|
||||||
suspect_user.update!(created_at: 1.year.ago)
|
suspect_user.update!(created_at: 1.year.ago)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -67,7 +69,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
it "ignores users that were imported from another site" do
|
it "ignores users that were imported from another site" do
|
||||||
suspect_user.upsert_custom_fields({ import_id: "fake_id" })
|
suspect_user.upsert_custom_fields({ import_id: "fake_id" })
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -75,7 +77,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
it "enqueues a suspect users with custom fields" do
|
it "enqueues a suspect users with custom fields" do
|
||||||
suspect_user.upsert_custom_fields({ field_a: "value", field_b: "value" })
|
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)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -85,7 +87,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
{ field_a: "value", field_b: "value", import_id: "fake_id" },
|
{ field_a: "value", field_b: "value", import_id: "fake_id" },
|
||||||
)
|
)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
expect(ReviewableUser.where(target: suspect_user).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -97,7 +99,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
time_read: 30.seconds.to_i,
|
time_read: 30.seconds.to_i,
|
||||||
)
|
)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.count).to eq(1)
|
expect(ReviewableUser.count).to eq(1)
|
||||||
end
|
end
|
||||||
|
@ -109,7 +111,7 @@ RSpec.describe Jobs::EnqueueSuspectUsers do
|
||||||
time_read: 2.minutes.to_i,
|
time_read: 2.minutes.to_i,
|
||||||
)
|
)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
|
|
||||||
expect(ReviewableUser.count).to eq(0)
|
expect(ReviewableUser.count).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::EnsureS3UploadsExistence do
|
RSpec.describe Jobs::EnsureS3UploadsExistence do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
context "with S3 inventory enabled" do
|
context "with S3 inventory enabled" do
|
||||||
before do
|
before do
|
||||||
setup_s3
|
setup_s3
|
||||||
|
@ -9,21 +11,21 @@ RSpec.describe Jobs::EnsureS3UploadsExistence do
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once
|
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't execute when the site was restored within the last 48 hours" do
|
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
|
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).never
|
||||||
BackupMetadata.update_last_restore_date(47.hours.ago)
|
BackupMetadata.update_last_restore_date(47.hours.ago)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "executes when the site was restored more than 48 hours ago" do
|
it "executes when the site was restored more than 48 hours ago" do
|
||||||
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once
|
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).once
|
||||||
BackupMetadata.update_last_restore_date(49.hours.ago)
|
BackupMetadata.update_last_restore_date(49.hours.ago)
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,7 +34,7 @@ RSpec.describe Jobs::EnsureS3UploadsExistence do
|
||||||
|
|
||||||
it "doesn't execute" do
|
it "doesn't execute" do
|
||||||
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).never
|
S3Inventory.any_instance.expects(:backfill_etags_and_list_missing).never
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::IgnoredUsersSummary do
|
RSpec.describe Jobs::IgnoredUsersSummary do
|
||||||
|
subject(:job) { Jobs::IgnoredUsersSummary.new.execute({}) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
SiteSetting.ignored_users_count_message_threshold = 1
|
SiteSetting.ignored_users_count_message_threshold = 1
|
||||||
SiteSetting.ignored_users_message_gap_days = 365
|
SiteSetting.ignored_users_message_gap_days = 365
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { Jobs::IgnoredUsersSummary.new.execute({}) }
|
|
||||||
|
|
||||||
context "with no ignored users" do
|
context "with no ignored users" do
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
subject
|
job
|
||||||
expect { subject }.to_not change { Post.count }
|
expect { job }.to_not change { Post.count }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,14 +30,14 @@ RSpec.describe Jobs::IgnoredUsersSummary do
|
||||||
before { SiteSetting.ignored_users_count_message_threshold = 5 }
|
before { SiteSetting.ignored_users_count_message_threshold = 5 }
|
||||||
|
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
subject
|
job
|
||||||
expect { subject }.to_not change { Post.count }
|
expect { job }.to_not change { Post.count }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when threshold is hit" do
|
context "when threshold is hit" do
|
||||||
it "creates a system message" do
|
it "creates a system message" do
|
||||||
subject
|
job
|
||||||
posts =
|
posts =
|
||||||
Post.joins(:topic).where(
|
Post.joins(:topic).where(
|
||||||
topics: {
|
topics: {
|
||||||
|
@ -57,15 +57,15 @@ RSpec.describe Jobs::IgnoredUsersSummary do
|
||||||
before { SiteSetting.ignored_users_count_message_threshold = 5 }
|
before { SiteSetting.ignored_users_count_message_threshold = 5 }
|
||||||
|
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
subject
|
job
|
||||||
expect { subject }.to_not change { Post.count }
|
expect { job }.to_not change { Post.count }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when threshold is hit" do
|
context "when threshold is hit" do
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
subject
|
job
|
||||||
expect { subject }.to_not change { Post.count }
|
expect { job }.to_not change { Post.count }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::InvalidateInactiveAdmins do
|
RSpec.describe Jobs::InvalidateInactiveAdmins do
|
||||||
fab!(:active_admin) { Fabricate(:admin, last_seen_at: 1.hour.ago) }
|
subject(:job) { Jobs::InvalidateInactiveAdmins.new.execute({}) }
|
||||||
before { active_admin.email_tokens.update_all(confirmed: true) }
|
|
||||||
|
|
||||||
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
|
it "does nothing when all admins have been seen recently" do
|
||||||
SiteSetting.invalidate_inactive_admin_email_after_days = 365
|
SiteSetting.invalidate_inactive_admin_email_after_days = 365
|
||||||
subject
|
job
|
||||||
expect(active_admin.reload.active).to eq(true)
|
expect(active_admin.reload.active).to eq(true)
|
||||||
expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true)
|
expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -21,12 +22,12 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do
|
||||||
before { SiteSetting.invalidate_inactive_admin_email_after_days = 365 }
|
before { SiteSetting.invalidate_inactive_admin_email_after_days = 365 }
|
||||||
|
|
||||||
it "marks email tokens as unconfirmed" do
|
it "marks email tokens as unconfirmed" do
|
||||||
subject
|
job
|
||||||
expect(not_seen_admin.reload.email_tokens.where(confirmed: true).exists?).to eq(false)
|
expect(not_seen_admin.reload.email_tokens.where(confirmed: true).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "makes the user as not active and logs the action" do
|
it "makes the user as not active and logs the action" do
|
||||||
subject
|
job
|
||||||
expect(not_seen_admin.reload.active).to eq(false)
|
expect(not_seen_admin.reload.active).to eq(false)
|
||||||
|
|
||||||
log = UserHistory.last
|
log = UserHistory.last
|
||||||
|
@ -35,7 +36,7 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "adds a staff log" do
|
it "adds a staff log" do
|
||||||
subject
|
job
|
||||||
expect(not_seen_admin.reload.active).to eq(false)
|
expect(not_seen_admin.reload.active).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,20 +53,20 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes the social logins" do
|
it "removes the social logins" do
|
||||||
subject
|
job
|
||||||
expect(UserAssociatedAccount.where(user_id: not_seen_admin.id).exists?).to eq(false)
|
expect(UserAssociatedAccount.where(user_id: not_seen_admin.id).exists?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't deactivate admins with recent posts" do
|
it "doesn't deactivate admins with recent posts" do
|
||||||
Fabricate(:post, user: not_seen_admin)
|
Fabricate(:post, user: not_seen_admin)
|
||||||
subject
|
job
|
||||||
expect(not_seen_admin.reload.active).to eq(true)
|
expect(not_seen_admin.reload.active).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't deactivate admins with recently used api keys" do
|
it "doesn't deactivate admins with recently used api keys" do
|
||||||
Fabricate(:api_key, user: not_seen_admin, last_used_at: 1.day.ago)
|
Fabricate(:api_key, user: not_seen_admin, last_used_at: 1.day.ago)
|
||||||
subject
|
job
|
||||||
expect(not_seen_admin.reload.active).to eq(true)
|
expect(not_seen_admin.reload.active).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -74,7 +75,7 @@ RSpec.describe Jobs::InvalidateInactiveAdmins do
|
||||||
before { SiteSetting.invalidate_inactive_admin_email_after_days = 0 }
|
before { SiteSetting.invalidate_inactive_admin_email_after_days = 0 }
|
||||||
|
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
subject
|
job
|
||||||
expect(active_admin.reload.active).to eq(true)
|
expect(active_admin.reload.active).to eq(true)
|
||||||
expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true)
|
expect(active_admin.email_tokens.where(confirmed: true).exists?).to eq(true)
|
||||||
expect(not_seen_admin.reload.active).to eq(true)
|
expect(not_seen_admin.reload.active).to eq(true)
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::PostUpdateTopicTrackingState do
|
RSpec.describe Jobs::PostUpdateTopicTrackingState do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:post) { Fabricate(:post) }
|
fab!(:post) { Fabricate(:post) }
|
||||||
|
|
||||||
it "should publish messages" do
|
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)
|
expect(messages.size).not_to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not publish messages for deleted topics" do
|
it "should not publish messages for deleted topics" do
|
||||||
post.topic.trash!
|
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)
|
expect(messages.size).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::ProcessShelvedNotifications do
|
RSpec.describe Jobs::ProcessShelvedNotifications do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
let(:post) { Fabricate(:post) }
|
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)
|
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)
|
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: future.id)).to eq(future)
|
||||||
expect(DoNotDisturbTiming.find_by(id: past.id)).to eq(nil)
|
expect(DoNotDisturbTiming.find_by(id: past.id)).to eq(nil)
|
||||||
end
|
end
|
||||||
|
@ -25,7 +27,7 @@ RSpec.describe Jobs::ProcessShelvedNotifications do
|
||||||
notification_type: 1,
|
notification_type: 1,
|
||||||
)
|
)
|
||||||
expect(notification.shelved_notification).to be_present
|
expect(notification.shelved_notification).to be_present
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
expect(notification.shelved_notification).to be_present
|
expect(notification.shelved_notification).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ RSpec.describe Jobs::ProcessShelvedNotifications do
|
||||||
user.do_not_disturb_timings.last.update(ends_at: 1.days.ago)
|
user.do_not_disturb_timings.last.update(ends_at: 1.days.ago)
|
||||||
|
|
||||||
expect(notification.shelved_notification).to be_present
|
expect(notification.shelved_notification).to be_present
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
expect { notification.shelved_notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
expect { notification.shelved_notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -472,25 +472,25 @@ RSpec.describe Jobs::PullHotlinkedImages do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#should_download_image?" do
|
describe "#should_download_image?" do
|
||||||
subject { described_class.new }
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
describe "when url is invalid" do
|
describe "when url is invalid" do
|
||||||
it "should return false" do
|
it "should return false" do
|
||||||
expect(subject.should_download_image?("null")).to eq(false)
|
expect(job.should_download_image?("null")).to eq(false)
|
||||||
expect(subject.should_download_image?("meta.discourse.org")).to eq(false)
|
expect(job.should_download_image?("meta.discourse.org")).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when url is valid" do
|
describe "when url is valid" do
|
||||||
it "should return true" do
|
it "should return true" do
|
||||||
expect(subject.should_download_image?("http://meta.discourse.org")).to eq(true)
|
expect(job.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?("//meta.discourse.org")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when url is an upload" do
|
describe "when url is an upload" do
|
||||||
it "should return false for original" 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
|
end
|
||||||
|
|
||||||
context "when secure uploads enabled" do
|
context "when secure uploads enabled" do
|
||||||
|
@ -501,19 +501,19 @@ RSpec.describe Jobs::PullHotlinkedImages do
|
||||||
upload = Fabricate(:upload_s3, secure: true)
|
upload = Fabricate(:upload_s3, secure: true)
|
||||||
stub_s3(upload)
|
stub_s3(upload)
|
||||||
url = Upload.secure_uploads_url_from_upload_url(upload.url)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true for optimized" do
|
it "should return true for optimized" do
|
||||||
src = Discourse.store.get_path_for_optimized_image(Fabricate(:optimized_image))
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false for emoji" do
|
it "returns false for emoji" do
|
||||||
src = Emoji.url_for("testemoji.png")
|
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
|
end
|
||||||
|
|
||||||
it "returns false for emoji when app and S3 CDNs configured" do
|
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"
|
set_cdn_url "https://mydomain.cdn/test"
|
||||||
|
|
||||||
src = UrlHelper.cook_url(Emoji.url_for("testemoji.png"))
|
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
|
end
|
||||||
|
|
||||||
it "returns false for emoji when emoji CDN configured" do
|
it "returns false for emoji when emoji CDN configured" do
|
||||||
SiteSetting.external_emoji_url = "https://emoji.cdn.com"
|
SiteSetting.external_emoji_url = "https://emoji.cdn.com"
|
||||||
|
|
||||||
src = UrlHelper.cook_url(Emoji.url_for("testemoji.png"))
|
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
|
end
|
||||||
|
|
||||||
it "returns false for emoji when app, S3 *and* emoji CDNs configured" do
|
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"
|
set_cdn_url "https://mydomain.cdn/test"
|
||||||
|
|
||||||
src = UrlHelper.cook_url(Emoji.url_for("testemoji.png"))
|
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
|
end
|
||||||
|
|
||||||
it "returns false for plugin assets" do
|
it "returns false for plugin assets" do
|
||||||
src = UrlHelper.cook_url("/plugins/discourse-amazing-plugin/myasset.png")
|
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
|
end
|
||||||
|
|
||||||
it "returns false for local non-uploaded files" do
|
it "returns false for local non-uploaded files" do
|
||||||
src = UrlHelper.cook_url("/mycustomroute.png")
|
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
|
end
|
||||||
|
|
||||||
context "when download_remote_images_to_local? is false" do
|
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
|
it "still returns true for optimized" do
|
||||||
src = Discourse.store.get_path_for_optimized_image(Fabricate(:optimized_image))
|
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 valid remote URLs" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::PurgeExpiredIgnoredUsers do
|
RSpec.describe Jobs::PurgeExpiredIgnoredUsers do
|
||||||
subject { Jobs::PurgeExpiredIgnoredUsers.new.execute({}) }
|
subject(:job) { Jobs::PurgeExpiredIgnoredUsers.new.execute({}) }
|
||||||
|
|
||||||
context "with no ignored users" do
|
context "with no ignored users" do
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
expect { subject }.to_not change { IgnoredUser.count }
|
expect { job }.to_not change { IgnoredUser.count }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ RSpec.describe Jobs::PurgeExpiredIgnoredUsers do
|
||||||
|
|
||||||
context "when no expired ignored users" do
|
context "when no expired ignored users" do
|
||||||
it "does nothing" do
|
it "does nothing" do
|
||||||
expect { subject }.to_not change { IgnoredUser.count }
|
expect { job }.to_not change { IgnoredUser.count }
|
||||||
end
|
end
|
||||||
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)
|
Fabricate(:ignored_user, user: tarek, ignored_user: fred, expiring_at: 1.month.from_now)
|
||||||
|
|
||||||
freeze_time(2.months.from_now) do
|
freeze_time(2.months.from_now) do
|
||||||
subject
|
job
|
||||||
expect(IgnoredUser.find_by(ignored_user: fred)).to be_nil
|
expect(IgnoredUser.find_by(ignored_user: fred)).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::GroupSmtpEmail do
|
RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:topic) { Fabricate(:private_message_topic, title: "Help I need support") }
|
fab!(:topic) { Fabricate(:private_message_topic, title: "Help I need support") }
|
||||||
fab!(:post) do
|
fab!(:post) do
|
||||||
Fabricate(:post, topic: topic, raw: "some first post content")
|
Fabricate(:post, topic: topic, raw: "some first post content")
|
||||||
|
@ -46,11 +48,11 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
bcc_addresses: [],
|
bcc_addresses: [],
|
||||||
)
|
)
|
||||||
.returns(message)
|
.returns(message)
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes a 'reply above this line' message" do
|
it "includes a 'reply above this line' message" do
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
email_log =
|
email_log =
|
||||||
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
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(
|
expect(email_log.as_mail_message.html_part.to_s).to include(
|
||||||
|
@ -59,7 +61,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not include context posts" do
|
it "does not include context posts" do
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
email_log =
|
email_log =
|
||||||
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
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(
|
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)
|
second_post = topic.posts.find_by(post_number: 2)
|
||||||
post.update!(reply_to_post_number: 1, reply_to_user: second_post.user)
|
post.update!(reply_to_post_number: 1, reply_to_user: second_post.user)
|
||||||
PostReply.create(post: second_post, reply: post)
|
PostReply.create(post: second_post, reply: post)
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
email_log =
|
email_log =
|
||||||
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
||||||
expect(email_log.raw_headers).to include(
|
expect(email_log.raw_headers).to include(
|
||||||
|
@ -84,7 +86,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes the participants in the correct format (but not the recipient user), and does not have links for the staged users" do
|
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 =
|
email_log =
|
||||||
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
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
|
email_text = email_log.as_mail_message.text_part.to_s
|
||||||
|
@ -98,7 +100,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates an EmailLog record with the correct details" do
|
it "creates an EmailLog record with the correct details" do
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
email_log =
|
email_log =
|
||||||
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
EmailLog.find_by(post_id: post.id, topic_id: post.topic_id, user_id: recipient_user.id)
|
||||||
expect(email_log).not_to eq(nil)
|
expect(email_log).not_to eq(nil)
|
||||||
|
@ -106,7 +108,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates an IncomingEmail record with the correct details to avoid double processing IMAP" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
incoming_email =
|
incoming_email =
|
||||||
|
@ -120,7 +122,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create a post reply key, it always replies to the group email_username" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
email_log =
|
email_log =
|
||||||
|
@ -132,7 +134,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates an EmailLog record with the correct details" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
email_log =
|
email_log =
|
||||||
|
@ -142,7 +144,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates an IncomingEmail record with the correct details to avoid double processing IMAP" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
incoming_email =
|
incoming_email =
|
||||||
|
@ -156,7 +158,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create a post reply key, it always replies to the group email_username" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
email_log =
|
email_log =
|
||||||
|
@ -169,7 +171,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
|
|
||||||
it "falls back to the group name if full name is blank" do
|
it "falls back to the group name if full name is blank" do
|
||||||
group.update(full_name: "")
|
group.update(full_name: "")
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
email_log =
|
email_log =
|
||||||
|
@ -178,7 +180,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has the group_smtp_id and the to_address filled in correctly" do
|
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.count).to eq(1)
|
||||||
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
expect(ActionMailer::Base.deliveries.last.subject).to eq("Re: Help I need support")
|
||||||
email_log =
|
email_log =
|
||||||
|
@ -190,7 +192,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
it "drops malformed cc addresses when sending the email" do
|
it "drops malformed cc addresses when sending the email" do
|
||||||
args2 = args.clone
|
args2 = args.clone
|
||||||
args2[:cc_emails] << "somebadccemail@test.com<mailto:somebadccemail@test.com"
|
args2[:cc_emails] << "somebadccemail@test.com<mailto:somebadccemail@test.com"
|
||||||
subject.execute(args2)
|
job.execute(args2)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
||||||
last_email = ActionMailer::Base.deliveries.last
|
last_email = ActionMailer::Base.deliveries.last
|
||||||
expect(last_email.subject).to eq("Re: Help I need support")
|
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
|
context "when there are cc_addresses" do
|
||||||
it "has the cc_addresses and cc_user_ids filled in correctly" 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)
|
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
||||||
sent_mail = ActionMailer::Base.deliveries.last
|
sent_mail = ActionMailer::Base.deliveries.last
|
||||||
expect(sent_mail.subject).to eq("Re: Help I need support")
|
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
|
it "where cc_addresses match non-staged users, convert to bcc_addresses" do
|
||||||
staged2.update!(staged: false, active: true)
|
staged2.update!(staged: false, active: true)
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
||||||
sent_mail = ActionMailer::Base.deliveries.last
|
sent_mail = ActionMailer::Base.deliveries.last
|
||||||
expect(sent_mail.subject).to eq("Re: Help I need support")
|
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) }
|
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
|
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)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -242,7 +244,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
before { group.update!(imap_enabled: false) }
|
before { group.update!(imap_enabled: false) }
|
||||||
|
|
||||||
it "sends the email as expected" do
|
it "sends the email as expected" do
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -251,7 +253,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when the post is deleted" do
|
context "when the post is deleted" do
|
||||||
it "aborts and adds a skipped email log" do
|
it "aborts and adds a skipped email log" do
|
||||||
post.trash!
|
post.trash!
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
expect(
|
expect(
|
||||||
SkippedEmailLog.exists?(
|
SkippedEmailLog.exists?(
|
||||||
|
@ -268,7 +270,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when the topic is deleted" do
|
context "when the topic is deleted" do
|
||||||
it "aborts and adds a skipped email log" do
|
it "aborts and adds a skipped email log" do
|
||||||
post.topic.trash!
|
post.topic.trash!
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
expect(
|
expect(
|
||||||
SkippedEmailLog.exists?(
|
SkippedEmailLog.exists?(
|
||||||
|
@ -285,7 +287,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when smtp is not enabled" do
|
context "when smtp is not enabled" do
|
||||||
it "returns without sending email" do
|
it "returns without sending email" do
|
||||||
SiteSetting.enable_smtp = false
|
SiteSetting.enable_smtp = false
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -293,7 +295,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when disable_emails is yes" do
|
context "when disable_emails is yes" do
|
||||||
it "returns without sending email" do
|
it "returns without sending email" do
|
||||||
SiteSetting.disable_emails = "yes"
|
SiteSetting.disable_emails = "yes"
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -301,7 +303,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when group is deleted" do
|
context "when group is deleted" do
|
||||||
it "returns without sending email" do
|
it "returns without sending email" do
|
||||||
group.destroy
|
group.destroy
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -309,7 +311,7 @@ RSpec.describe Jobs::GroupSmtpEmail do
|
||||||
context "when smtp is not enabled for the group" do
|
context "when smtp is not enabled for the group" do
|
||||||
it "returns without sending email" do
|
it "returns without sending email" do
|
||||||
group.update!(smtp_enabled: false)
|
group.update!(smtp_enabled: false)
|
||||||
subject.execute(args)
|
job.execute(args)
|
||||||
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
||||||
expect(
|
expect(
|
||||||
SkippedEmailLog.exists?(
|
SkippedEmailLog.exists?(
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::PublishGroupMembershipUpdates do
|
describe Jobs::PublishGroupMembershipUpdates do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
fab!(:group) { Fabricate(:group) }
|
fab!(:group) { Fabricate(:group) }
|
||||||
|
|
||||||
it "publishes events for added users" do
|
it "publishes events for added users" do
|
||||||
events =
|
events =
|
||||||
DiscourseEvent.track_events do
|
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
|
end
|
||||||
|
|
||||||
expect(events).to include(
|
expect(events).to include(
|
||||||
|
@ -19,7 +21,7 @@ describe Jobs::PublishGroupMembershipUpdates do
|
||||||
it "publishes events for removed users" do
|
it "publishes events for removed users" do
|
||||||
events =
|
events =
|
||||||
DiscourseEvent.track_events do
|
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
|
end
|
||||||
|
|
||||||
expect(events).to include(event_name: :user_removed_from_group, params: [user, group])
|
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
|
it "does nothing if the group doesn't exist" do
|
||||||
events =
|
events =
|
||||||
DiscourseEvent.track_events do
|
DiscourseEvent.track_events { job.execute(user_ids: [user.id], group_id: nil, type: "add") }
|
||||||
subject.execute(user_ids: [user.id], group_id: nil, type: "add")
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(events).not_to include(
|
expect(events).not_to include(
|
||||||
event_name: :user_added_to_group,
|
event_name: :user_added_to_group,
|
||||||
|
@ -38,7 +38,7 @@ describe Jobs::PublishGroupMembershipUpdates do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fails when the update type is invalid" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -46,7 +46,7 @@ describe Jobs::PublishGroupMembershipUpdates do
|
||||||
it "does nothing when the user is not human" do
|
it "does nothing when the user is not human" do
|
||||||
events =
|
events =
|
||||||
DiscourseEvent.track_events do
|
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
|
end
|
||||||
|
|
||||||
expect(events).not_to include(
|
expect(events).not_to include(
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::ReindexSearch do
|
RSpec.describe Jobs::ReindexSearch do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
|
let(:locale) { "fr" }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
SearchIndexer.enable
|
SearchIndexer.enable
|
||||||
Jobs.run_immediately!
|
Jobs.run_immediately!
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:locale) { "fr" }
|
|
||||||
# This works since test db has a small record less than limit.
|
# This works since test db has a small record less than limit.
|
||||||
# Didn't check `topic` because topic doesn't have posts in fabrication
|
# Didn't check `topic` because topic doesn't have posts in fabrication
|
||||||
# thus no search data
|
# thus no search data
|
||||||
|
@ -15,7 +18,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
SiteSetting.default_locale = "en"
|
SiteSetting.default_locale = "en"
|
||||||
model = Fabricate(m.to_sym)
|
model = Fabricate(m.to_sym)
|
||||||
SiteSetting.default_locale = locale
|
SiteSetting.default_locale = locale
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
expect(model.public_send("#{m}_search_data").locale).to eq locale
|
expect(model.public_send("#{m}_search_data").locale).to eq locale
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
search_data.update!(version: 0)
|
search_data.update!(version: 0)
|
||||||
model.reload
|
model.reload
|
||||||
|
|
||||||
subject.execute({})
|
job.execute({})
|
||||||
expect(model.public_send("#{m}_search_data").version).to eq(
|
expect(model.public_send("#{m}_search_data").version).to eq(
|
||||||
"SearchIndexer::#{m.upcase}_INDEX_VERSION".constantize,
|
"SearchIndexer::#{m.upcase}_INDEX_VERSION".constantize,
|
||||||
)
|
)
|
||||||
|
@ -64,7 +67,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
post2.topic.trash!
|
post2.topic.trash!
|
||||||
post3.trash!
|
post3.trash!
|
||||||
|
|
||||||
subject.rebuild_posts(indexer: FakeIndexer)
|
job.rebuild_posts(indexer: FakeIndexer)
|
||||||
|
|
||||||
expect(FakeIndexer.posts).to contain_exactly(post)
|
expect(FakeIndexer.posts).to contain_exactly(post)
|
||||||
end
|
end
|
||||||
|
@ -72,7 +75,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
it "should not reindex posts with a developmental version" do
|
it "should not reindex posts with a developmental version" do
|
||||||
Fabricate(:post, version: SearchIndexer::POST_INDEX_VERSION + 1)
|
Fabricate(:post, version: SearchIndexer::POST_INDEX_VERSION + 1)
|
||||||
|
|
||||||
subject.rebuild_posts(indexer: FakeIndexer)
|
job.rebuild_posts(indexer: FakeIndexer)
|
||||||
|
|
||||||
expect(FakeIndexer.posts).to eq([])
|
expect(FakeIndexer.posts).to eq([])
|
||||||
end
|
end
|
||||||
|
@ -85,7 +88,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
|
|
||||||
post2.save!(validate: false)
|
post2.save!(validate: false)
|
||||||
|
|
||||||
subject.rebuild_posts(indexer: FakeIndexer)
|
job.rebuild_posts(indexer: FakeIndexer)
|
||||||
|
|
||||||
expect(FakeIndexer.posts).to contain_exactly(post)
|
expect(FakeIndexer.posts).to contain_exactly(post)
|
||||||
end
|
end
|
||||||
|
@ -100,7 +103,7 @@ RSpec.describe Jobs::ReindexSearch do
|
||||||
|
|
||||||
freeze_time(1.day.ago) { topic.trash! }
|
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(Topic.pluck(:id)).to contain_exactly(topic2.id)
|
||||||
|
|
||||||
expect(TopicSearchData.pluck(:topic_id)).to contain_exactly(topic2.topic_search_data.topic_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!
|
post6.trash!
|
||||||
end
|
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)
|
expect(Post.pluck(:id)).to contain_exactly(post.id, post2.id, post3.id, post4.id, post5.id)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::SyncTopicUserBookmarked do
|
RSpec.describe Jobs::SyncTopicUserBookmarked do
|
||||||
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:topic) { Fabricate(:topic) }
|
fab!(:topic) { Fabricate(:topic) }
|
||||||
fab!(:post1) { Fabricate(:post, topic: topic) }
|
fab!(:post1) { Fabricate(:post, topic: topic) }
|
||||||
fab!(:post2) { 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: tu1.user, bookmarkable: topic.posts.sample)
|
||||||
Fabricate(:bookmark, user: tu4.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(tu1.reload.bookmarked).to eq(true)
|
||||||
expect(tu2.reload.bookmarked).to eq(false)
|
expect(tu2.reload.bookmarked).to eq(false)
|
||||||
|
@ -31,7 +33,7 @@ RSpec.describe Jobs::SyncTopicUserBookmarked do
|
||||||
|
|
||||||
post1.trash!
|
post1.trash!
|
||||||
|
|
||||||
subject.execute(topic_id: topic.id)
|
job.execute(topic_id: topic.id)
|
||||||
|
|
||||||
expect(tu1.reload.bookmarked).to eq(false)
|
expect(tu1.reload.bookmarked).to eq(false)
|
||||||
expect(tu2.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: tu1.user, bookmarkable: topic.posts.sample)
|
||||||
Fabricate(:bookmark, user: tu4.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(tu1.reload.bookmarked).to eq(true)
|
||||||
expect(tu2.reload.bookmarked).to eq(false)
|
expect(tu2.reload.bookmarked).to eq(false)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Jobs::TopicTimerEnqueuer do
|
RSpec.describe Jobs::TopicTimerEnqueuer do
|
||||||
subject { described_class.new }
|
subject(:job) { described_class.new }
|
||||||
|
|
||||||
fab!(:timer1) do
|
fab!(:timer1) do
|
||||||
Fabricate(
|
Fabricate(
|
||||||
|
@ -40,20 +40,20 @@ RSpec.describe Jobs::TopicTimerEnqueuer do
|
||||||
|
|
||||||
it "does not enqueue deleted timers" do
|
it "does not enqueue deleted timers" 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: deleted_timer.id })
|
||||||
subject.execute
|
job.execute
|
||||||
expect(deleted_timer.topic.reload.closed?).to eq(false)
|
expect(deleted_timer.topic.reload.closed?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not enqueue future timers" do
|
it "does not enqueue future timers" do
|
||||||
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: future_timer.id })
|
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)
|
expect(future_timer.topic.reload.closed?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the related job" do
|
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: deleted_timer.id })
|
||||||
expect_not_enqueued_with(job: :close_topic, args: { topic_timer_id: future_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: :close_topic, args: { topic_timer_id: timer1.id })
|
||||||
expect_job_enqueued(job: :open_topic, args: { topic_timer_id: timer2.id })
|
expect_job_enqueued(job: :open_topic, args: { topic_timer_id: timer2.id })
|
||||||
end
|
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
|
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 })
|
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)
|
Jobs.enqueue_at(1.hours.from_now, :close_topic, topic_timer_id: timer1.id)
|
||||||
subject.execute
|
job.execute
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not fail to enqueue other timers just because one timer errors" do
|
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)
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
require_relative "shared_context_for_backup_restore"
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::DatabaseRestorer, type: :multisite do
|
RSpec.describe BackupRestore::DatabaseRestorer, type: :multisite do
|
||||||
|
subject(:restorer) { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
||||||
|
|
||||||
include_context "with shared stuff"
|
include_context "with shared stuff"
|
||||||
|
|
||||||
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
||||||
|
|
||||||
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
|
||||||
|
|
||||||
describe "#restore" do
|
describe "#restore" do
|
||||||
context "with database connection" do
|
context "with database connection" do
|
||||||
it "reconnects to the correct database" do
|
it "reconnects to the correct database" do
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
require_relative "shared_context_for_backup_restore"
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::DatabaseRestorer do
|
RSpec.describe BackupRestore::DatabaseRestorer do
|
||||||
|
subject(:restorer) { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
||||||
|
|
||||||
include_context "with shared stuff"
|
include_context "with shared stuff"
|
||||||
|
|
||||||
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
||||||
|
|
||||||
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
|
||||||
|
|
||||||
describe "#restore" do
|
describe "#restore" do
|
||||||
it "executes everything in the correct order" do
|
it "executes everything in the correct order" do
|
||||||
restore = sequence("restore")
|
restore = sequence("restore")
|
||||||
|
@ -18,7 +18,7 @@ RSpec.describe BackupRestore::DatabaseRestorer do
|
||||||
expect_db_migrate.in_sequence(restore)
|
expect_db_migrate.in_sequence(restore)
|
||||||
expect_db_reconnect.in_sequence(restore)
|
expect_db_reconnect.in_sequence(restore)
|
||||||
|
|
||||||
subject.restore("foo.sql")
|
restorer.restore("foo.sql")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "stores the date of the last restore" do
|
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
|
it "moves tables back when tables were moved" do
|
||||||
BackupRestore.stubs(:can_rollback?).returns(true)
|
BackupRestore.stubs(:can_rollback?).returns(true)
|
||||||
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").never
|
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").never
|
||||||
subject.rollback
|
restorer.rollback
|
||||||
|
|
||||||
execute_stubbed_restore
|
execute_stubbed_restore
|
||||||
|
|
||||||
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").once
|
BackupRestore.expects(:move_tables_between_schemas).with("backup", "public").once
|
||||||
subject.rollback
|
restorer.rollback
|
||||||
end
|
end
|
||||||
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
|
it "doesn't try to drop function when no functions have been created" do
|
||||||
Migration::BaseDropper.expects(:drop_readonly_function).never
|
Migration::BaseDropper.expects(:drop_readonly_function).never
|
||||||
subject.clean_up
|
restorer.clean_up
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates and drops all functions when none exist" do
|
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, :via_email)
|
||||||
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :raw_email)
|
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :raw_email)
|
||||||
subject.clean_up
|
restorer.clean_up
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates and drops only missing functions during restore" do
|
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)
|
execute_stubbed_restore(stub_readonly_functions: false)
|
||||||
|
|
||||||
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :via_email)
|
Migration::BaseDropper.expects(:drop_readonly_function).with(:posts, :via_email)
|
||||||
subject.clean_up
|
restorer.clean_up
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".drop_backup_schema" do
|
describe ".drop_backup_schema" do
|
||||||
subject { BackupRestore::DatabaseRestorer }
|
|
||||||
|
|
||||||
context "when no backup schema exists" do
|
context "when no backup schema exists" do
|
||||||
it "doesn't do anything" do
|
it "doesn't do anything" do
|
||||||
ActiveRecord::Base.connection.expects(:schema_exists?).with("backup").returns(false)
|
ActiveRecord::Base.connection.expects(:schema_exists?).with("backup").returns(false)
|
||||||
ActiveRecord::Base.connection.expects(:drop_schema).never
|
ActiveRecord::Base.connection.expects(:drop_schema).never
|
||||||
|
|
||||||
subject.drop_backup_schema
|
described_class.drop_backup_schema
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -209,14 +207,14 @@ RSpec.describe BackupRestore::DatabaseRestorer do
|
||||||
ActiveRecord::Base.connection.expects(:drop_schema).with("backup")
|
ActiveRecord::Base.connection.expects(:drop_schema).with("backup")
|
||||||
BackupMetadata.update_last_restore_date(8.days.ago)
|
BackupMetadata.update_last_restore_date(8.days.ago)
|
||||||
|
|
||||||
subject.drop_backup_schema
|
described_class.drop_backup_schema
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't drop the schema when the last restore was recently" do
|
it "doesn't drop the schema when the last restore was recently" do
|
||||||
ActiveRecord::Base.connection.expects(:drop_schema).with("backup").never
|
ActiveRecord::Base.connection.expects(:drop_schema).with("backup").never
|
||||||
BackupMetadata.update_last_restore_date(6.days.ago)
|
BackupMetadata.update_last_restore_date(6.days.ago)
|
||||||
|
|
||||||
subject.drop_backup_schema
|
described_class.drop_backup_schema
|
||||||
end
|
end
|
||||||
|
|
||||||
it "stores the current date when there is no record of the last restore" do
|
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"
|
date_string = "2020-01-08T17:38:27Z"
|
||||||
freeze_time(Time.parse(date_string))
|
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)
|
expect(BackupMetadata.value_for(BackupMetadata::LAST_RESTORE_DATE)).to eq(date_string)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,8 @@ require "backup_restore/local_backup_store"
|
||||||
require_relative "shared_examples_for_backup_store"
|
require_relative "shared_examples_for_backup_store"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::LocalBackupStore do
|
RSpec.describe BackupRestore::LocalBackupStore do
|
||||||
|
subject(:store) { BackupRestore::BackupStore.create(root_directory: @root_directory) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@root_directory = Dir.mktmpdir
|
@root_directory = Dir.mktmpdir
|
||||||
@paths = []
|
@paths = []
|
||||||
|
@ -12,7 +14,6 @@ RSpec.describe BackupRestore::LocalBackupStore do
|
||||||
|
|
||||||
after { FileUtils.remove_dir(@root_directory, true) }
|
after { FileUtils.remove_dir(@root_directory, true) }
|
||||||
|
|
||||||
subject(:store) { BackupRestore::BackupStore.create(root_directory: @root_directory) }
|
|
||||||
let(:expected_type) { BackupRestore::LocalBackupStore }
|
let(:expected_type) { BackupRestore::LocalBackupStore }
|
||||||
|
|
||||||
it_behaves_like "backup store"
|
it_behaves_like "backup store"
|
||||||
|
|
|
@ -5,6 +5,8 @@ require "backup_restore/s3_backup_store"
|
||||||
require_relative "shared_examples_for_backup_store"
|
require_relative "shared_examples_for_backup_store"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::S3BackupStore do
|
RSpec.describe BackupRestore::S3BackupStore do
|
||||||
|
subject(:store) { BackupRestore::BackupStore.create(s3_options: @s3_options) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@s3_client = Aws::S3::Client.new(stub_responses: true)
|
@s3_client = Aws::S3::Client.new(stub_responses: true)
|
||||||
@s3_options = { client: @s3_client }
|
@s3_options = { client: @s3_client }
|
||||||
|
@ -86,7 +88,6 @@ RSpec.describe BackupRestore::S3BackupStore do
|
||||||
SiteSetting.backup_location = BackupLocationSiteSetting::S3
|
SiteSetting.backup_location = BackupLocationSiteSetting::S3
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:store) { BackupRestore::BackupStore.create(s3_options: @s3_options) }
|
|
||||||
let(:expected_type) { BackupRestore::S3BackupStore }
|
let(:expected_type) { BackupRestore::S3BackupStore }
|
||||||
|
|
||||||
it_behaves_like "backup store"
|
it_behaves_like "backup store"
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
require_relative "shared_context_for_backup_restore"
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::SystemInterface, type: :multisite do
|
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
|
describe "#flush_redis" do
|
||||||
it "removes only keys from the current site in a multisite" 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("foo")).to eq("second-foo")
|
||||||
expect(Discourse.redis.get("bar")).to eq("second-bar")
|
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("foo")).to be_nil
|
||||||
expect(Discourse.redis.get("bar")).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!
|
BackupRestore.mark_as_running!
|
||||||
|
|
||||||
expect do
|
expect do
|
||||||
thread = subject.listen_for_shutdown_signal
|
thread = system_interface.listen_for_shutdown_signal
|
||||||
BackupRestore.set_shutdown_signal!
|
BackupRestore.set_shutdown_signal!
|
||||||
thread.join
|
thread.join
|
||||||
end.to raise_error(SystemExit)
|
end.to raise_error(SystemExit)
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
require_relative "shared_context_for_backup_restore"
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::SystemInterface do
|
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
|
describe "readonly mode" do
|
||||||
after { Discourse::READONLY_KEYS.each { |key| Discourse.redis.del(key) } }
|
after { Discourse::READONLY_KEYS.each { |key| Discourse.redis.del(key) } }
|
||||||
|
@ -13,26 +13,26 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
describe "#enable_readonly_mode" do
|
describe "#enable_readonly_mode" do
|
||||||
it "enables readonly mode" do
|
it "enables readonly mode" do
|
||||||
Discourse.expects(:enable_readonly_mode).once
|
Discourse.expects(:enable_readonly_mode).once
|
||||||
subject.enable_readonly_mode
|
system_interface.enable_readonly_mode
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not enable readonly mode when it is already in readonly mode" do
|
it "does not enable readonly mode when it is already in readonly mode" do
|
||||||
Discourse.enable_readonly_mode
|
Discourse.enable_readonly_mode
|
||||||
Discourse.expects(:enable_readonly_mode).never
|
Discourse.expects(:enable_readonly_mode).never
|
||||||
subject.enable_readonly_mode
|
system_interface.enable_readonly_mode
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#disable_readonly_mode" do
|
describe "#disable_readonly_mode" do
|
||||||
it "disables readonly mode" do
|
it "disables readonly mode" do
|
||||||
Discourse.expects(:disable_readonly_mode).once
|
Discourse.expects(:disable_readonly_mode).once
|
||||||
subject.disable_readonly_mode
|
system_interface.disable_readonly_mode
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not disable readonly mode when readonly mode was explicitly enabled" do
|
it "does not disable readonly mode when readonly mode was explicitly enabled" do
|
||||||
Discourse.enable_readonly_mode
|
Discourse.enable_readonly_mode
|
||||||
Discourse.expects(:disable_readonly_mode).never
|
Discourse.expects(:disable_readonly_mode).never
|
||||||
subject.disable_readonly_mode
|
system_interface.disable_readonly_mode
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -40,14 +40,14 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
describe "#mark_restore_as_running" do
|
describe "#mark_restore_as_running" do
|
||||||
it "calls mark_restore_as_running" do
|
it "calls mark_restore_as_running" do
|
||||||
BackupRestore.expects(:mark_as_running!).once
|
BackupRestore.expects(:mark_as_running!).once
|
||||||
subject.mark_restore_as_running
|
system_interface.mark_restore_as_running
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#mark_restore_as_not_running" do
|
describe "#mark_restore_as_not_running" do
|
||||||
it "calls mark_restore_as_not_running" do
|
it "calls mark_restore_as_not_running" do
|
||||||
BackupRestore.expects(:mark_as_not_running!).once
|
BackupRestore.expects(:mark_as_not_running!).once
|
||||||
subject.mark_restore_as_not_running
|
system_interface.mark_restore_as_not_running
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
|
|
||||||
it "exits the process when shutdown signal is set" do
|
it "exits the process when shutdown signal is set" do
|
||||||
expect do
|
expect do
|
||||||
thread = subject.listen_for_shutdown_signal
|
thread = system_interface.listen_for_shutdown_signal
|
||||||
BackupRestore.set_shutdown_signal!
|
BackupRestore.set_shutdown_signal!
|
||||||
thread.join
|
thread.join
|
||||||
end.to raise_error(SystemExit)
|
end.to raise_error(SystemExit)
|
||||||
|
@ -71,7 +71,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
BackupRestore.set_shutdown_signal!
|
BackupRestore.set_shutdown_signal!
|
||||||
expect(BackupRestore.should_shutdown?).to eq(true)
|
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)
|
expect(BackupRestore.should_shutdown?).to eq(false)
|
||||||
Thread.kill(thread)
|
Thread.kill(thread)
|
||||||
end
|
end
|
||||||
|
@ -82,7 +82,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
|
|
||||||
it "calls pause!" do
|
it "calls pause!" do
|
||||||
expect(Sidekiq.paused?).to eq(false)
|
expect(Sidekiq.paused?).to eq(false)
|
||||||
subject.pause_sidekiq("my reason")
|
system_interface.pause_sidekiq("my reason")
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
expect(Discourse.redis.get(SidekiqPauser::PAUSED_KEY)).to eq("my reason")
|
expect(Discourse.redis.get(SidekiqPauser::PAUSED_KEY)).to eq("my reason")
|
||||||
end
|
end
|
||||||
|
@ -93,15 +93,15 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
Sidekiq.pause!
|
Sidekiq.pause!
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
|
|
||||||
subject.unpause_sidekiq
|
system_interface.unpause_sidekiq
|
||||||
expect(Sidekiq.paused?).to eq(false)
|
expect(Sidekiq.paused?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#wait_for_sidekiq" do
|
describe "#wait_for_sidekiq" do
|
||||||
it "waits 6 seconds even when there are no running Sidekiq jobs" do
|
it "waits 6 seconds even when there are no running Sidekiq jobs" do
|
||||||
subject.expects(:sleep).with(6).once
|
system_interface.expects(:sleep).with(6).once
|
||||||
subject.wait_for_sidekiq
|
system_interface.wait_for_sidekiq
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with Sidekiq workers" do
|
context "with Sidekiq workers" do
|
||||||
|
@ -146,22 +146,26 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "waits up to 60 seconds for jobs running for the current site to finish" do
|
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
|
create_workers
|
||||||
expect { subject.wait_for_sidekiq }.to raise_error(BackupRestore::RunningSidekiqJobsError)
|
expect { system_interface.wait_for_sidekiq }.to raise_error(
|
||||||
|
BackupRestore::RunningSidekiqJobsError,
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "waits up to 60 seconds for jobs running on all sites to finish" do
|
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)
|
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
|
end
|
||||||
|
|
||||||
it "ignores jobs of other sites" do
|
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")
|
create_workers(site_id: "another_site")
|
||||||
|
|
||||||
subject.wait_for_sidekiq
|
system_interface.wait_for_sidekiq
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -172,7 +176,7 @@ RSpec.describe BackupRestore::SystemInterface do
|
||||||
|
|
||||||
it "doesn't unpause Sidekiq" do
|
it "doesn't unpause Sidekiq" do
|
||||||
Sidekiq.pause!
|
Sidekiq.pause!
|
||||||
subject.flush_redis
|
system_interface.flush_redis
|
||||||
|
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
require_relative "shared_context_for_backup_restore"
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
RSpec.describe BackupRestore::UploadsRestorer do
|
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)
|
def with_temp_uploads_directory(name: "default", with_optimized: false)
|
||||||
Dir.mktmpdir do |directory|
|
Dir.mktmpdir do |directory|
|
||||||
|
@ -93,7 +93,7 @@ RSpec.describe BackupRestore::UploadsRestorer do
|
||||||
|
|
||||||
def setup_and_restore(directory, metadata)
|
def setup_and_restore(directory, metadata)
|
||||||
metadata.each { |d| BackupMetadata.create!(d) }
|
metadata.each { |d| BackupMetadata.create!(d) }
|
||||||
subject.restore(directory)
|
restorer.restore(directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
def uploads_path(database)
|
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_site_name) { target_site_type == multisite ? "second" : "default" }
|
||||||
let(:target_hostname) { target_site_type == multisite ? "test2.localhost" : "test.localhost" }
|
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
|
it "does nothing when temporary uploads directory is missing or empty" do
|
||||||
store_class.any_instance.expects(:copy_from).never
|
store_class.any_instance.expects(:copy_from).never
|
||||||
|
|
||||||
Dir.mktmpdir do |directory|
|
Dir.mktmpdir do |directory|
|
||||||
subject.restore(directory)
|
restorer.restore(directory)
|
||||||
|
|
||||||
FileUtils.mkdir(File.join(directory, "uploads"))
|
FileUtils.mkdir(File.join(directory, "uploads"))
|
||||||
subject.restore(directory)
|
restorer.restore(directory)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -176,7 +176,7 @@ RSpec.describe BackupRestore::UploadsRestorer do
|
||||||
with_temp_uploads_directory do |directory, path|
|
with_temp_uploads_directory do |directory, path|
|
||||||
store_class.any_instance.expects(:copy_from).with(path).once
|
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,
|
-1,
|
||||||
).and change { Jobs::CreateAvatarThumbnails.jobs.size }.by(1).and change {
|
).and change { Jobs::CreateAvatarThumbnails.jobs.size }.by(1).and change {
|
||||||
Post.where(baked_version: nil).count
|
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|
|
with_temp_uploads_directory(with_optimized: true) do |directory, path|
|
||||||
store_class.any_instance.expects(:copy_from).with(path).once
|
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
|
OptimizedImage.count
|
||||||
}.and not_change { Jobs::CreateAvatarThumbnails.jobs.size }.and change {
|
}.and not_change { Jobs::CreateAvatarThumbnails.jobs.size }.and change {
|
||||||
Post.where(baked_version: nil).count
|
Post.where(baked_version: nil).count
|
||||||
|
@ -609,14 +609,14 @@ RSpec.describe BackupRestore::UploadsRestorer do
|
||||||
Discourse.stubs(:store).returns(Object.new)
|
Discourse.stubs(:store).returns(Object.new)
|
||||||
|
|
||||||
with_temp_uploads_directory do |directory|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an exception when there are multiple folders in the uploads directory" do
|
it "raises an exception when there are multiple folders in the uploads directory" do
|
||||||
with_temp_uploads_directory do |directory|
|
with_temp_uploads_directory do |directory|
|
||||||
FileUtils.mkdir_p(File.join(directory, "uploads", "foo"))
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe BookmarkManager do
|
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) }
|
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
|
describe ".destroy" do
|
||||||
let!(:bookmark) { Fabricate(:bookmark, user: user, bookmarkable: post) }
|
let!(:bookmark) { Fabricate(:bookmark, user: user, bookmarkable: post) }
|
||||||
it "deletes the existing bookmark" do
|
it "deletes the existing bookmark" do
|
||||||
subject.destroy(bookmark.id)
|
manager.destroy(bookmark.id)
|
||||||
expect(Bookmark.exists?(id: bookmark.id)).to eq(false)
|
expect(Bookmark.exists?(id: bookmark.id)).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "if the bookmark is the last one bookmarked in the topic" do
|
context "if the bookmark is the last one bookmarked in the topic" do
|
||||||
it "marks the topic user bookmarked column as false" do
|
it "marks the topic user bookmarked column as false" do
|
||||||
TopicUser.create(user: user, topic: post.topic, bookmarked: true)
|
TopicUser.create(user: user, topic: post.topic, bookmarked: true)
|
||||||
subject.destroy(bookmark.id)
|
manager.destroy(bookmark.id)
|
||||||
tu = TopicUser.find_by(user: user)
|
tu = TopicUser.find_by(user: user)
|
||||||
expect(tu.bookmarked).to eq(false)
|
expect(tu.bookmarked).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -28,13 +28,13 @@ RSpec.describe BookmarkManager do
|
||||||
context "if the bookmark is belonging to some other user" do
|
context "if the bookmark is belonging to some other user" do
|
||||||
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin), bookmarkable: post) }
|
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin), bookmarkable: post) }
|
||||||
it "raises an invalid access error" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context "if the bookmark no longer exists" do
|
context "if the bookmark no longer exists" do
|
||||||
it "raises a not found error" 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
|
end
|
||||||
end
|
end
|
||||||
|
@ -53,7 +53,7 @@ RSpec.describe BookmarkManager do
|
||||||
let(:options) { {} }
|
let(:options) { {} }
|
||||||
|
|
||||||
def update_bookmark
|
def update_bookmark
|
||||||
subject.update(
|
manager.update(
|
||||||
bookmark_id: bookmark.id,
|
bookmark_id: bookmark.id,
|
||||||
name: new_name,
|
name: new_name,
|
||||||
reminder_at: new_reminder_at,
|
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
|
it "does not reminder_last_sent_at if reminder did not change" do
|
||||||
bookmark.update(reminder_last_sent_at: 1.day.ago)
|
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
|
bookmark.reload
|
||||||
expect(bookmark.reminder_last_sent_at).not_to eq(nil)
|
expect(bookmark.reminder_last_sent_at).not_to eq(nil)
|
||||||
end
|
end
|
||||||
|
@ -112,20 +112,20 @@ RSpec.describe BookmarkManager do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "destroys all bookmarks for the topic for the specified user" do
|
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)
|
expect(Bookmark.for_user_in_topic(user.id, topic.id).length).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not destroy any other user's topic bookmarks" do
|
it "does not destroy any other user's topic bookmarks" do
|
||||||
user2 = Fabricate(:user)
|
user2 = Fabricate(:user)
|
||||||
Fabricate(:bookmark, bookmarkable: Fabricate(:post, topic: topic), user: user2)
|
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)
|
expect(Bookmark.for_user_in_topic(user2.id, topic.id).length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the topic user bookmarked column to false" do
|
it "updates the topic user bookmarked column to false" do
|
||||||
TopicUser.create(user: user, topic: topic, bookmarked: true)
|
TopicUser.create(user: user, topic: topic, bookmarked: true)
|
||||||
subject.destroy_for_topic(topic)
|
manager.destroy_for_topic(topic)
|
||||||
tu = TopicUser.find_by(user: user)
|
tu = TopicUser.find_by(user: user)
|
||||||
expect(tu.bookmarked).to eq(false)
|
expect(tu.bookmarked).to eq(false)
|
||||||
end
|
end
|
||||||
|
@ -176,20 +176,20 @@ RSpec.describe BookmarkManager do
|
||||||
|
|
||||||
it "sets pinned to false if it is true" do
|
it "sets pinned to false if it is true" do
|
||||||
bookmark.update(pinned: true)
|
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)
|
expect(bookmark.reload.pinned).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets pinned to true if it is false" do
|
it "sets pinned to true if it is false" do
|
||||||
bookmark.update(pinned: false)
|
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)
|
expect(bookmark.reload.pinned).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "if the bookmark is belonging to some other user" do
|
context "if the bookmark is belonging to some other user" do
|
||||||
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin)) }
|
let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin)) }
|
||||||
it "raises an invalid access error" do
|
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,
|
Discourse::InvalidAccess,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -198,18 +198,18 @@ RSpec.describe BookmarkManager do
|
||||||
context "if the bookmark no longer exists" do
|
context "if the bookmark no longer exists" do
|
||||||
before { bookmark.destroy! }
|
before { bookmark.destroy! }
|
||||||
it "raises a not found error" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#create_for" do
|
describe "#create_for" do
|
||||||
it "allows creating a bookmark for the topic and for the first post" 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)
|
bookmark = Bookmark.find_by(user: user, bookmarkable: post.topic)
|
||||||
expect(bookmark.present?).to eq(true)
|
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)
|
bookmark = Bookmark.find_by(user: user, bookmarkable: post)
|
||||||
expect(bookmark).not_to eq(nil)
|
expect(bookmark).not_to eq(nil)
|
||||||
end
|
end
|
||||||
|
@ -217,26 +217,26 @@ RSpec.describe BookmarkManager do
|
||||||
it "when topic is deleted it raises invalid access from guardian check" do
|
it "when topic is deleted it raises invalid access from guardian check" do
|
||||||
post.topic.trash!
|
post.topic.trash!
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "when post is deleted it raises invalid access from guardian check" do
|
it "when post is deleted it raises invalid access from guardian check" do
|
||||||
post.trash!
|
post.trash!
|
||||||
expect do
|
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.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "adds a validation error when the bookmarkable_type is not registered" do
|
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)
|
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "BlahFactory", name: name)
|
||||||
expect(subject.errors.full_messages).to include(
|
expect(manager.errors.full_messages).to include(
|
||||||
I18n.t("bookmarks.errors.invalid_bookmarkable", type: "BlahFactory"),
|
I18n.t("bookmarks.errors.invalid_bookmarkable", type: "BlahFactory"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the topic user bookmarked column to true if any post is bookmarked" do
|
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_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -246,14 +246,14 @@ RSpec.describe BookmarkManager do
|
||||||
expect(tu.bookmarked).to eq(true)
|
expect(tu.bookmarked).to eq(true)
|
||||||
tu.update(bookmarked: false)
|
tu.update(bookmarked: false)
|
||||||
new_post = Fabricate(:post, topic: post.topic)
|
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
|
tu.reload
|
||||||
expect(tu.bookmarked).to eq(true)
|
expect(tu.bookmarked).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets auto_delete_preference to clear_reminder by default" do
|
it "sets auto_delete_preference to clear_reminder by default" do
|
||||||
bookmark =
|
bookmark =
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
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
|
it "sets auto_delete_preferences to the user's user_option.bookmark_auto_delete_preference" do
|
||||||
bookmark =
|
bookmark =
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
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
|
it "uses the passed in auto_delete_preference option instead of the user's one" do
|
||||||
bookmark =
|
bookmark =
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -303,7 +303,7 @@ RSpec.describe BookmarkManager do
|
||||||
|
|
||||||
context "when a reminder time is provided" do
|
context "when a reminder time is provided" do
|
||||||
it "saves the values correctly" do
|
it "saves the values correctly" do
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -322,7 +322,7 @@ RSpec.describe BookmarkManager do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "saves any additional options successfully" do
|
it "saves any additional options successfully" do
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -339,8 +339,8 @@ RSpec.describe BookmarkManager do
|
||||||
before { Bookmark.create(bookmarkable: post, user: user) }
|
before { Bookmark.create(bookmarkable: post, user: user) }
|
||||||
|
|
||||||
it "adds an error to the manager" do
|
it "adds an error to the manager" do
|
||||||
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post")
|
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post")
|
||||||
expect(subject.errors.full_messages).to include(
|
expect(manager.errors.full_messages).to include(
|
||||||
I18n.t("bookmarks.errors.already_bookmarked", type: "Post"),
|
I18n.t("bookmarks.errors.already_bookmarked", type: "Post"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -348,8 +348,8 @@ RSpec.describe BookmarkManager do
|
||||||
|
|
||||||
context "when the bookmark name is too long" do
|
context "when the bookmark name is too long" do
|
||||||
it "adds an error to the manager" do
|
it "adds an error to the manager" do
|
||||||
subject.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: "test" * 100)
|
manager.create_for(bookmarkable_id: post.id, bookmarkable_type: "Post", name: "test" * 100)
|
||||||
expect(subject.errors.full_messages).to include(
|
expect(manager.errors.full_messages).to include(
|
||||||
"Name is too long (maximum is 100 characters)",
|
"Name is too long (maximum is 100 characters)",
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -359,13 +359,13 @@ RSpec.describe BookmarkManager do
|
||||||
let(:reminder_at) { 10.days.ago }
|
let(:reminder_at) { 10.days.ago }
|
||||||
|
|
||||||
it "adds an error to the manager" do
|
it "adds an error to the manager" do
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
reminder_at: reminder_at,
|
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"),
|
I18n.t("bookmarks.errors.cannot_set_past_reminder"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -375,13 +375,13 @@ RSpec.describe BookmarkManager do
|
||||||
let(:reminder_at) { 11.years.from_now }
|
let(:reminder_at) { 11.years.from_now }
|
||||||
|
|
||||||
it "adds an error to the manager" do
|
it "adds an error to the manager" do
|
||||||
subject.create_for(
|
manager.create_for(
|
||||||
bookmarkable_id: post.id,
|
bookmarkable_id: post.id,
|
||||||
bookmarkable_type: "Post",
|
bookmarkable_type: "Post",
|
||||||
name: name,
|
name: name,
|
||||||
reminder_at: reminder_at,
|
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"),
|
I18n.t("bookmarks.errors.cannot_set_reminder_in_distant_future"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -391,7 +391,7 @@ RSpec.describe BookmarkManager do
|
||||||
before { post.trash! }
|
before { post.trash! }
|
||||||
it "raises an invalid access error" do
|
it "raises an invalid access error" do
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -400,7 +400,7 @@ RSpec.describe BookmarkManager do
|
||||||
before { post.topic.update(category: Fabricate(:private_category, group: Fabricate(:group))) }
|
before { post.topic.update(category: Fabricate(:private_category, group: Fabricate(:group))) }
|
||||||
it "raises an invalid access error" do
|
it "raises an invalid access error" do
|
||||||
expect {
|
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)
|
}.to raise_error(Discourse::InvalidAccess)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe BookmarkReminderNotificationHandler do
|
RSpec.describe BookmarkReminderNotificationHandler do
|
||||||
subject { described_class }
|
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
before { Discourse.redis.flushdb }
|
before { Discourse.redis.flushdb }
|
||||||
|
|
||||||
describe "#send_notification" do
|
describe "#send_notification" do
|
||||||
|
subject(:send_notification) { handler.send_notification }
|
||||||
|
|
||||||
|
let(:handler) { described_class.new(bookmark) }
|
||||||
let!(:bookmark) do
|
let!(:bookmark) do
|
||||||
Fabricate(:bookmark_next_business_day_reminder, user: user, bookmarkable: Fabricate(:post))
|
Fabricate(:bookmark_next_business_day_reminder, user: user, bookmarkable: Fabricate(:post))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a bookmark reminder notification with the correct details" do
|
it "creates a bookmark reminder notification with the correct details" do
|
||||||
subject.new(bookmark).send_notification
|
send_notification
|
||||||
notif = bookmark.user.notifications.last
|
notif = bookmark.user.notifications.last
|
||||||
expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder])
|
expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder])
|
||||||
expect(notif.topic_id).to eq(bookmark.bookmarkable.topic_id)
|
expect(notif.topic_id).to eq(bookmark.bookmarkable.topic_id)
|
||||||
|
@ -32,7 +33,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not send a notification and updates last notification attempt time" do
|
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
|
expect(bookmark.reload.reminder_last_sent_at).not_to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -46,12 +47,12 @@ RSpec.describe BookmarkReminderNotificationHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "deletes the bookmark after the reminder gets sent" do
|
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)
|
expect(Bookmark.find_by(id: bookmark.id)).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "changes the TopicUser bookmarked column to false" do
|
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(
|
expect(TopicUser.find_by(topic: bookmark.bookmarkable.topic, user: user).bookmarked).to eq(
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
@ -67,7 +68,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not change the TopicUser bookmarked column to false" do
|
it "does not change the TopicUser bookmarked column to false" do
|
||||||
subject.new(bookmark).send_notification
|
send_notification
|
||||||
expect(
|
expect(
|
||||||
TopicUser.find_by(topic: bookmark.bookmarkable.topic, user: user).bookmarked,
|
TopicUser.find_by(topic: bookmark.bookmarkable.topic, user: user).bookmarked,
|
||||||
).to eq(true)
|
).to eq(true)
|
||||||
|
@ -82,7 +83,7 @@ RSpec.describe BookmarkReminderNotificationHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "resets reminder_at after the reminder gets sent" do
|
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)
|
expect(Bookmark.find_by(id: bookmark.id).reminder_at).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,32 +6,32 @@ RSpec.describe CommonPasswords do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#common_password?" do
|
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
|
it "returns false if password isn't in the common passwords list" do
|
||||||
described_class.stubs(:password_list).returns(stub_everything(include?: false))
|
described_class.stubs(:password_list).returns(stub_everything(include?: false))
|
||||||
@password = "uncommonPassword"
|
@password = "uncommonPassword"
|
||||||
expect(subject).to eq(false)
|
expect(common_password).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false if password is nil" do
|
it "returns false if password is nil" do
|
||||||
described_class.expects(:password_list).never
|
described_class.expects(:password_list).never
|
||||||
@password = nil
|
@password = nil
|
||||||
expect(subject).to eq(false)
|
expect(common_password).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false if password is blank" do
|
it "returns false if password is blank" do
|
||||||
described_class.expects(:password_list).never
|
described_class.expects(:password_list).never
|
||||||
@password = ""
|
@password = ""
|
||||||
expect(subject).to eq(false)
|
expect(common_password).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns true if password is in the common passwords list" do
|
it "returns true if password is in the common passwords list" do
|
||||||
described_class.stubs(:password_list).returns(stub_everything(include?: true))
|
described_class.stubs(:password_list).returns(stub_everything(include?: true))
|
||||||
@password = "password"
|
@password = "password"
|
||||||
expect(subject).to eq(true)
|
expect(common_password).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe DiscourseUpdates do
|
||||||
DiscourseUpdates.updated_at = updated_at
|
DiscourseUpdates.updated_at = updated_at
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { DiscourseUpdates.check_version }
|
subject(:version) { DiscourseUpdates.check_version }
|
||||||
|
|
||||||
context "when version check was done at the current installed version" do
|
context "when version check was done at the current installed version" do
|
||||||
before { DiscourseUpdates.last_installed_version = Discourse::VERSION::STRING }
|
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) }
|
before { stub_data(Discourse::VERSION::STRING, 0, false, time) }
|
||||||
|
|
||||||
it "returns all the version fields" do
|
it "returns all the version fields" do
|
||||||
expect(subject.latest_version).to eq(Discourse::VERSION::STRING)
|
expect(version.latest_version).to eq(Discourse::VERSION::STRING)
|
||||||
expect(subject.missing_versions_count).to eq(0)
|
expect(version.missing_versions_count).to eq(0)
|
||||||
expect(subject.critical_updates).to eq(false)
|
expect(version.critical_updates).to eq(false)
|
||||||
expect(subject.installed_version).to eq(Discourse::VERSION::STRING)
|
expect(version.installed_version).to eq(Discourse::VERSION::STRING)
|
||||||
expect(subject.stale_data).to eq(false)
|
expect(version.stale_data).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the timestamp of the last version check" do
|
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
|
end
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ RSpec.describe DiscourseUpdates do
|
||||||
before { stub_data("0.9.0", 2, false, time) }
|
before { stub_data("0.9.0", 2, false, time) }
|
||||||
|
|
||||||
it "returns all the version fields" do
|
it "returns all the version fields" do
|
||||||
expect(subject.latest_version).to eq("0.9.0")
|
expect(version.latest_version).to eq("0.9.0")
|
||||||
expect(subject.missing_versions_count).to eq(2)
|
expect(version.missing_versions_count).to eq(2)
|
||||||
expect(subject.critical_updates).to eq(false)
|
expect(version.critical_updates).to eq(false)
|
||||||
expect(subject.installed_version).to eq(Discourse::VERSION::STRING)
|
expect(version.installed_version).to eq(Discourse::VERSION::STRING)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the timestamp of the last version check" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,22 +52,22 @@ RSpec.describe DiscourseUpdates do
|
||||||
before { stub_data(nil, nil, false, nil) }
|
before { stub_data(nil, nil, false, nil) }
|
||||||
|
|
||||||
it "returns the installed version" do
|
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
|
end
|
||||||
|
|
||||||
it "indicates that version check has not been performed" do
|
it "indicates that version check has not been performed" do
|
||||||
expect(subject.updated_at).to eq(nil)
|
expect(version.updated_at).to eq(nil)
|
||||||
expect(subject.stale_data).to eq(true)
|
expect(version.stale_data).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not return latest version info" do
|
it "does not return latest version info" do
|
||||||
expect(subject.latest_version).to eq(nil)
|
expect(version.latest_version).to eq(nil)
|
||||||
expect(subject.missing_versions_count).to eq(nil)
|
expect(version.missing_versions_count).to eq(nil)
|
||||||
expect(subject.critical_updates).to eq(nil)
|
expect(version.critical_updates).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "queues a version check" do
|
it "queues a version check" do
|
||||||
expect_enqueued_with(job: :version_check) { subject }
|
expect_enqueued_with(job: :version_check) { version }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,15 +76,15 @@ RSpec.describe DiscourseUpdates do
|
||||||
context "with old version check data" do
|
context "with old version check data" do
|
||||||
shared_examples "queue version check and report that version is ok" do
|
shared_examples "queue version check and report that version is ok" do
|
||||||
it "queues a version check" do
|
it "queues a version check" do
|
||||||
expect_enqueued_with(job: :version_check) { subject }
|
expect_enqueued_with(job: :version_check) { version }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reports 0 missing versions" do
|
it "reports 0 missing versions" do
|
||||||
expect(subject.missing_versions_count).to eq(0)
|
expect(version.missing_versions_count).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reports that a version check will be run soon" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -105,15 +105,15 @@ RSpec.describe DiscourseUpdates do
|
||||||
|
|
||||||
shared_examples "when last_installed_version is old" do
|
shared_examples "when last_installed_version is old" do
|
||||||
it "queues a version check" do
|
it "queues a version check" do
|
||||||
expect_enqueued_with(job: :version_check) { subject }
|
expect_enqueued_with(job: :version_check) { version }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reports 0 missing versions" do
|
it "reports 0 missing versions" do
|
||||||
expect(subject.missing_versions_count).to eq(0)
|
expect(version.missing_versions_count).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reports that a version check will be run soon" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ require "email/message_builder"
|
||||||
|
|
||||||
RSpec.describe Email::MessageBuilder do
|
RSpec.describe Email::MessageBuilder do
|
||||||
let(:to_address) { "jake@adventuretime.ooo" }
|
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(: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(:build_args) { builder.build_args }
|
||||||
let(:header_args) { builder.header_args }
|
let(:header_args) { builder.header_args }
|
||||||
let(:allow_reply_header) { described_class::ALLOW_REPLY_BY_EMAIL_HEADER }
|
let(:allow_reply_header) { described_class::ALLOW_REPLY_BY_EMAIL_HEADER }
|
||||||
|
@ -16,7 +16,7 @@ RSpec.describe Email::MessageBuilder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has the subject" do
|
it "has the subject" do
|
||||||
expect(builder.subject).to eq(subject)
|
expect(builder.subject).to eq(email_subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has the body" do
|
it "has the body" do
|
||||||
|
|
|
@ -6,8 +6,8 @@ describe FinalDestination::SSRFDetector do
|
||||||
SiteSetting.blocked_ip_blocks = "13.134.89.0/24|73.234.19.0/30\n"
|
SiteSetting.blocked_ip_blocks = "13.134.89.0/24|73.234.19.0/30\n"
|
||||||
SiteSetting.allowed_internal_hosts = "awesomesauce.com\n|goodbye.net"
|
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(described_class.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.allowed_internal_hosts).to eq(
|
||||||
[
|
[
|
||||||
"test.localhost", # Discourse.base_url
|
"test.localhost", # Discourse.base_url
|
||||||
"awesomesauce.com",
|
"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.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"
|
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(described_class.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.allowed_internal_hosts).to eq(
|
||||||
[
|
[
|
||||||
"test.localhost", # Discourse.base_url
|
"test.localhost", # Discourse.base_url
|
||||||
"awesomesauce.com",
|
"awesomesauce.com",
|
||||||
|
@ -32,90 +32,90 @@ describe FinalDestination::SSRFDetector do
|
||||||
|
|
||||||
it "ignores invalid IP blocks" do
|
it "ignores invalid IP blocks" do
|
||||||
SiteSetting.blocked_ip_blocks = "2001:abc:de::/48|notanip"
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".ip_allowed?" do
|
describe ".ip_allowed?" do
|
||||||
it "returns false for blocked IPs" 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"
|
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(described_class.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?("9001:82f3:8873::3")).to eq(false)
|
||||||
end
|
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|
|
%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
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false for private IPv4-mapped IPv6 addresses" do
|
it "returns false for private IPv4-mapped IPv6 addresses" do
|
||||||
expect(subject.ip_allowed?("::ffff:172.31.100.31")).to eq(false)
|
expect(described_class.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:0.0.0.0")).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns true for public IPv4-mapped IPv6 addresses" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".host_bypasses_checks?" do
|
describe ".host_bypasses_checks?" do
|
||||||
it "returns true for URLs when allowed_internal_hosts allows the host" do
|
it "returns true for URLs when allowed_internal_hosts allows the host" do
|
||||||
SiteSetting.allowed_internal_hosts = "allowedhost1.com|allowedhost2.com"
|
SiteSetting.allowed_internal_hosts = "allowedhost1.com|allowedhost2.com"
|
||||||
expect(subject.host_bypasses_checks?("allowedhost1.com")).to eq(true)
|
expect(described_class.host_bypasses_checks?("allowedhost1.com")).to eq(true)
|
||||||
expect(subject.host_bypasses_checks?("allowedhost2.com")).to eq(true)
|
expect(described_class.host_bypasses_checks?("allowedhost2.com")).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false for other hosts" do
|
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
|
end
|
||||||
|
|
||||||
it "returns true for the base uri" do
|
it "returns true for the base uri" do
|
||||||
SiteSetting.force_hostname = "final-test.example.com"
|
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
|
end
|
||||||
|
|
||||||
it "returns true for the S3 CDN url" do
|
it "returns true for the S3 CDN url" do
|
||||||
SiteSetting.enable_s3_uploads = true
|
SiteSetting.enable_s3_uploads = true
|
||||||
SiteSetting.s3_cdn_url = "https://s3.example.com"
|
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
|
end
|
||||||
|
|
||||||
it "returns true for the CDN url" do
|
it "returns true for the CDN url" do
|
||||||
GlobalSetting.stubs(:cdn_url).returns("https://cdn.example.com/discourse")
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".lookup_and_filter_ips" do
|
describe ".lookup_and_filter_ips" do
|
||||||
it "returns a fake response in tests" 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
|
end
|
||||||
|
|
||||||
it "correctly filters private and blocked IPs" do
|
it "correctly filters private and blocked IPs" do
|
||||||
SiteSetting.blocked_ip_blocks = "9.10.11.12/24"
|
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])
|
described_class.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"])
|
expect(described_class.lookup_and_filter_ips("example.com")).to eq(["5.6.7.8"])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an exception if all IPs are blocked" do
|
it "raises an exception if all IPs are blocked" do
|
||||||
subject.stubs(:lookup_ips).returns(["127.0.0.1"])
|
described_class.stubs(:lookup_ips).returns(["127.0.0.1"])
|
||||||
expect { subject.lookup_and_filter_ips("example.com") }.to raise_error(
|
expect { described_class.lookup_and_filter_ips("example.com") }.to raise_error(
|
||||||
subject::DisallowedIpError,
|
described_class::DisallowedIpError,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an exception if lookup fails" do
|
it "raises an exception if lookup fails" do
|
||||||
subject.stubs(:lookup_ips).raises(SocketError)
|
described_class.stubs(:lookup_ips).raises(SocketError)
|
||||||
expect { subject.lookup_and_filter_ips("example.com") }.to raise_error(
|
expect { described_class.lookup_and_filter_ips("example.com") }.to raise_error(
|
||||||
subject::LookupFailedError,
|
described_class::LookupFailedError,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "bypasses filtering for allowlisted hosts" do
|
it "bypasses filtering for allowlisted hosts" do
|
||||||
SiteSetting.allowed_internal_hosts = "example.com"
|
SiteSetting.allowed_internal_hosts = "example.com"
|
||||||
subject.stubs(:lookup_ips).returns(["127.0.0.1"])
|
described_class.stubs(:lookup_ips).returns(["127.0.0.1"])
|
||||||
expect(subject.lookup_and_filter_ips("example.com")).to eq(["127.0.0.1"])
|
expect(described_class.lookup_and_filter_ips("example.com")).to eq(["127.0.0.1"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,14 +39,14 @@ RSpec.describe Imap::Sync do
|
||||||
|
|
||||||
describe "no previous sync" do
|
describe "no previous sync" do
|
||||||
let(:from) { "john@free.fr" }
|
let(:from) { "john@free.fr" }
|
||||||
let(:subject) { "Testing email post" }
|
let(:email_subject) { "Testing email post" }
|
||||||
let(:message_id) { "#{SecureRandom.hex}@example.com" }
|
let(:message_id) { "#{SecureRandom.hex}@example.com" }
|
||||||
|
|
||||||
let(:email) do
|
let(:email) do
|
||||||
EmailFabricator(
|
EmailFabricator(
|
||||||
from: from,
|
from: from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
message_id: message_id,
|
message_id: message_id,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -80,7 +80,7 @@ RSpec.describe Imap::Sync do
|
||||||
expect(group.imap_last_uid).to eq(100)
|
expect(group.imap_last_uid).to eq(100)
|
||||||
|
|
||||||
topic = Topic.last
|
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.user.email).to eq(from)
|
||||||
expect(topic.tags.pluck(:name)).to contain_exactly("seen", "important", "test-label")
|
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)
|
expect(group.imap_last_uid).to eq(100)
|
||||||
|
|
||||||
topic = Topic.last
|
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.user.email).to eq(from)
|
||||||
expect(topic.tags).to eq([])
|
expect(topic.tags).to eq([])
|
||||||
end
|
end
|
||||||
|
@ -161,7 +161,7 @@ RSpec.describe Imap::Sync do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "previous sync" do
|
describe "previous sync" do
|
||||||
let(:subject) { "Testing email post" }
|
let(:email_subject) { "Testing email post" }
|
||||||
|
|
||||||
let(:first_from) { "john@free.fr" }
|
let(:first_from) { "john@free.fr" }
|
||||||
let(:first_message_id) { SecureRandom.hex }
|
let(:first_message_id) { SecureRandom.hex }
|
||||||
|
@ -191,7 +191,7 @@ RSpec.describe Imap::Sync do
|
||||||
from: first_from,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -203,7 +203,7 @@ RSpec.describe Imap::Sync do
|
||||||
}.by(1).and change { IncomingEmail.count }.by(1)
|
}.by(1).and change { IncomingEmail.count }.by(1)
|
||||||
|
|
||||||
topic = Topic.last
|
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)
|
expect(GroupArchivedMessage.where(topic_id: topic.id).exists?).to eq(false)
|
||||||
|
|
||||||
post = Post.where(post_type: Post.types[:regular]).last
|
post = Post.where(post_type: Post.types[:regular]).last
|
||||||
|
@ -233,7 +233,7 @@ RSpec.describe Imap::Sync do
|
||||||
in_reply_to: first_message_id,
|
in_reply_to: first_message_id,
|
||||||
from: second_from,
|
from: second_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
subject: "Re: #{subject}",
|
subject: "Re: #{email_subject}",
|
||||||
body: second_body,
|
body: second_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -267,7 +267,7 @@ RSpec.describe Imap::Sync do
|
||||||
}.and not_change { IncomingEmail.count }
|
}.and not_change { IncomingEmail.count }
|
||||||
|
|
||||||
topic = Topic.last
|
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(GroupArchivedMessage.where(topic_id: topic.id).exists?).to eq(true)
|
||||||
|
|
||||||
expect(Topic.last.posts.where(post_type: Post.types[:regular]).count).to eq(2)
|
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,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -389,7 +389,7 @@ RSpec.describe Imap::Sync do
|
||||||
from: first_from,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -446,7 +446,7 @@ RSpec.describe Imap::Sync do
|
||||||
from: first_from,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -494,7 +494,7 @@ RSpec.describe Imap::Sync do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "invalidated previous sync" do
|
describe "invalidated previous sync" do
|
||||||
let(:subject) { "Testing email post" }
|
let(:email_subject) { "Testing email post" }
|
||||||
|
|
||||||
let(:first_from) { "john@free.fr" }
|
let(:first_from) { "john@free.fr" }
|
||||||
let(:first_message_id) { SecureRandom.hex }
|
let(:first_message_id) { SecureRandom.hex }
|
||||||
|
@ -526,7 +526,7 @@ RSpec.describe Imap::Sync do
|
||||||
from: first_from,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -540,7 +540,7 @@ RSpec.describe Imap::Sync do
|
||||||
in_reply_to: first_message_id,
|
in_reply_to: first_message_id,
|
||||||
from: second_from,
|
from: second_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
subject: "Re: #{subject}",
|
subject: "Re: #{email_subject}",
|
||||||
body: second_body,
|
body: second_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -571,7 +571,7 @@ RSpec.describe Imap::Sync do
|
||||||
from: first_from,
|
from: first_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
cc: second_from,
|
cc: second_from,
|
||||||
subject: subject,
|
subject: email_subject,
|
||||||
body: first_body,
|
body: first_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -585,7 +585,7 @@ RSpec.describe Imap::Sync do
|
||||||
in_reply_to: first_message_id,
|
in_reply_to: first_message_id,
|
||||||
from: second_from,
|
from: second_from,
|
||||||
to: group.email_username,
|
to: group.email_username,
|
||||||
subject: "Re: #{subject}",
|
subject: "Re: #{email_subject}",
|
||||||
body: second_body,
|
body: second_body,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,18 +5,16 @@ RSpec.describe Email::MessageIdService do
|
||||||
fab!(:post) { Fabricate(:post, topic: topic) }
|
fab!(:post) { Fabricate(:post, topic: topic) }
|
||||||
fab!(:second_post) { Fabricate(:post, topic: topic) }
|
fab!(:second_post) { Fabricate(:post, topic: topic) }
|
||||||
|
|
||||||
subject { described_class }
|
|
||||||
|
|
||||||
describe "#generate_or_use_existing" do
|
describe "#generate_or_use_existing" do
|
||||||
it "does not override a post's existing outbound_message_id" do
|
it "does not override a post's existing outbound_message_id" do
|
||||||
post.update!(outbound_message_id: "blah@host.test")
|
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>"])
|
expect(result).to eq(["<blah@host.test>"])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "generates an outbound_message_id in the correct format if it's blank for the post" do
|
it "generates an outbound_message_id in the correct format if it's blank for the post" do
|
||||||
post.update!(outbound_message_id: nil)
|
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}>"])
|
expect(result).to eq(["<discourse/post/#{post.id}@#{Email::MessageIdService.host}>"])
|
||||||
end
|
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)
|
post_bulk4 = Fabricate(:post, topic: topic, created_at: 3.days.ago, outbound_message_id: nil)
|
||||||
result =
|
result =
|
||||||
subject.generate_or_use_existing(
|
described_class.generate_or_use_existing(
|
||||||
[post_bulk1.id, post_bulk2.id, post_bulk3.id, post_bulk4.id],
|
[post_bulk1.id, post_bulk2.id, post_bulk3.id, post_bulk4.id],
|
||||||
)
|
)
|
||||||
expect(result).to eq(
|
expect(result).to eq(
|
||||||
|
@ -63,36 +61,43 @@ RSpec.describe Email::MessageIdService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "finds a post based only on a post-format message id" do
|
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
|
end
|
||||||
|
|
||||||
it "finds a post based only on a topic-format message id" do
|
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
|
end
|
||||||
|
|
||||||
it "finds a post based only on a discourse-format message id" do
|
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
|
end
|
||||||
|
|
||||||
it "finds a post from the post's outbound_message_id" do
|
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))
|
post.update!(
|
||||||
expect(subject.find_post_from_message_ids([discourse_format_message_id])).to eq(post)
|
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
|
end
|
||||||
|
|
||||||
it "finds a post from the email log" do
|
it "finds a post from the email log" do
|
||||||
email_log =
|
email_log =
|
||||||
Fabricate(:email_log, message_id: subject.message_id_clean(default_format_message_id))
|
Fabricate(
|
||||||
expect(subject.find_post_from_message_ids([default_format_message_id])).to eq(email_log.post)
|
: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
|
end
|
||||||
|
|
||||||
it "finds a post from the incoming email log" do
|
it "finds a post from the incoming email log" do
|
||||||
incoming_email =
|
incoming_email =
|
||||||
Fabricate(
|
Fabricate(
|
||||||
:incoming_email,
|
: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),
|
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,
|
incoming_email.post,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -101,16 +106,16 @@ RSpec.describe Email::MessageIdService do
|
||||||
incoming_email =
|
incoming_email =
|
||||||
Fabricate(
|
Fabricate(
|
||||||
:incoming_email,
|
: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),
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#discourse_generated_message_id?" do
|
describe "#discourse_generated_message_id?" do
|
||||||
def check_format(message_id)
|
def check_format(message_id)
|
||||||
subject.discourse_generated_message_id?(message_id)
|
described_class.discourse_generated_message_id?(message_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "works correctly for the different possible formats" do
|
it "works correctly for the different possible formats" do
|
||||||
|
|
|
@ -53,6 +53,16 @@ RSpec.describe Onebox::Engine::GoogleMapsOnebox do
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register URL redirects
|
# 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
|
before do
|
||||||
URLS.values.each do |t|
|
URLS.values.each do |t|
|
||||||
status, location = *t[:redirect]
|
status, location = *t[:redirect]
|
||||||
|
@ -62,27 +72,17 @@ RSpec.describe Onebox::Engine::GoogleMapsOnebox do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Prevent sleep from wasting our time when we test with strange redirects
|
let(:data) { Onebox::Helpers.symbolize_keys(onebox.send(:data)) }
|
||||||
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(:link) { |example| URLS[example.metadata[:urltype] || :short][:test] }
|
let(:link) { |example| URLS[example.metadata[:urltype] || :short][:test] }
|
||||||
|
|
||||||
include_context "an engine", urltype: :short
|
include_context "an engine", urltype: :short
|
||||||
|
|
||||||
URLS.each do |kind, t|
|
URLS.each do |kind, t|
|
||||||
it "processes #{kind.to_s} url correctly", urltype: kind do
|
it "processes #{kind.to_s} url correctly", urltype: kind do
|
||||||
expect(subject.url).to eq t[:expect]
|
expect(onebox.url).to eq t[:expect]
|
||||||
expect(subject.streetview?).to t[:streetview] ? be_truthy : be_falsey
|
expect(onebox.streetview?).to t[:streetview] ? be_truthy : be_falsey
|
||||||
expect(subject.to_html).to include("<iframe")
|
expect(onebox.to_html).to include("<iframe")
|
||||||
expect(subject.placeholder_html).to include("placeholder-icon map")
|
expect(onebox.placeholder_html).to include("placeholder-icon map")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Plugin::Instance do
|
RSpec.describe Plugin::Instance do
|
||||||
|
subject(:plugin_instance) { described_class.new }
|
||||||
|
|
||||||
after { DiscoursePluginRegistry.reset! }
|
after { DiscoursePluginRegistry.reset! }
|
||||||
|
|
||||||
describe "find_all" do
|
describe "find_all" do
|
||||||
|
@ -601,7 +603,7 @@ RSpec.describe Plugin::Instance do
|
||||||
highest_flag_id = ReviewableScore.types.values.max
|
highest_flag_id = ReviewableScore.types.values.max
|
||||||
flag_name = :new_flag
|
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)
|
settings.add(next_flag_id, flag_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -613,7 +615,7 @@ RSpec.describe Plugin::Instance do
|
||||||
highest_flag_id = ReviewableScore.types.values.max
|
highest_flag_id = ReviewableScore.types.values.max
|
||||||
new_score_type = :new_score_type
|
new_score_type = :new_score_type
|
||||||
|
|
||||||
subject.replace_flags(
|
plugin_instance.replace_flags(
|
||||||
settings: original_flags,
|
settings: original_flags,
|
||||||
score_type_names: [new_score_type],
|
score_type_names: [new_score_type],
|
||||||
) { |settings, next_flag_id| settings.add(next_flag_id, :new_flag) }
|
) { |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
|
it "adds a custom api key scope" do
|
||||||
actions = %w[admin/groups#create]
|
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(
|
expect(ApiKeyScope.scope_mappings.dig(:groups, :create, :actions)).to contain_exactly(
|
||||||
*actions,
|
*actions,
|
||||||
|
|
|
@ -735,20 +735,20 @@ RSpec.describe PostDestroyer do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as an admin" do
|
context "as an admin" do
|
||||||
subject { PostDestroyer.new(admin, post).destroy }
|
subject(:destroyer) { PostDestroyer.new(admin, post).destroy }
|
||||||
|
|
||||||
it "deletes the post" do
|
it "deletes the post" do
|
||||||
subject
|
destroyer
|
||||||
expect(post.deleted_at).to be_present
|
expect(post.deleted_at).to be_present
|
||||||
expect(post.deleted_by).to eq(admin)
|
expect(post.deleted_by).to eq(admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a new user history entry" do
|
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
|
||||||
|
|
||||||
it "triggers a extensibility event" do
|
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][:event_name]).to eq(:post_destroyed)
|
||||||
expect(events[0][:params].first).to eq(post)
|
expect(events[0][:params].first).to eq(post)
|
||||||
|
@ -768,34 +768,34 @@ RSpec.describe PostDestroyer do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as a moderator" do
|
context "as a moderator" do
|
||||||
subject { PostDestroyer.new(moderator, reply).destroy }
|
subject(:destroyer) { PostDestroyer.new(moderator, reply).destroy }
|
||||||
|
|
||||||
it "deletes the reply" do
|
it "deletes the reply" do
|
||||||
subject
|
destroyer
|
||||||
expect(reply.deleted_at).to be_present
|
expect(reply.deleted_at).to be_present
|
||||||
expect(reply.deleted_by).to eq(moderator)
|
expect(reply.deleted_by).to eq(moderator)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't decrement post_count again" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as an admin" do
|
context "as an admin" do
|
||||||
subject { PostDestroyer.new(admin, reply).destroy }
|
subject(:destroyer) { PostDestroyer.new(admin, reply).destroy }
|
||||||
|
|
||||||
it "deletes the post" do
|
it "deletes the post" do
|
||||||
subject
|
destroyer
|
||||||
expect(reply.deleted_at).to be_present
|
expect(reply.deleted_at).to be_present
|
||||||
expect(reply.deleted_by).to eq(admin)
|
expect(reply.deleted_by).to eq(admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't decrement post_count again" do
|
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
|
||||||
|
|
||||||
it "creates a new user history entry" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe PostJobsEnqueuer do
|
RSpec.describe PostJobsEnqueuer do
|
||||||
|
subject(:enqueuer) { described_class.new(post, topic, new_topic, opts) }
|
||||||
|
|
||||||
let!(:post) { Fabricate(:post, topic: topic) }
|
let!(:post) { Fabricate(:post, topic: topic) }
|
||||||
let!(:topic) { Fabricate(:topic) }
|
let!(:topic) { Fabricate(:topic) }
|
||||||
let(:new_topic) { false }
|
let(:new_topic) { false }
|
||||||
let(:opts) { { post_alert_options: {} } }
|
let(:opts) { { post_alert_options: {} } }
|
||||||
|
|
||||||
subject { described_class.new(post, topic, new_topic, opts) }
|
|
||||||
|
|
||||||
context "for regular topics" do
|
context "for regular topics" do
|
||||||
it "enqueues the :post_alert job" do
|
it "enqueues the :post_alert job" do
|
||||||
expect_enqueued_with(
|
expect_enqueued_with(
|
||||||
|
@ -17,24 +17,24 @@ RSpec.describe PostJobsEnqueuer do
|
||||||
new_record: true,
|
new_record: true,
|
||||||
options: opts[:post_alert_options],
|
options: opts[:post_alert_options],
|
||||||
},
|
},
|
||||||
) { subject.enqueue_jobs }
|
) { enqueuer.enqueue_jobs }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the :notify_mailing_list_subscribers job" do
|
it "enqueues the :notify_mailing_list_subscribers job" do
|
||||||
expect_enqueued_with(job: :notify_mailing_list_subscribers, args: { post_id: post.id }) do
|
expect_enqueued_with(job: :notify_mailing_list_subscribers, args: { post_id: post.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the :post_update_topic_tracking_state job" do
|
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
|
expect_enqueued_with(job: :post_update_topic_tracking_state, args: { post_id: post.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the :feature_topic_users job" do
|
it "enqueues the :feature_topic_users job" do
|
||||||
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
|
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ RSpec.describe PostJobsEnqueuer do
|
||||||
it "calls the correct topic tracking state class to publish_new" do
|
it "calls the correct topic tracking state class to publish_new" do
|
||||||
TopicTrackingState.expects(:publish_new).with(topic)
|
TopicTrackingState.expects(:publish_new).with(topic)
|
||||||
PrivateMessageTopicTrackingState.expects(:publish_new).never
|
PrivateMessageTopicTrackingState.expects(:publish_new).never
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,19 +54,19 @@ RSpec.describe PostJobsEnqueuer do
|
||||||
|
|
||||||
it "does not enqueue the :notify_mailing_list_subscribers job" 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
|
expect_not_enqueued_with(job: :notify_mailing_list_subscribers, args: { post_id: post.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the :post_update_topic_tracking_state job" do
|
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
|
expect_enqueued_with(job: :post_update_topic_tracking_state, args: { post_id: post.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues the :feature_topic_users job" do
|
it "enqueues the :feature_topic_users job" do
|
||||||
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
|
expect_enqueued_with(job: :feature_topic_users, args: { topic_id: topic.id }) do
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ RSpec.describe PostJobsEnqueuer do
|
||||||
it "calls the correct topic tracking state class to publish_new" do
|
it "calls the correct topic tracking state class to publish_new" do
|
||||||
TopicTrackingState.expects(:publish_new).never
|
TopicTrackingState.expects(:publish_new).never
|
||||||
PrivateMessageTopicTrackingState.expects(:publish_new).with(topic)
|
PrivateMessageTopicTrackingState.expects(:publish_new).with(topic)
|
||||||
subject.enqueue_jobs
|
enqueuer.enqueue_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ RSpec.describe PostJobsEnqueuer do
|
||||||
args: {
|
args: {
|
||||||
topic_id: topic.id,
|
topic_id: topic.id,
|
||||||
},
|
},
|
||||||
) { subject.enqueue_jobs }
|
) { enqueuer.enqueue_jobs }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -197,9 +197,9 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "editing tags" do
|
describe "editing tags" do
|
||||||
fab!(:post) { Fabricate(:post) }
|
subject(:post_revisor) { PostRevisor.new(post) }
|
||||||
|
|
||||||
subject { PostRevisor.new(post) }
|
fab!(:post) { Fabricate(:post) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Jobs.run_immediately!
|
Jobs.run_immediately!
|
||||||
|
@ -212,19 +212,21 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates notifications" do
|
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
|
end
|
||||||
|
|
||||||
it "skips notifications if disable_tags_edit_notifications" do
|
it "skips notifications if disable_tags_edit_notifications" do
|
||||||
SiteSetting.disable_tags_edit_notifications = true
|
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
|
end
|
||||||
|
|
||||||
it "doesn't create a small_action post when create_post_for_category_and_tag_changes is false" do
|
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
|
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
|
end
|
||||||
|
|
||||||
describe "when `create_post_for_category_and_tag_changes` site setting is enabled" do
|
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
|
it "Creates a small_action post with correct translation when both adding and removing tags" do
|
||||||
post.topic.update!(tags: [tag1])
|
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
|
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
|
||||||
}.by(1)
|
}.by(1)
|
||||||
|
|
||||||
|
@ -252,7 +254,7 @@ RSpec.describe PostRevisor do
|
||||||
it "Creates a small_action post with correct translation when adding tags" do
|
it "Creates a small_action post with correct translation when adding tags" do
|
||||||
post.topic.update!(tags: [])
|
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
|
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
|
||||||
}.by(1)
|
}.by(1)
|
||||||
|
|
||||||
|
@ -264,7 +266,7 @@ RSpec.describe PostRevisor do
|
||||||
it "Creates a small_action post with correct translation when removing tags" do
|
it "Creates a small_action post with correct translation when removing tags" do
|
||||||
post.topic.update!(tags: [tag1, tag2])
|
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
|
Post.where(topic_id: post.topic_id, action_code: "tags_changed").count
|
||||||
}.by(1)
|
}.by(1)
|
||||||
|
|
||||||
|
@ -277,7 +279,7 @@ RSpec.describe PostRevisor do
|
||||||
current_category = post.topic.category
|
current_category = post.topic.category
|
||||||
category = Fabricate(: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
|
Post.where(topic_id: post.topic_id, action_code: "category_changed").count
|
||||||
}.by(1)
|
}.by(1)
|
||||||
|
|
||||||
|
@ -310,24 +312,24 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "revise" do
|
describe "revise" do
|
||||||
|
subject(:post_revisor) { PostRevisor.new(post) }
|
||||||
|
|
||||||
let(:post) { Fabricate(:post, post_args) }
|
let(:post) { Fabricate(:post, post_args) }
|
||||||
let(:first_version_at) { post.last_version_at }
|
let(:first_version_at) { post.last_version_at }
|
||||||
|
|
||||||
subject { PostRevisor.new(post) }
|
|
||||||
|
|
||||||
it "destroys last revision if edit is undone" do
|
it "destroys last revision if edit is undone" do
|
||||||
old_raw = post.raw
|
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.topic.reload.tags.map(&:name)).to contain_exactly("new-tag")
|
||||||
expect(post.post_revisions.reload.size).to eq(1)
|
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.topic.reload.tags.map(&:name)).to be_empty
|
||||||
expect(post.post_revisions.reload.size).to eq(0)
|
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.topic.reload.tags.map(&:name)).to contain_exactly("new-tag")
|
||||||
expect(post.post_revisions.reload.size).to eq(1)
|
expect(post.post_revisions.reload.size).to eq(1)
|
||||||
end
|
end
|
||||||
|
@ -335,7 +337,7 @@ RSpec.describe PostRevisor do
|
||||||
describe "with the same body" do
|
describe "with the same body" do
|
||||||
it "doesn't change version" do
|
it "doesn't change version" do
|
||||||
expect {
|
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
|
post.reload
|
||||||
}.not_to change(post, :version)
|
}.not_to change(post, :version)
|
||||||
end
|
end
|
||||||
|
@ -344,7 +346,7 @@ RSpec.describe PostRevisor do
|
||||||
describe "with nil raw contents" do
|
describe "with nil raw contents" do
|
||||||
it "doesn't change version" do
|
it "doesn't change version" do
|
||||||
expect {
|
expect {
|
||||||
expect(subject.revise!(post.user, raw: nil)).to eq(false)
|
expect(post_revisor.revise!(post.user, raw: nil)).to eq(false)
|
||||||
post.reload
|
post.reload
|
||||||
}.not_to change(post, :version)
|
}.not_to change(post, :version)
|
||||||
end
|
end
|
||||||
|
@ -354,7 +356,7 @@ RSpec.describe PostRevisor do
|
||||||
before { topic.update!(slow_mode_seconds: 1000) }
|
before { topic.update!(slow_mode_seconds: 1000) }
|
||||||
|
|
||||||
it "regular edits are not allowed by default" do
|
it "regular edits are not allowed by default" do
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + 1000.minutes,
|
revised_at: post.updated_at + 1000.minutes,
|
||||||
|
@ -368,7 +370,7 @@ RSpec.describe PostRevisor do
|
||||||
it "grace period editing is allowed" do
|
it "grace period editing is allowed" do
|
||||||
SiteSetting.editing_grace_period = 1.minute
|
SiteSetting.editing_grace_period = 1.minute
|
||||||
|
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + 10.seconds,
|
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
|
it "regular edits are allowed if it was turned on in settings" do
|
||||||
SiteSetting.slow_mode_prevents_editing = false
|
SiteSetting.slow_mode_prevents_editing = false
|
||||||
|
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + 10.minutes,
|
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
|
it "staff is allowed to edit posts even if the topic is in slow mode" do
|
||||||
admin = Fabricate(:admin)
|
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
|
post.reload
|
||||||
expect(post.errors).to be_empty
|
expect(post.errors).to be_empty
|
||||||
|
@ -404,7 +410,7 @@ RSpec.describe PostRevisor do
|
||||||
it "correctly applies edits" do
|
it "correctly applies edits" do
|
||||||
SiteSetting.editing_grace_period = 1.minute
|
SiteSetting.editing_grace_period = 1.minute
|
||||||
|
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + 10.seconds,
|
revised_at: post.updated_at + 10.seconds,
|
||||||
|
@ -415,7 +421,7 @@ RSpec.describe PostRevisor do
|
||||||
expect(post.public_version).to eq(1)
|
expect(post.public_version).to eq(1)
|
||||||
expect(post.revisions.size).to eq(0)
|
expect(post.revisions.size).to eq(0)
|
||||||
expect(post.last_version_at).to eq_time(first_version_at)
|
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
|
end
|
||||||
|
|
||||||
it "does create a new version if a large diff happens" do
|
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
|
SiteSetting.editing_grace_period_max_diff = 100
|
||||||
|
|
||||||
# making a revision
|
# making a revision
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
|
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
|
||||||
)
|
)
|
||||||
# "roll back"
|
# "roll back"
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "Hello world" },
|
{ raw: "Hello world" },
|
||||||
revised_at: post.updated_at + SiteSetting.editing_grace_period + 2.seconds,
|
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
|
it "should bump the topic" do
|
||||||
expect {
|
expect {
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
|
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)
|
post_from_topic_with_no_category = Fabricate(:post, topic: topic_with_no_category)
|
||||||
expect {
|
expect {
|
||||||
result =
|
result =
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post_from_topic_with_no_category.raw,
|
raw: post_from_topic_with_no_category.raw,
|
||||||
tags: ["foo"],
|
tags: ["foo"],
|
||||||
|
@ -533,7 +539,7 @@ RSpec.describe PostRevisor do
|
||||||
TopicUser.create!(topic: post.topic, user: post.user, notification_level: 0)
|
TopicUser.create!(topic: post.topic, user: post.user, notification_level: 0)
|
||||||
messages =
|
messages =
|
||||||
MessageBus.track_publish("/latest") do
|
MessageBus.track_publish("/latest") do
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "updated body" },
|
{ raw: "updated body" },
|
||||||
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
|
revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds,
|
||||||
|
@ -632,12 +638,12 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
SiteSetting.editing_grace_period = 1.minute
|
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
|
post.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't update a category" do
|
it "doesn't update a category" do
|
||||||
expect(subject.category_changed).to be_blank
|
expect(post_revisor.category_changed).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the versions" do
|
it "updates the versions" do
|
||||||
|
@ -655,7 +661,11 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
describe "new edit window" do
|
describe "new edit window" do
|
||||||
before 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
|
post.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -669,14 +679,14 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't update a category" do
|
it "doesn't update a category" do
|
||||||
expect(subject.category_changed).to be_blank
|
expect(post_revisor.category_changed).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
context "after second window" do
|
context "after second window" do
|
||||||
let!(:new_revised_at) { revised_at + 2.minutes }
|
let!(:new_revised_at) { revised_at + 2.minutes }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ raw: "yet another, another updated body" },
|
{ raw: "yet another, another updated body" },
|
||||||
revised_at: new_revised_at,
|
revised_at: new_revised_at,
|
||||||
|
@ -711,12 +721,12 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
context "with one paragraph description" do
|
context "with one paragraph description" do
|
||||||
before do
|
before do
|
||||||
subject.revise!(post.user, raw: new_description)
|
post_revisor.revise!(post.user, raw: new_description)
|
||||||
category.reload
|
category.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the changed category info" do
|
it "returns the changed category info" do
|
||||||
expect(subject.category_changed).to eq(category)
|
expect(post_revisor.category_changed).to eq(category)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the description of the category" do
|
it "updates the description of the category" do
|
||||||
|
@ -726,12 +736,12 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
context "with multiple paragraph description" do
|
context "with multiple paragraph description" do
|
||||||
before 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
|
category.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the changed category info" do
|
it "returns the changed category info" do
|
||||||
expect(subject.category_changed).to eq(category)
|
expect(post_revisor.category_changed).to eq(category)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates the description of the category" do
|
it "updates the description of the category" do
|
||||||
|
@ -741,7 +751,7 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
context "with invalid description without paragraphs" do
|
context "with invalid description without paragraphs" do
|
||||||
before do
|
before do
|
||||||
subject.revise!(post.user, raw: "# This is a title")
|
post_revisor.revise!(post.user, raw: "# This is a title")
|
||||||
category.reload
|
category.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -760,7 +770,7 @@ RSpec.describe PostRevisor do
|
||||||
context "when updating back to the original paragraph" do
|
context "when updating back to the original paragraph" do
|
||||||
before do
|
before do
|
||||||
category.update_column(:description, "this is my description")
|
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
|
category.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -769,7 +779,7 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the changed category info" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -786,16 +796,16 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
it "triggers a rate limiter" do
|
it "triggers a rate limiter" do
|
||||||
EditRateLimiter.any_instance.expects(:performed!)
|
EditRateLimiter.any_instance.expects(:performed!)
|
||||||
subject.revise!(changed_by, raw: "updated body")
|
post_revisor.revise!(changed_by, raw: "updated body")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises error when a user gets rate limited" do
|
it "raises error when a user gets rate limited" do
|
||||||
SiteSetting.max_edits_per_day = 1
|
SiteSetting.max_edits_per_day = 1
|
||||||
user = Fabricate(:user, trust_level: 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,
|
RateLimiter::LimitExceeded,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -807,26 +817,26 @@ RSpec.describe PostRevisor do
|
||||||
SiteSetting.tl4_additional_edits_per_day_multiplier = 4
|
SiteSetting.tl4_additional_edits_per_day_multiplier = 4
|
||||||
|
|
||||||
user = Fabricate(:user, trust_level: 2)
|
user = Fabricate(:user, trust_level: 2)
|
||||||
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
|
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
|
||||||
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
|
expect { post_revisor.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 do post_revisor.revise!(user, raw: "body (edited three times) ") end.to raise_error(
|
||||||
RateLimiter::LimitExceeded,
|
RateLimiter::LimitExceeded,
|
||||||
)
|
)
|
||||||
|
|
||||||
user = Fabricate(:user, trust_level: 3)
|
user = Fabricate(:user, trust_level: 3)
|
||||||
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
|
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
|
||||||
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
|
expect { post_revisor.revise!(user, raw: "body (edited twice)") }.to_not raise_error
|
||||||
expect { subject.revise!(user, raw: "body (edited three times)") }.to_not raise_error
|
expect { post_revisor.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 do post_revisor.revise!(user, raw: "body (edited four times) ") end.to raise_error(
|
||||||
RateLimiter::LimitExceeded,
|
RateLimiter::LimitExceeded,
|
||||||
)
|
)
|
||||||
|
|
||||||
user = Fabricate(:user, trust_level: 4)
|
user = Fabricate(:user, trust_level: 4)
|
||||||
expect { subject.revise!(user, raw: "body (edited)") }.to_not raise_error
|
expect { post_revisor.revise!(user, raw: "body (edited)") }.to_not raise_error
|
||||||
expect { subject.revise!(user, raw: "body (edited twice)") }.to_not raise_error
|
expect { post_revisor.revise!(user, raw: "body (edited twice)") }.to_not raise_error
|
||||||
expect { subject.revise!(user, raw: "body (edited three times)") }.to_not raise_error
|
expect { post_revisor.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 { post_revisor.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 do post_revisor.revise!(user, raw: "body (edited five times) ") end.to raise_error(
|
||||||
RateLimiter::LimitExceeded,
|
RateLimiter::LimitExceeded,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -839,7 +849,7 @@ RSpec.describe PostRevisor do
|
||||||
SiteSetting.newuser_max_embedded_media = 0
|
SiteSetting.newuser_max_embedded_media = 0
|
||||||
url = "http://i.imgur.com/wfn7rgU.jpg"
|
url = "http://i.imgur.com/wfn7rgU.jpg"
|
||||||
Oneboxer.stubs(:onebox).with(url, anything).returns("<img src='#{url}'>")
|
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
|
end
|
||||||
|
|
||||||
it "allows an admin to insert images into a new user's post" do
|
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
|
SiteSetting.newuser_max_embedded_media = 0
|
||||||
url = "http://i.imgur.com/FGg7Vzu.gif"
|
url = "http://i.imgur.com/FGg7Vzu.gif"
|
||||||
Oneboxer.stubs(:cached_onebox).with(url, anything).returns("<img src='#{url}'>")
|
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
|
end
|
||||||
|
|
||||||
it "doesn't allow images to be inserted" do
|
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 }
|
before { SiteSetting.editing_grace_period_max_diff = 1000 }
|
||||||
|
|
||||||
fab!(:changed_by) { coding_horror }
|
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
|
it "correctly updates raw" do
|
||||||
expect(result).to eq(true)
|
expect(result).to eq(true)
|
||||||
|
@ -886,7 +896,7 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "increases the post_edits stat count" do
|
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
|
post.user.user_stat.post_edits_count.to_i
|
||||||
}.by(1)
|
}.by(1)
|
||||||
end
|
end
|
||||||
|
@ -894,7 +904,7 @@ RSpec.describe PostRevisor do
|
||||||
context "when second poster posts again quickly" do
|
context "when second poster posts again quickly" do
|
||||||
it "is a grace period edit, because the second poster posted again quickly" do
|
it "is a grace period edit, because the second poster posted again quickly" do
|
||||||
SiteSetting.editing_grace_period = 1.minute
|
SiteSetting.editing_grace_period = 1.minute
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
changed_by,
|
changed_by,
|
||||||
{ raw: "yet another updated body" },
|
{ raw: "yet another updated body" },
|
||||||
revised_at: post.updated_at + 10.seconds,
|
revised_at: post.updated_at + 10.seconds,
|
||||||
|
@ -909,7 +919,7 @@ RSpec.describe PostRevisor do
|
||||||
context "when passing skip_revision as true" do
|
context "when passing skip_revision as true" do
|
||||||
before do
|
before do
|
||||||
SiteSetting.editing_grace_period = 1.minute
|
SiteSetting.editing_grace_period = 1.minute
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
changed_by,
|
changed_by,
|
||||||
{ raw: "yet another updated body" },
|
{ raw: "yet another updated body" },
|
||||||
revised_at: post.updated_at + 10.hours,
|
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
|
context "when editing the before_edit_post event signature" do
|
||||||
it "contains post and params" do
|
it "contains post and params" do
|
||||||
params = { raw: "body (edited)" }
|
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])
|
expect(events).to include(event_name: :before_edit_post, params: [post, params])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -955,7 +965,7 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't strip starting whitespaces" do
|
it "doesn't strip starting whitespaces" do
|
||||||
subject.revise!(post.user, raw: " <-- whitespaces --> ")
|
post_revisor.revise!(post.user, raw: " <-- whitespaces --> ")
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.raw).to eq(" <-- whitespaces -->")
|
expect(post.raw).to eq(" <-- whitespaces -->")
|
||||||
end
|
end
|
||||||
|
@ -963,20 +973,24 @@ RSpec.describe PostRevisor do
|
||||||
it "revises and tracks changes of topic titles" do
|
it "revises and tracks changes of topic titles" do
|
||||||
new_title = "New topic title"
|
new_title = "New topic title"
|
||||||
result =
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.title).to eq(new_title)
|
expect(post.topic.title).to eq(new_title)
|
||||||
expect(post.revisions.first.modifications["title"][1]).to eq(new_title)
|
expect(post.revisions.first.modifications["title"][1]).to eq(new_title)
|
||||||
expect(subject.topic_title_changed?).to eq(true)
|
expect(post_revisor.topic_title_changed?).to eq(true)
|
||||||
expect(subject.raw_changed?).to eq(false)
|
expect(post_revisor.raw_changed?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "revises and tracks changes of topic archetypes" do
|
it "revises and tracks changes of topic archetypes" do
|
||||||
new_archetype = Archetype.banner
|
new_archetype = Archetype.banner
|
||||||
result =
|
result =
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
post.user,
|
post.user,
|
||||||
{ archetype: new_archetype },
|
{ archetype: new_archetype },
|
||||||
revised_at: post.updated_at + 10.minutes,
|
revised_at: post.updated_at + 10.minutes,
|
||||||
|
@ -986,21 +1000,21 @@ RSpec.describe PostRevisor do
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.archetype).to eq(new_archetype)
|
expect(post.topic.archetype).to eq(new_archetype)
|
||||||
expect(post.revisions.first.modifications["archetype"][1]).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
|
end
|
||||||
|
|
||||||
it "revises and tracks changes of topic tags" do
|
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(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(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(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
|
end
|
||||||
|
|
||||||
describe "#publish_changes" do
|
describe "#publish_changes" do
|
||||||
|
@ -1023,14 +1037,14 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
context "when logging staff edits" do
|
context "when logging staff edits" do
|
||||||
it "doesn't log when a regular user revises a post" 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 =
|
log =
|
||||||
UserHistory.where(acting_user_id: post.user.id, action: UserHistory.actions[:post_edit])
|
UserHistory.where(acting_user_id: post.user.id, action: UserHistory.actions[:post_edit])
|
||||||
expect(log).to be_blank
|
expect(log).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "logs an edit when a staff member revises a post" do
|
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 =
|
log =
|
||||||
UserHistory.where(
|
UserHistory.where(
|
||||||
acting_user_id: moderator.id,
|
acting_user_id: moderator.id,
|
||||||
|
@ -1041,7 +1055,11 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't log an edit when skip_staff_log is true" do
|
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 =
|
log =
|
||||||
UserHistory.where(
|
UserHistory.where(
|
||||||
acting_user_id: moderator.id,
|
acting_user_id: moderator.id,
|
||||||
|
@ -1095,7 +1113,7 @@ RSpec.describe PostRevisor do
|
||||||
before { SiteSetting.staff_edit_locks_post = false }
|
before { SiteSetting.staff_edit_locks_post = false }
|
||||||
|
|
||||||
it "does not lock the post when revised" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post).not_to be_locked
|
expect(post).not_to be_locked
|
||||||
|
@ -1106,7 +1124,7 @@ RSpec.describe PostRevisor do
|
||||||
before { SiteSetting.staff_edit_locks_post = true }
|
before { SiteSetting.staff_edit_locks_post = true }
|
||||||
|
|
||||||
it "locks the post when revised by staff" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post).to be_locked
|
expect(post).to be_locked
|
||||||
|
@ -1114,14 +1132,14 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
it "doesn't lock the wiki posts" do
|
it "doesn't lock the wiki posts" do
|
||||||
post.wiki = true
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post).not_to be_locked
|
expect(post).not_to be_locked
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't lock the post when the raw did not change" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.title).to eq("New topic title, cool!")
|
expect(post.topic.title).to eq("New topic title, cool!")
|
||||||
|
@ -1129,14 +1147,15 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't lock the post when revised by a regular user" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post).not_to be_locked
|
expect(post).not_to be_locked
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't lock the post when revised by system user" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post).not_to be_locked
|
expect(post).not_to be_locked
|
||||||
|
@ -1161,13 +1180,16 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
it "generates a notification for a mention" do
|
it "generates a notification for a mention" do
|
||||||
expect {
|
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 }
|
}.to change { Notification.where(notification_type: Notification.types[:mentioned]).count }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "never generates a notification for a mention when the System user revise a post" do
|
it "never generates a notification for a mention when the System user revise a post" do
|
||||||
expect {
|
expect {
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Discourse.system_user,
|
Discourse.system_user,
|
||||||
raw: "System user is mentioning @#{mentioned_user.username_lower}",
|
raw: "System user is mentioning @#{mentioned_user.username_lower}",
|
||||||
)
|
)
|
||||||
|
@ -1183,7 +1205,11 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
it "doesn't add the tags" do
|
it "doesn't add the tags" do
|
||||||
result =
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.tags.size).to eq(0)
|
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
|
it "can create all tags if none exist" do
|
||||||
expect {
|
expect {
|
||||||
@result =
|
@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)
|
}.to change { Tag.count }.by(2)
|
||||||
expect(@result).to eq(true)
|
expect(@result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
|
@ -1213,7 +1243,11 @@ RSpec.describe PostRevisor do
|
||||||
Fabricate(:tag, name: "totally")
|
Fabricate(:tag, name: "totally")
|
||||||
expect {
|
expect {
|
||||||
@result =
|
@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)
|
}.to change { Tag.count }.by(1)
|
||||||
expect(@result).to eq(true)
|
expect(@result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
|
@ -1222,7 +1256,7 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
it "can remove all tags" do
|
it "can remove all tags" do
|
||||||
topic.tags = [Fabricate(:tag, name: "super"), Fabricate(:tag, name: "stuff")]
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.tags.size).to eq(0)
|
expect(post.topic.tags.size).to eq(0)
|
||||||
|
@ -1231,7 +1265,11 @@ RSpec.describe PostRevisor do
|
||||||
it "can't add staff-only tags" do
|
it "can't add staff-only tags" do
|
||||||
create_staff_only_tags(["important"])
|
create_staff_only_tags(["important"])
|
||||||
result =
|
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(result).to eq(false)
|
||||||
expect(post.topic.errors.present?).to eq(true)
|
expect(post.topic.errors.present?).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -1239,7 +1277,11 @@ RSpec.describe PostRevisor do
|
||||||
it "staff can add staff-only tags" do
|
it "staff can add staff-only tags" do
|
||||||
create_staff_only_tags(["important"])
|
create_staff_only_tags(["important"])
|
||||||
result =
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.tags.map(&:name).sort).to eq(%w[important stuff])
|
expect(post.topic.tags.map(&:name).sort).to eq(%w[important stuff])
|
||||||
|
@ -1250,7 +1292,7 @@ RSpec.describe PostRevisor do
|
||||||
|
|
||||||
events =
|
events =
|
||||||
DiscourseEvent.track_events do
|
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
|
end
|
||||||
|
|
||||||
event = events.find { |e| e[:event_name] == :post_edited }
|
event = events.find { |e| e[:event_name] == :post_edited }
|
||||||
|
@ -1273,7 +1315,8 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "staff-only tags can't be removed" do
|
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(result).to eq(false)
|
||||||
expect(post.topic.errors.present?).to eq(true)
|
expect(post.topic.errors.present?).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
|
@ -1281,7 +1324,7 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can't remove all tags if some are staff-only" do
|
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(result).to eq(false)
|
||||||
expect(post.topic.errors.present?).to eq(true)
|
expect(post.topic.errors.present?).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
|
@ -1289,14 +1332,15 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "staff-only tags can be removed by staff" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.tags.map(&:name)).to eq(["stuff"])
|
expect(post.topic.tags.map(&:name)).to eq(["stuff"])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "staff can remove all tags" do
|
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)
|
expect(result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
expect(post.topic.tags.size).to eq(0)
|
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
|
it "doesn't bump topic if only staff-only tags are added" do
|
||||||
expect {
|
expect {
|
||||||
result =
|
result =
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post.raw,
|
raw: post.raw,
|
||||||
tags: topic.tags.map(&:name) + ["secret"],
|
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
|
it "doesn't bump topic if only staff-only tags are removed" do
|
||||||
expect {
|
expect {
|
||||||
result =
|
result =
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post.raw,
|
raw: post.raw,
|
||||||
tags: topic.tags.map(&:name) - %w[important secret],
|
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
|
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
|
topic.tags = Tag.where(name: %w[important secret]).to_a
|
||||||
expect {
|
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)
|
expect(result).to eq(true)
|
||||||
}.to_not change { topic.reload.bumped_at }
|
}.to_not change { topic.reload.bumped_at }
|
||||||
end
|
end
|
||||||
|
@ -1352,7 +1396,7 @@ RSpec.describe PostRevisor do
|
||||||
it "doesn't bump topic if empty string is given" do
|
it "doesn't bump topic if empty string is given" do
|
||||||
topic.tags = Tag.where(name: %w[important secret]).to_a
|
topic.tags = Tag.where(name: %w[important secret]).to_a
|
||||||
expect {
|
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)
|
expect(result).to eq(true)
|
||||||
}.to_not change { topic.reload.bumped_at }
|
}.to_not change { topic.reload.bumped_at }
|
||||||
end
|
end
|
||||||
|
@ -1360,7 +1404,7 @@ RSpec.describe PostRevisor do
|
||||||
it "should bump topic if non staff-only tags are added" do
|
it "should bump topic if non staff-only tags are added" do
|
||||||
expect {
|
expect {
|
||||||
result =
|
result =
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post.raw,
|
raw: post.raw,
|
||||||
tags: topic.tags.map(&:name) + [Fabricate(:tag).name],
|
tags: topic.tags.map(&:name) + [Fabricate(:tag).name],
|
||||||
|
@ -1370,7 +1414,7 @@ RSpec.describe PostRevisor do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a hidden revision" do
|
it "creates a hidden revision" do
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post.raw,
|
raw: post.raw,
|
||||||
tags: topic.tags.map(&:name) + ["secret"],
|
tags: topic.tags.map(&:name) + ["secret"],
|
||||||
|
@ -1382,7 +1426,7 @@ RSpec.describe PostRevisor do
|
||||||
PostActionNotifier.enable
|
PostActionNotifier.enable
|
||||||
Jobs.run_immediately!
|
Jobs.run_immediately!
|
||||||
expect {
|
expect {
|
||||||
subject.revise!(
|
post_revisor.revise!(
|
||||||
Fabricate(:admin),
|
Fabricate(:admin),
|
||||||
raw: post.raw,
|
raw: post.raw,
|
||||||
tags: topic.tags.map(&:name) + ["secret"],
|
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
|
it "doesn't allow removing all tags from the group" do
|
||||||
post.topic.tags = [tag1, tag2]
|
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)
|
expect(result).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows removing some tags" do
|
it "allows removing some tags" do
|
||||||
post.topic.tags = [tag1, tag2, tag3]
|
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(result).to eq(true)
|
||||||
expect(post.reload.topic.tags.map(&:name)).to eq([tag1.name])
|
expect(post.reload.topic.tags.map(&:name)).to eq([tag1.name])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows admins to remove the tags" do
|
it "allows admins to remove the tags" do
|
||||||
post.topic.tags = [tag1, tag2, tag3]
|
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(result).to eq(true)
|
||||||
expect(post.reload.topic.tags.size).to eq(0)
|
expect(post.reload.topic.tags.size).to eq(0)
|
||||||
end
|
end
|
||||||
|
@ -1442,7 +1487,11 @@ RSpec.describe PostRevisor do
|
||||||
Fabricate(:tag, name: "totally")
|
Fabricate(:tag, name: "totally")
|
||||||
expect {
|
expect {
|
||||||
@result =
|
@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 }
|
}.to_not change { Tag.count }
|
||||||
expect(@result).to eq(true)
|
expect(@result).to eq(true)
|
||||||
post.reload
|
post.reload
|
||||||
|
@ -1467,7 +1516,7 @@ RSpec.describe PostRevisor do
|
||||||
post.link_post_uploads
|
post.link_post_uploads
|
||||||
expect(post.upload_references.pluck(:upload_id)).to contain_exactly(image1.id, image2.id)
|
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
|
This is a post with multiple uploads
|
||||||
![image2](#{image2.short_url})
|
![image2](#{image2.short_url})
|
||||||
![image3](#{image3.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
|
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
|
stub_image_size
|
||||||
subject.revise!(user, raw: <<~RAW)
|
post_revisor.revise!(user, raw: <<~RAW)
|
||||||
This is a post with a secure upload
|
This is a post with a secure upload
|
||||||
![image5](#{image5.short_url})
|
![image5](#{image5.short_url})
|
||||||
RAW
|
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
|
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)))
|
post.topic.update(category: Fabricate(:private_category, group: Fabricate(:group)))
|
||||||
stub_image_size
|
stub_image_size
|
||||||
subject.revise!(user, raw: <<~RAW)
|
post_revisor.revise!(user, raw: <<~RAW)
|
||||||
This is a post with a secure upload
|
This is a post with a secure upload
|
||||||
![image5](#{image5.short_url})
|
![image5](#{image5.short_url})
|
||||||
RAW
|
RAW
|
||||||
|
@ -1554,12 +1603,12 @@ RSpec.describe PostRevisor do
|
||||||
fab!(:post) { Fabricate(:post, raw: "aaa", skip_validation: true) }
|
fab!(:post) { Fabricate(:post, raw: "aaa", skip_validation: true) }
|
||||||
|
|
||||||
it "can revise multiple times and remove unnecessary revisions" do
|
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
|
expect(post.errors).to be_empty
|
||||||
|
|
||||||
# Revert to old version which was invalid to destroy previously created
|
# Revert to old version which was invalid to destroy previously created
|
||||||
# post revision and trigger another post save.
|
# 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
|
expect(post.errors).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -203,7 +203,7 @@ RSpec.describe RetrieveTitle do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "ignores SSRF lookup errors" do
|
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)
|
expect(RetrieveTitle.crawl("https://example.com")).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
require "seed_data/categories"
|
require "seed_data/categories"
|
||||||
|
|
||||||
RSpec.describe SeedData::Categories do
|
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")
|
def create_category(name = "staff_category_id")
|
||||||
subject.create(site_setting_names: [name])
|
seeder.create(site_setting_names: [name])
|
||||||
end
|
end
|
||||||
|
|
||||||
def description_post(category)
|
def description_post(category)
|
||||||
|
@ -152,7 +152,7 @@ RSpec.describe SeedData::Categories do
|
||||||
|
|
||||||
describe "#update" do
|
describe "#update" do
|
||||||
def update_category(name = "staff_category_id", skip_changed: false)
|
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
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -211,7 +211,7 @@ RSpec.describe SeedData::Categories do
|
||||||
{ id: "general_category_id", name: I18n.t("general_category_name"), selected: false },
|
{ 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
require "seed_data/topics"
|
require "seed_data/topics"
|
||||||
|
|
||||||
RSpec.describe SeedData::Topics do
|
RSpec.describe SeedData::Topics do
|
||||||
subject { SeedData::Topics.with_default_locale }
|
subject(:seeder) { SeedData::Topics.with_default_locale }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
general_category = Fabricate(:category, name: "General")
|
general_category = Fabricate(:category, name: "General")
|
||||||
|
@ -11,7 +11,7 @@ RSpec.describe SeedData::Topics do
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_topic(name = "welcome_topic_id")
|
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
|
end
|
||||||
|
|
||||||
describe "#create" do
|
describe "#create" do
|
||||||
|
@ -74,7 +74,7 @@ RSpec.describe SeedData::Topics do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create a legal topic if company_name is not set" do
|
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)
|
expect(SiteSetting.tos_topic_id).to eq(-1)
|
||||||
end
|
end
|
||||||
|
@ -102,7 +102,7 @@ RSpec.describe SeedData::Topics do
|
||||||
|
|
||||||
it "creates a legal topic if company_name is set" do
|
it "creates a legal topic if company_name is set" do
|
||||||
SiteSetting.company_name = "Company Name"
|
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)
|
expect(SiteSetting.tos_topic_id).to_not eq(-1)
|
||||||
end
|
end
|
||||||
|
@ -110,7 +110,7 @@ RSpec.describe SeedData::Topics do
|
||||||
|
|
||||||
describe "#update" do
|
describe "#update" do
|
||||||
def update_topic(name = "welcome_topic_id", skip_changed: false)
|
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
|
end
|
||||||
|
|
||||||
it "updates the changed topic" do
|
it "updates the changed topic" do
|
||||||
|
@ -167,7 +167,7 @@ RSpec.describe SeedData::Topics do
|
||||||
|
|
||||||
describe "#delete" do
|
describe "#delete" do
|
||||||
def delete_topic(name = "welcome_topic_id", skip_changed: false)
|
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
|
end
|
||||||
|
|
||||||
it "deletes the topic" do
|
it "deletes the topic" do
|
||||||
|
@ -199,7 +199,7 @@ RSpec.describe SeedData::Topics do
|
||||||
{ id: "welcome_topic_id", name: "Changed Topic Title", selected: false },
|
{ 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,8 +9,6 @@ RSpec.describe SiteSettings::TypeSupervisor do
|
||||||
new_settings(provider_local)
|
new_settings(provider_local)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { SiteSettings::TypeSupervisor }
|
|
||||||
|
|
||||||
describe "constants" do
|
describe "constants" do
|
||||||
it "validator opts are the subset of consumed opts" do
|
it "validator opts are the subset of consumed opts" do
|
||||||
expect(
|
expect(
|
||||||
|
@ -103,33 +101,33 @@ RSpec.describe SiteSettings::TypeSupervisor do
|
||||||
|
|
||||||
describe "#parse_value_type" do
|
describe "#parse_value_type" do
|
||||||
it "returns :null type when the value is nil" 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
|
end
|
||||||
|
|
||||||
it "returns :integer type when the value is int" do
|
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
|
end
|
||||||
|
|
||||||
it "returns :integer type when the value is large int" do
|
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(
|
expect(
|
||||||
SiteSetting.types[:integer],
|
described_class.parse_value_type(99_999_999_999_999_999_999_999_999_999_999_999),
|
||||||
)
|
).to eq(SiteSetting.types[:integer])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns :float type when the value is float" do
|
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
|
end
|
||||||
|
|
||||||
it "returns :bool type when the value is true" do
|
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
|
end
|
||||||
|
|
||||||
it "returns :bool type when the value is false" do
|
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
|
end
|
||||||
|
|
||||||
it "raises when the value is not listed" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,22 +3,24 @@
|
||||||
require "site_settings/validations"
|
require "site_settings/validations"
|
||||||
|
|
||||||
RSpec.describe SiteSettings::Validations do
|
RSpec.describe SiteSettings::Validations do
|
||||||
subject { Class.new.include(described_class).new }
|
subject(:validations) { Class.new.include(described_class).new }
|
||||||
|
|
||||||
describe "default_categories" do
|
describe "default_categories" do
|
||||||
fab!(:category) { Fabricate(:category) }
|
fab!(:category) { Fabricate(:category) }
|
||||||
|
|
||||||
it "supports valid categories" do
|
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
|
end
|
||||||
|
|
||||||
it "won't allow you to input junk categories" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
subject.validate_default_categories_watching("#{category.id}|12312323")
|
validations.validate_default_categories_watching("#{category.id}|12312323")
|
||||||
}.to raise_error(Discourse::InvalidParameters)
|
}.to raise_error(Discourse::InvalidParameters)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -85,7 +87,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
let(:other_setting_name) { "s3_upload_bucket" }
|
let(:other_setting_name) { "s3_upload_bucket" }
|
||||||
|
|
||||||
def validate(new_value)
|
def validate(new_value)
|
||||||
subject.validate_s3_backup_bucket(new_value)
|
validations.validate_s3_backup_bucket(new_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like "s3 bucket validation"
|
it_behaves_like "s3 bucket validation"
|
||||||
|
@ -103,7 +105,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
let(:other_setting_name) { "s3_backup_bucket" }
|
let(:other_setting_name) { "s3_backup_bucket" }
|
||||||
|
|
||||||
def validate(new_value)
|
def validate(new_value)
|
||||||
subject.validate_s3_upload_bucket(new_value)
|
validations.validate_s3_upload_bucket(new_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like "s3 bucket validation"
|
it_behaves_like "s3 bucket validation"
|
||||||
|
@ -142,7 +144,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enable_local_logins = false }
|
before { SiteSetting.enable_local_logins = false }
|
||||||
|
|
||||||
it "should raise an error" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -153,7 +155,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enable_local_logins = true }
|
before { SiteSetting.enable_local_logins = true }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -170,7 +172,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises and error, and specifies the auth providers" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -189,7 +191,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise an error" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -207,7 +209,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enforce_second_factor = "all" }
|
before { SiteSetting.enforce_second_factor = "all" }
|
||||||
|
|
||||||
it "should raise an error" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -218,14 +220,14 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enforce_second_factor = "no" }
|
before { SiteSetting.enforce_second_factor = "no" }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the new value is true" do
|
context "when the new value is true" do
|
||||||
it "should be ok" 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
|
end
|
||||||
end
|
end
|
||||||
|
@ -237,7 +239,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
|
|
||||||
context "when the new value has trailing slash" do
|
context "when the new value has trailing slash" do
|
||||||
it "should raise an error" 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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -248,7 +250,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
describe "#validate_enable_page_publishing" do
|
describe "#validate_enable_page_publishing" do
|
||||||
context "when the new value is true" do
|
context "when the new value is true" do
|
||||||
it "is ok" 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
|
end
|
||||||
|
|
||||||
context "if secure uploads is enabled" do
|
context "if secure uploads is enabled" do
|
||||||
|
@ -256,7 +258,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { enable_secure_uploads }
|
before { enable_secure_uploads }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -268,13 +270,13 @@ RSpec.describe SiteSettings::Validations do
|
||||||
describe "#validate_s3_use_acls" do
|
describe "#validate_s3_use_acls" do
|
||||||
context "when the new value is true" do
|
context "when the new value is true" do
|
||||||
it "is ok" 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
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the new value is false" do
|
context "when the new value is false" do
|
||||||
it "is ok" 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
|
end
|
||||||
|
|
||||||
context "if secure uploads is enabled" do
|
context "if secure uploads is enabled" do
|
||||||
|
@ -282,7 +284,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { enable_secure_uploads }
|
before { enable_secure_uploads }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -299,7 +301,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enable_s3_uploads = true }
|
before { SiteSetting.enable_s3_uploads = true }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
|
|
||||||
|
@ -307,7 +309,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.enable_s3_uploads = false }
|
before { SiteSetting.enable_s3_uploads = false }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -317,7 +319,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { GlobalSetting.stubs(:use_s3?).returns(true) }
|
before { GlobalSetting.stubs(:use_s3?).returns(true) }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -326,7 +328,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.s3_use_acls = false }
|
before { SiteSetting.s3_use_acls = false }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -345,7 +347,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { GlobalSetting.stubs(:use_s3?).returns(true) }
|
before { GlobalSetting.stubs(:use_s3?).returns(true) }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -356,7 +358,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { GlobalSetting.stubs(:use_s3?).returns(false) }
|
before { GlobalSetting.stubs(:use_s3?).returns(false) }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
|
|
||||||
|
@ -366,7 +368,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.s3_upload_bucket = nil }
|
before { SiteSetting.s3_upload_bucket = nil }
|
||||||
|
|
||||||
it "is not ok" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -377,7 +379,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.s3_upload_bucket = "some-bucket" }
|
before { SiteSetting.s3_upload_bucket = "some-bucket" }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -399,49 +401,47 @@ RSpec.describe SiteSettings::Validations do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "cannot contain a user agent that's shorter than 3 characters" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
too_short_message,
|
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,
|
Discourse::InvalidParameters,
|
||||||
too_short_message,
|
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,
|
Discourse::InvalidParameters,
|
||||||
too_short_message,
|
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,
|
Discourse::InvalidParameters,
|
||||||
too_short_message,
|
too_short_message,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows user agents that are 3 characters or longer" do
|
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 { validations.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 { validations.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("pupsc|kcx") }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows the setting to be empty" do
|
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
|
end
|
||||||
|
|
||||||
it "cannot contain a token of a popular browser user agent" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
popular_browser_message,
|
popular_browser_message,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect { subject.validate_slow_down_crawler_user_agents("chRome|badcrawler") }.to raise_error(
|
expect {
|
||||||
Discourse::InvalidParameters,
|
validations.validate_slow_down_crawler_user_agents("chRome|badcrawler")
|
||||||
popular_browser_message,
|
}.to raise_error(Discourse::InvalidParameters, popular_browser_message)
|
||||||
)
|
|
||||||
|
|
||||||
expect { subject.validate_slow_down_crawler_user_agents("html|badcrawler") }.to raise_error(
|
expect {
|
||||||
Discourse::InvalidParameters,
|
validations.validate_slow_down_crawler_user_agents("html|badcrawler")
|
||||||
popular_browser_message,
|
}.to raise_error(Discourse::InvalidParameters, popular_browser_message)
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.composer_media_optimization_image_enabled = true }
|
before { SiteSetting.composer_media_optimization_image_enabled = true }
|
||||||
|
|
||||||
it "should raise an error" do
|
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,
|
Discourse::InvalidParameters,
|
||||||
error_message,
|
error_message,
|
||||||
)
|
)
|
||||||
|
@ -469,14 +469,14 @@ RSpec.describe SiteSettings::Validations do
|
||||||
before { SiteSetting.composer_media_optimization_image_enabled = false }
|
before { SiteSetting.composer_media_optimization_image_enabled = false }
|
||||||
|
|
||||||
it "should be ok" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the new value is true" do
|
context "when the new value is true" do
|
||||||
it "should be ok" 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
|
end
|
||||||
end
|
end
|
||||||
|
@ -485,13 +485,13 @@ RSpec.describe SiteSettings::Validations do
|
||||||
describe "#twitter_summary_large_image" do
|
describe "#twitter_summary_large_image" do
|
||||||
it "does not allow SVG image files" do
|
it "does not allow SVG image files" do
|
||||||
upload = Fabricate(:upload, url: "/images/logo-dark.svg", extension: "svg")
|
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,
|
Discourse::InvalidParameters,
|
||||||
I18n.t("errors.site_settings.twitter_summary_large_image_no_svg"),
|
I18n.t("errors.site_settings.twitter_summary_large_image_no_svg"),
|
||||||
)
|
)
|
||||||
upload.update!(url: "/images/logo-dark.png", extension: "png")
|
upload.update!(url: "/images/logo-dark.png", extension: "png")
|
||||||
expect { subject.validate_twitter_summary_large_image(upload.id) }.not_to raise_error
|
expect { validations.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(nil) }.not_to raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe TopicUploadSecurityManager do
|
RSpec.describe TopicUploadSecurityManager do
|
||||||
|
subject(:manager) { described_class.new(topic) }
|
||||||
|
|
||||||
let(:group) { Fabricate(:group) }
|
let(:group) { Fabricate(:group) }
|
||||||
let(:category) { Fabricate(:category) }
|
let(:category) { Fabricate(:category) }
|
||||||
let!(:topic) { Fabricate(:topic, user: user, category: category) }
|
let!(:topic) { Fabricate(:topic, user: user, category: category) }
|
||||||
|
@ -10,8 +12,6 @@ RSpec.describe TopicUploadSecurityManager do
|
||||||
let!(:post3) { Fabricate(:post, topic: topic) }
|
let!(:post3) { Fabricate(:post, topic: topic) }
|
||||||
let!(:post4) { 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
|
context "when a topic has posts linked to secure uploads" do
|
||||||
let!(:upload) { Fabricate(:secure_upload) }
|
let!(:upload) { Fabricate(:secure_upload) }
|
||||||
let!(:upload2) { 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
|
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
|
Post.any_instance.expects(:rebake!).once
|
||||||
subject.run
|
manager.run
|
||||||
expect(upload3.reload.secure?).to eq(true)
|
expect(upload3.reload.secure?).to eq(true)
|
||||||
expect(upload3.reload.access_control_post).to eq(post4)
|
expect(upload3.reload.access_control_post).to eq(post4)
|
||||||
end
|
end
|
||||||
|
@ -136,7 +136,7 @@ RSpec.describe TopicUploadSecurityManager do
|
||||||
before { SiteSetting.secure_uploads = false }
|
before { SiteSetting.secure_uploads = false }
|
||||||
|
|
||||||
it "does not change the upload secure status and does not set the access control post" do
|
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.secure?).to eq(false)
|
||||||
expect(upload3.reload.access_control_post).to eq(nil)
|
expect(upload3.reload.access_control_post).to eq(nil)
|
||||||
end
|
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
|
it "does not change the upload secure status and does not set the access control post" do
|
||||||
Post.any_instance.expects(:rebake!).never
|
Post.any_instance.expects(:rebake!).never
|
||||||
subject.run
|
manager.run
|
||||||
expect(upload3.reload.secure?).to eq(false)
|
expect(upload3.reload.secure?).to eq(false)
|
||||||
expect(upload3.reload.access_control_post).to eq(nil)
|
expect(upload3.reload.access_control_post).to eq(nil)
|
||||||
end
|
end
|
||||||
|
@ -161,14 +161,14 @@ RSpec.describe TopicUploadSecurityManager do
|
||||||
|
|
||||||
def expect_upload_status_not_to_change
|
def expect_upload_status_not_to_change
|
||||||
Post.any_instance.expects(:rebake!).never
|
Post.any_instance.expects(:rebake!).never
|
||||||
subject.run
|
manager.run
|
||||||
expect(upload.reload.secure?).to eq(true)
|
expect(upload.reload.secure?).to eq(true)
|
||||||
expect(upload2.reload.secure?).to eq(true)
|
expect(upload2.reload.secure?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def expect_upload_status_to_change_and_rebake
|
def expect_upload_status_to_change_and_rebake
|
||||||
Post.any_instance.expects(:rebake!).twice
|
Post.any_instance.expects(:rebake!).twice
|
||||||
subject.run
|
manager.run
|
||||||
expect(upload.reload.secure?).to eq(false)
|
expect(upload.reload.secure?).to eq(false)
|
||||||
expect(upload2.reload.secure?).to eq(false)
|
expect(upload2.reload.secure?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UploadSecurity do
|
RSpec.describe UploadSecurity do
|
||||||
|
subject(:security) { described_class.new(upload, opts) }
|
||||||
|
|
||||||
fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) }
|
fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) }
|
||||||
fab!(:post_in_secure_context) do
|
fab!(:post_in_secure_context) do
|
||||||
Fabricate(:post, topic: Fabricate(:topic, category: private_category))
|
Fabricate(:post, topic: Fabricate(:topic, category: private_category))
|
||||||
end
|
end
|
||||||
fab!(:upload) { Fabricate(:upload) }
|
fab!(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
let(:type) { nil }
|
let(:type) { nil }
|
||||||
let(:opts) { { type: type, creating: creating } }
|
let(:opts) { { type: type, creating: creating } }
|
||||||
|
|
||||||
subject { described_class.new(upload, opts) }
|
|
||||||
|
|
||||||
context "when secure uploads is enabled" do
|
context "when secure uploads is enabled" do
|
||||||
before do
|
before do
|
||||||
setup_s3
|
setup_s3
|
||||||
|
@ -24,63 +25,63 @@ RSpec.describe UploadSecurity do
|
||||||
before { SiteSetting.login_required = true }
|
before { SiteSetting.login_required = true }
|
||||||
|
|
||||||
it "returns true" do
|
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 in public context" do
|
context "when uploading in public context" do
|
||||||
describe "for a public type badge_image" do
|
describe "for a public type badge_image" do
|
||||||
let(:type) { "badge_image" }
|
let(:type) { "badge_image" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type group_flair" do
|
describe "for a public type group_flair" do
|
||||||
let(:type) { "group_flair" }
|
let(:type) { "group_flair" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type avatar" do
|
describe "for a public type avatar" do
|
||||||
let(:type) { "avatar" }
|
let(:type) { "avatar" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type custom_emoji" do
|
describe "for a public type custom_emoji" do
|
||||||
let(:type) { "custom_emoji" }
|
let(:type) { "custom_emoji" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type profile_background" do
|
describe "for a public type profile_background" do
|
||||||
let(:type) { "profile_background" }
|
let(:type) { "profile_background" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type avatar" do
|
describe "for a public type avatar" do
|
||||||
let(:type) { "avatar" }
|
let(:type) { "avatar" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type category_logo" do
|
describe "for a public type category_logo" do
|
||||||
let(:type) { "category_logo" }
|
let(:type) { "category_logo" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a public type category_background" do
|
describe "for a public type category_background" do
|
||||||
let(:type) { "category_background" }
|
let(:type) { "category_background" }
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -88,12 +89,12 @@ RSpec.describe UploadSecurity do
|
||||||
let(:type) { "my_custom_type" }
|
let(:type) { "my_custom_type" }
|
||||||
|
|
||||||
it "returns true if the custom type has not been added" do
|
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
|
end
|
||||||
|
|
||||||
it "returns false if the custom type has been added" do
|
it "returns false if the custom type has been added" do
|
||||||
UploadSecurity.register_custom_public_type(type)
|
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
|
UploadSecurity.reset_custom_public_types
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -102,7 +103,7 @@ RSpec.describe UploadSecurity do
|
||||||
before { upload.stubs(:for_theme).returns(true) }
|
before { upload.stubs(:for_theme).returns(true) }
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ RSpec.describe UploadSecurity do
|
||||||
before { upload.stubs(:for_site_setting).returns(true) }
|
before { upload.stubs(:for_site_setting).returns(true) }
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ RSpec.describe UploadSecurity do
|
||||||
before { upload.stubs(:for_gravatar).returns(true) }
|
before { upload.stubs(:for_gravatar).returns(true) }
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ RSpec.describe UploadSecurity do
|
||||||
e.url == "/images/emoji/twitter/falafel.png?v=#{Emoji::EMOJI_VERSION}"
|
e.url == "/images/emoji/twitter/falafel.png?v=#{Emoji::EMOJI_VERSION}"
|
||||||
end
|
end
|
||||||
upload.update!(origin: "http://localhost:3000#{falafel.url}")
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -139,14 +140,14 @@ RSpec.describe UploadSecurity do
|
||||||
before { upload.update(access_control_post_id: post_in_secure_context.id) }
|
before { upload.update(access_control_post_id: post_in_secure_context.id) }
|
||||||
|
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the post is deleted" do
|
context "when the post is deleted" do
|
||||||
before { post_in_secure_context.trash! }
|
before { post_in_secure_context.trash! }
|
||||||
|
|
||||||
it "still determines whether the post has secure uploads; returns true" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -154,28 +155,28 @@ RSpec.describe UploadSecurity do
|
||||||
context "when uploading in the composer" do
|
context "when uploading in the composer" do
|
||||||
let(:type) { "composer" }
|
let(:type) { "composer" }
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when uploading for a group message" do
|
context "when uploading for a group message" do
|
||||||
before { upload.stubs(:for_group_message).returns(true) }
|
before { upload.stubs(:for_group_message).returns(true) }
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when uploading for a PM" do
|
context "when uploading for a PM" do
|
||||||
before { upload.stubs(:for_private_message).returns(true) }
|
before { upload.stubs(:for_private_message).returns(true) }
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when upload is already secure" do
|
context "when upload is already secure" do
|
||||||
before { upload.update(secure: true) }
|
before { upload.update(secure: true) }
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -185,7 +186,7 @@ RSpec.describe UploadSecurity do
|
||||||
context "when the access control post has_secure_uploads?" do
|
context "when the access control post has_secure_uploads?" do
|
||||||
before { upload.update(access_control_post: post_in_secure_context) }
|
before { upload.update(access_control_post: post_in_secure_context) }
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
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
|
describe "when the upload is first used for a post in a secure context" do
|
||||||
it "returns true" do
|
it "returns true" do
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(true)
|
expect(security.should_be_secure?).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -223,7 +224,7 @@ RSpec.describe UploadSecurity do
|
||||||
post_in_secure_context.trash!
|
post_in_secure_context.trash!
|
||||||
CustomEmoji.create(name: "meme", upload: upload)
|
CustomEmoji.create(name: "meme", upload: upload)
|
||||||
|
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -231,7 +232,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
SiteSetting.favicon = upload
|
SiteSetting.favicon = upload
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -239,7 +240,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:theme_field, type_id: ThemeField.types[:theme_upload_var], upload: upload)
|
Fabricate(:theme_field, type_id: ThemeField.types[:theme_upload_var], upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -247,7 +248,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:group, flair_upload: upload)
|
Fabricate(:group, flair_upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -255,7 +256,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
CustomEmoji.create(name: "meme", upload: upload)
|
CustomEmoji.create(name: "meme", upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the created_at dates for upload references are identical" do
|
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: custom_emoji).update!(created_at: now)
|
||||||
UploadReference.find_by(target: post_in_secure_context).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
|
end
|
||||||
end
|
end
|
||||||
|
@ -275,7 +276,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:badge, image_upload: upload)
|
Fabricate(:badge, image_upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -283,7 +284,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:category, uploaded_logo: upload)
|
Fabricate(:category, uploaded_logo: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -292,7 +293,7 @@ RSpec.describe UploadSecurity do
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
user.user_profile.update!(card_background_upload: upload)
|
user.user_profile.update!(card_background_upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -300,7 +301,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:user, uploaded_avatar: upload)
|
Fabricate(:user, uploaded_avatar: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,7 +309,7 @@ RSpec.describe UploadSecurity do
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
Fabricate(:user_avatar, custom_upload: upload)
|
Fabricate(:user_avatar, custom_upload: upload)
|
||||||
create_secure_post_reference
|
create_secure_post_reference
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -320,14 +321,14 @@ RSpec.describe UploadSecurity do
|
||||||
before { SiteSetting.secure_uploads = false }
|
before { SiteSetting.secure_uploads = false }
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "for attachments" do
|
context "for attachments" do
|
||||||
before { upload.update(original_filename: "test.pdf") }
|
before { upload.update(original_filename: "test.pdf") }
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
expect(subject.should_be_secure?).to eq(false)
|
expect(security.should_be_secure?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UserCommScreener do
|
RSpec.describe UserCommScreener do
|
||||||
fab!(:target_user1) { Fabricate(:user, username: "bobscreen") }
|
subject(:screener) do
|
||||||
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
|
|
||||||
described_class.new(
|
described_class.new(
|
||||||
acting_user: acting_user,
|
acting_user: acting_user,
|
||||||
target_user_ids: [
|
target_user_ids: [
|
||||||
|
@ -25,6 +14,17 @@ RSpec.describe UserCommScreener do
|
||||||
)
|
)
|
||||||
end
|
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
|
it "allows initializing the class with both an acting_user_id and an acting_user" do
|
||||||
acting_user = Fabricate(:user)
|
acting_user = Fabricate(:user)
|
||||||
screener = described_class.new(acting_user: acting_user, target_user_ids: [target_user1.id])
|
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
|
describe "#allowing_actor_communication" do
|
||||||
it "returns the usernames of people not ignoring, muting, or disallowing PMs from the actor" 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],
|
[target_user4.id, target_user5.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -66,7 +66,7 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#preventing_actor_communication" do
|
describe "#preventing_actor_communication" do
|
||||||
it "returns the usernames of people ignoring, muting, or disallowing PMs from the actor" 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],
|
[target_user1.id, target_user2.id, target_user3.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -74,23 +74,23 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#ignoring_or_muting_actor?" do
|
describe "#ignoring_or_muting_actor?" do
|
||||||
it "does not raise an error when looking for a user who has no communication preferences" 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
|
end
|
||||||
|
|
||||||
it "returns true for a user muting the actor" do
|
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
|
end
|
||||||
|
|
||||||
it "returns true for a user ignoring the actor" do
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user neither ignoring or muting the actor" do
|
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
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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,
|
Discourse::NotFound,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -98,34 +98,34 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#disallowing_pms_from_actor?" do
|
describe "#disallowing_pms_from_actor?" do
|
||||||
it "returns true for a user disallowing all PMs" 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
|
end
|
||||||
|
|
||||||
it "returns true for a user allowing only PMs for certain users but not the actor" do
|
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)
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user allowing only PMs for certain users which the actor allowed" do
|
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)
|
target_user4.user_option.update!(enable_allowed_pm_users: true)
|
||||||
AllowedPmUser.create!(user: target_user4, allowed_pm_user: acting_user)
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user not disallowing PMs or muting or ignoring" do
|
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
|
end
|
||||||
|
|
||||||
it "returns true for a user not disallowing PMs but still ignoring" do
|
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
|
end
|
||||||
|
|
||||||
it "returns true for a user not disallowing PMs but still muting" do
|
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
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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,
|
Discourse::NotFound,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -146,7 +146,7 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#allowing_actor_communication" do
|
describe "#allowing_actor_communication" do
|
||||||
it "returns all usernames since staff can communicate with anyone" 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],
|
[target_user1.id, target_user2.id, target_user3.id, target_user4.id, target_user5.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -154,25 +154,25 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#preventing_actor_communication" do
|
describe "#preventing_actor_communication" do
|
||||||
it "does not return any usernames since no users can prevent staff communicating with them" 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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#ignoring_or_muting_actor?" do
|
describe "#ignoring_or_muting_actor?" do
|
||||||
it "returns false for a user muting the staff" 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
|
end
|
||||||
|
|
||||||
it "returns false for a user ignoring the staff actor" do
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user neither ignoring or muting the actor" do
|
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
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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,
|
Discourse::NotFound,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -180,28 +180,28 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#disallowing_pms_from_actor?" do
|
describe "#disallowing_pms_from_actor?" do
|
||||||
it "returns false for a user disallowing all PMs" 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
|
end
|
||||||
|
|
||||||
it "returns false for a user allowing only PMs for certain users but not the actor" do
|
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)
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user not disallowing PMs or muting or ignoring" do
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user not disallowing PMs but still ignoring" do
|
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
|
end
|
||||||
|
|
||||||
it "returns false for a user not disallowing PMs but still muting" do
|
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
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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,
|
Discourse::NotFound,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -232,13 +232,13 @@ RSpec.describe UserCommScreener do
|
||||||
describe "#actor_preventing_communication" do
|
describe "#actor_preventing_communication" do
|
||||||
it "returns the user_ids of the users the actor is ignoring, muting, or disallowing PMs from" 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)
|
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],
|
[target_user1.id, target_user2.id, target_user3.id, target_user5.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not include users the actor is disallowing PMs from if they have not set enable_allowed_pm_users" do
|
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],
|
[target_user1.id, target_user2.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -250,7 +250,7 @@ RSpec.describe UserCommScreener do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns an empty array and does not error" do
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -258,7 +258,7 @@ RSpec.describe UserCommScreener do
|
||||||
describe "#actor_allowing_communication" 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
|
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)
|
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
|
end
|
||||||
|
|
||||||
describe "when the actor has no preferences" do
|
describe "when the actor has no preferences" do
|
||||||
|
@ -268,7 +268,7 @@ RSpec.describe UserCommScreener do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns an array of the target users and does not error" do
|
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],
|
[target_user1.id, target_user2.id, target_user3.id, target_user4.id, target_user5.id],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -277,49 +277,51 @@ RSpec.describe UserCommScreener do
|
||||||
|
|
||||||
describe "#actor_ignoring?" do
|
describe "#actor_ignoring?" do
|
||||||
it "returns true for user ids that the actor is 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(screener.actor_ignoring?(target_user2.id)).to eq(true)
|
||||||
expect(subject.actor_ignoring?(target_user4.id)).to eq(false)
|
expect(screener.actor_ignoring?(target_user4.id)).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#actor_muting?" do
|
describe "#actor_muting?" do
|
||||||
it "returns true for user ids that the actor is 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(screener.actor_muting?(target_user1.id)).to eq(true)
|
||||||
expect(subject.actor_muting?(target_user2.id)).to eq(false)
|
expect(screener.actor_muting?(target_user2.id)).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#actor_disallowing_pms?" do
|
describe "#actor_disallowing_pms?" do
|
||||||
it "returns true for user ids that the actor is not explicitly allowing PMs from" 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)
|
acting_user.user_option.update!(enable_allowed_pm_users: true)
|
||||||
expect(subject.actor_disallowing_pms?(target_user3.id)).to eq(true)
|
expect(screener.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_user1.id)).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns true if the actor has disallowed all PMs" do
|
it "returns true if the actor has disallowed all PMs" do
|
||||||
acting_user.user_option.update!(allow_private_messages: false)
|
acting_user.user_option.update!(allow_private_messages: false)
|
||||||
expect(subject.actor_disallowing_pms?(target_user3.id)).to eq(true)
|
expect(screener.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_user1.id)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a NotFound error if the user_id passed in is not part of the target users" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#actor_disallowing_all_pms?" do
|
describe "#actor_disallowing_all_pms?" do
|
||||||
it "returns true if the acting user has disabled private messages altogether" 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)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe AllowedIpAddressValidator do
|
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(:record) { Fabricate.build(:user, trust_level: TrustLevel[0], ip_address: "99.232.23.123") }
|
||||||
let(:validator) { described_class.new(attributes: :ip_address) }
|
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
|
context "when ip address should be blocked" do
|
||||||
it "should add an error" do
|
it "should add an error" do
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe CssColorValidator do
|
RSpec.describe CssColorValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
it "validates hex colors" do
|
it "validates hex colors" do
|
||||||
expect(subject.valid_value?("#0")).to eq(false)
|
expect(validator.valid_value?("#0")).to eq(false)
|
||||||
expect(subject.valid_value?("#00")).to eq(false)
|
expect(validator.valid_value?("#00")).to eq(false)
|
||||||
expect(subject.valid_value?("#000")).to eq(true)
|
expect(validator.valid_value?("#000")).to eq(true)
|
||||||
expect(subject.valid_value?("#0000")).to eq(false)
|
expect(validator.valid_value?("#0000")).to eq(false)
|
||||||
expect(subject.valid_value?("#00000")).to eq(false)
|
expect(validator.valid_value?("#00000")).to eq(false)
|
||||||
expect(subject.valid_value?("#000000")).to eq(true)
|
expect(validator.valid_value?("#000000")).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates css colors" do
|
it "validates css colors" do
|
||||||
expect(subject.valid_value?("red")).to eq(true)
|
expect(validator.valid_value?("red")).to eq(true)
|
||||||
expect(subject.valid_value?("green")).to eq(true)
|
expect(validator.valid_value?("green")).to eq(true)
|
||||||
expect(subject.valid_value?("blue")).to eq(true)
|
expect(validator.valid_value?("blue")).to eq(true)
|
||||||
expect(subject.valid_value?("hello")).to eq(false)
|
expect(validator.valid_value?("hello")).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe EnableLocalLoginsViaEmailValidator do
|
RSpec.describe EnableLocalLoginsViaEmailValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
describe "#valid_value?" do
|
describe "#valid_value?" do
|
||||||
describe "when 'enable_local_logins' is false" do
|
describe "when 'enable_local_logins' is false" do
|
||||||
|
@ -9,15 +9,15 @@ RSpec.describe EnableLocalLoginsViaEmailValidator do
|
||||||
|
|
||||||
describe "when val is false" do
|
describe "when val is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should not be valid" 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"),
|
I18n.t("site_settings.errors.enable_local_logins_disabled"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -29,13 +29,13 @@ RSpec.describe EnableLocalLoginsViaEmailValidator do
|
||||||
|
|
||||||
describe "when val is false" do
|
describe "when val is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should be valid" 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe EnableSsoValidator do
|
RSpec.describe EnableSsoValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
describe "#valid_value?" do
|
describe "#valid_value?" do
|
||||||
describe "when 'sso url' is empty" do
|
describe "when 'sso url' is empty" do
|
||||||
|
@ -9,15 +9,15 @@ RSpec.describe EnableSsoValidator do
|
||||||
|
|
||||||
describe "when val is false" do
|
describe "when val is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should not be valid" 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"),
|
I18n.t("site_settings.errors.discourse_connect_url_is_empty"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -29,13 +29,13 @@ RSpec.describe EnableSsoValidator do
|
||||||
|
|
||||||
describe "when value is false" do
|
describe "when value is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should be valid" 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
|
end
|
||||||
end
|
end
|
||||||
|
@ -46,13 +46,13 @@ RSpec.describe EnableSsoValidator do
|
||||||
it "should be invalid" do
|
it "should be invalid" do
|
||||||
SiteSetting.enforce_second_factor = "all"
|
SiteSetting.enforce_second_factor = "all"
|
||||||
|
|
||||||
expect(subject.valid_value?("t")).to eq(false)
|
expect(validator.valid_value?("t")).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
SiteSetting.enforce_second_factor = "no"
|
SiteSetting.enforce_second_factor = "no"
|
||||||
|
|
||||||
expect(subject.valid_value?("t")).to eq(true)
|
expect(validator.valid_value?("t")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe ExternalSystemAvatarsValidator do
|
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
|
it "disallows disabling external system avatars when Unicode usernames are enabled" do
|
||||||
SiteSetting.unicode_usernames = true
|
SiteSetting.unicode_usernames = true
|
||||||
|
|
||||||
expect(subject.valid_value?("f")).to eq(false)
|
expect(validator.valid_value?("f")).to eq(false)
|
||||||
expect(subject.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars"))
|
expect(validator.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars"))
|
||||||
|
|
||||||
expect(subject.valid_value?("t")).to eq(true)
|
expect(validator.valid_value?("t")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows disabling external system avatars when Unicode usernames are disabled" do
|
it "allows disabling external system avatars when Unicode usernames are disabled" do
|
||||||
SiteSetting.unicode_usernames = false
|
SiteSetting.unicode_usernames = false
|
||||||
|
|
||||||
expect(subject.valid_value?("t")).to eq(true)
|
expect(validator.valid_value?("t")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
|
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe IpAddressFormatValidator do
|
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(:record) { Fabricate.build(:screened_ip_address, ip_address: "99.232.23.123") }
|
||||||
let(:validator) { described_class.new(attributes: :ip_address) }
|
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|
|
%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
|
it "should not add an error for #{arg}" do
|
||||||
|
|
|
@ -5,9 +5,10 @@ RSpec.describe PasswordValidator do
|
||||||
I18n.t("activerecord.errors.models.user.attributes.password.#{key.to_s}")
|
I18n.t("activerecord.errors.models.user.attributes.password.#{key.to_s}")
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:validator) { described_class.new(attributes: :password) }
|
|
||||||
subject(:validate) { validator.validate_each(record, :password, @password) }
|
subject(:validate) { validator.validate_each(record, :password, @password) }
|
||||||
|
|
||||||
|
let(:validator) { described_class.new(attributes: :password) }
|
||||||
|
|
||||||
describe "password required" do
|
describe "password required" do
|
||||||
let(:record) do
|
let(:record) do
|
||||||
u = Fabricate.build(:user, password: @password)
|
u = Fabricate.build(:user, password: @password)
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe RegexPresenceValidator do
|
RSpec.describe RegexPresenceValidator do
|
||||||
subject do
|
subject(:validator) do
|
||||||
described_class.new(regex: "latest", regex_error: "site_settings.errors.must_include_latest")
|
described_class.new(regex: "latest", regex_error: "site_settings.errors.must_include_latest")
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#valid_value?" do
|
describe "#valid_value?" do
|
||||||
describe "when value is present" do
|
describe "when value is present" do
|
||||||
it "without regex match" 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
|
end
|
||||||
|
|
||||||
it "with regex match" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is empty" do
|
describe "when value is empty" do
|
||||||
it "should not be valid" 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe RegexpListValidator do
|
RSpec.describe RegexpListValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
it "allows lists of valid regular expressions" do
|
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
|
end
|
||||||
|
|
||||||
it "does not allow lists of invalid regular expressions do" do
|
it "does not allow lists of invalid regular expressions do" do
|
||||||
expect(subject.valid_value?('\d+|[0-9?|\w+')).to eq(false)
|
expect(validator.valid_value?('\d+|[0-9?|\w+')).to eq(false)
|
||||||
expect(subject.error_message).to eq(
|
expect(validator.error_message).to eq(
|
||||||
I18n.t(
|
I18n.t(
|
||||||
"site_settings.errors.invalid_regex_with_message",
|
"site_settings.errors.invalid_regex_with_message",
|
||||||
regex: "[0-9?",
|
regex: "[0-9?",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe SsoOverridesEmailValidator do
|
RSpec.describe SsoOverridesEmailValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
describe "#valid_value?" do
|
describe "#valid_value?" do
|
||||||
describe "when 'email editable' is true" do
|
describe "when 'email editable' is true" do
|
||||||
|
@ -13,15 +13,17 @@ RSpec.describe SsoOverridesEmailValidator do
|
||||||
|
|
||||||
describe "when val is false" do
|
describe "when val is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should not be valid" 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
|
end
|
||||||
end
|
end
|
||||||
|
@ -35,13 +37,13 @@ RSpec.describe SsoOverridesEmailValidator do
|
||||||
|
|
||||||
describe "when value is false" do
|
describe "when value is false" do
|
||||||
it "should be valid" do
|
it "should be valid" do
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when value is true" do
|
describe "when value is true" do
|
||||||
it "should be valid" 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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UnicodeUsernameAllowlistValidator do
|
RSpec.describe UnicodeUsernameAllowlistValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
it "allows an empty allowlist" do
|
it "allows an empty allowlist" do
|
||||||
expect(subject.valid_value?("")).to eq(true)
|
expect(validator.valid_value?("")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "disallows leading and trailing slashes" do
|
it "disallows leading and trailing slashes" do
|
||||||
expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash")
|
expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash")
|
||||||
|
|
||||||
expect(subject.valid_value?("/foo/")).to eq(false)
|
expect(validator.valid_value?("/foo/")).to eq(false)
|
||||||
expect(subject.error_message).to eq(expected_error)
|
expect(validator.error_message).to eq(expected_error)
|
||||||
|
|
||||||
expect(subject.valid_value?("foo/")).to eq(true)
|
expect(validator.valid_value?("foo/")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
|
|
||||||
expect(subject.valid_value?("/foo")).to eq(true)
|
expect(validator.valid_value?("/foo")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
|
|
||||||
expect(subject.valid_value?("f/o/o")).to eq(true)
|
expect(validator.valid_value?("f/o/o")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
|
|
||||||
expect(subject.valid_value?("/foo/i")).to eq(false)
|
expect(validator.valid_value?("/foo/i")).to eq(false)
|
||||||
expect(subject.error_message).to eq(expected_error)
|
expect(validator.error_message).to eq(expected_error)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "detects invalid regular expressions" do
|
it "detects invalid regular expressions" do
|
||||||
expected_error =
|
expected_error =
|
||||||
I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: "")
|
I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: "")
|
||||||
|
|
||||||
expect(subject.valid_value?("\\p{Foo}")).to eq(false)
|
expect(validator.valid_value?("\\p{Foo}")).to eq(false)
|
||||||
expect(subject.error_message).to start_with(expected_error)
|
expect(validator.error_message).to start_with(expected_error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UnicodeUsernameValidator do
|
RSpec.describe UnicodeUsernameValidator do
|
||||||
subject { described_class.new }
|
subject(:validator) { described_class.new }
|
||||||
|
|
||||||
it "disallows Unicode usernames when external system avatars are disabled" do
|
it "disallows Unicode usernames when external system avatars are disabled" do
|
||||||
SiteSetting.external_system_avatars_enabled = false
|
SiteSetting.external_system_avatars_enabled = false
|
||||||
|
|
||||||
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.unicode_usernames_avatars"))
|
expect(validator.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars"))
|
||||||
|
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows Unicode usernames when external system avatars are enabled" do
|
it "allows Unicode usernames when external system avatars are enabled" do
|
||||||
SiteSetting.external_system_avatars_enabled = true
|
SiteSetting.external_system_avatars_enabled = true
|
||||||
|
|
||||||
expect(subject.valid_value?("t")).to eq(true)
|
expect(validator.valid_value?("t")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
|
|
||||||
expect(subject.valid_value?("f")).to eq(true)
|
expect(validator.valid_value?("f")).to eq(true)
|
||||||
expect(subject.error_message).to be_blank
|
expect(validator.error_message).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,7 +45,7 @@ RSpec.describe UploadValidator do
|
||||||
original_filename: "test.png",
|
original_filename: "test.png",
|
||||||
filesize: 2_097_152,
|
filesize: 2_097_152,
|
||||||
)
|
)
|
||||||
subject.validate(upload)
|
validator.validate(upload)
|
||||||
expect(upload.errors.full_messages.first).to eq(
|
expect(upload.errors.full_messages.first).to eq(
|
||||||
"Filesize #{I18n.t("upload.images.too_large_humanized", max_size: "1.5 MB")}",
|
"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,
|
for_private_message: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(subject.validate(upload)).to eq(true)
|
expect(validator.validate(upload)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for a normal user" do
|
describe "for a normal user" do
|
||||||
|
@ -75,7 +75,7 @@ RSpec.describe UploadValidator do
|
||||||
for_private_message: true,
|
for_private_message: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(subject.validate(upload)).to eq(nil)
|
expect(validator.validate(upload)).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -91,13 +91,13 @@ RSpec.describe UploadValidator do
|
||||||
|
|
||||||
describe "for admin user" do
|
describe "for admin user" do
|
||||||
it "should allow the upload" do
|
it "should allow the upload" do
|
||||||
expect(subject.validate(upload)).to eq(true)
|
expect(validator.validate(upload)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "when filename is invalid" do
|
describe "when filename is invalid" do
|
||||||
it "should not allow the upload" do
|
it "should not allow the upload" do
|
||||||
upload.original_filename = "test.txt"
|
upload.original_filename = "test.txt"
|
||||||
expect(subject.validate(upload)).to eq(nil)
|
expect(validator.validate(upload)).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -106,7 +106,7 @@ RSpec.describe UploadValidator do
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
it "should not allow the upload" do
|
it "should not allow the upload" do
|
||||||
expect(subject.validate(upload)).to eq(nil)
|
expect(validator.validate(upload)).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UrlValidator do
|
RSpec.describe UrlValidator do
|
||||||
|
subject(:validate) { validator.validate_each(record, :website, record.website) }
|
||||||
|
|
||||||
let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) }
|
let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) }
|
||||||
let(:validator) { described_class.new(attributes: :website) }
|
let(:validator) { described_class.new(attributes: :website) }
|
||||||
subject(:validate) { validator.validate_each(record, :website, record.website) }
|
|
||||||
|
|
||||||
[
|
[
|
||||||
"http://https://google.com",
|
"http://https://google.com",
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe UserFullNameValidator do
|
RSpec.describe UserFullNameValidator do
|
||||||
let(:validator) { described_class.new(attributes: :name) }
|
|
||||||
subject(:validate) { validator.validate_each(record, :name, @name) }
|
subject(:validate) { validator.validate_each(record, :name, @name) }
|
||||||
|
|
||||||
|
let(:validator) { described_class.new(attributes: :name) }
|
||||||
let(:record) { Fabricate.build(:user, name: @name) }
|
let(:record) { Fabricate.build(:user, name: @name) }
|
||||||
|
|
||||||
context "when name is not required" do
|
context "when name is not required" do
|
||||||
|
|
|
@ -38,6 +38,8 @@ require "webauthn/security_key_registration_service"
|
||||||
# The origin params just need to be whatever your localhost URL for Discourse is.
|
# The origin params just need to be whatever your localhost URL for Discourse is.
|
||||||
|
|
||||||
RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
|
subject(:service) { described_class.new(current_user, params, challenge_params) }
|
||||||
|
|
||||||
let(:security_key_user) { current_user }
|
let(:security_key_user) { current_user }
|
||||||
let!(:security_key) do
|
let!(:security_key) do
|
||||||
Fabricate(
|
Fabricate(
|
||||||
|
@ -91,24 +93,23 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:challenge_params_origin) { "http://localhost:3000" }
|
let(:challenge_params_origin) { "http://localhost:3000" }
|
||||||
let(:challenge_params) { { challenge: challenge, rp_id: rp_id, origin: challenge_params_origin } }
|
let(:challenge_params) { { challenge: challenge, rp_id: rp_id, origin: challenge_params_origin } }
|
||||||
let(:current_user) { Fabricate(:user) }
|
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
|
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)
|
expect(security_key.reload.last_used).not_to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when params is blank" do
|
context "when params is blank" do
|
||||||
let(:params) { nil }
|
let(:params) { nil }
|
||||||
it "returns false with no validation" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when params is not blank and not a hash" do
|
context "when params is not blank and not a hash" do
|
||||||
let(:params) { "test" }
|
let(:params) { "test" }
|
||||||
it "returns false with no validation" do
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
before { security_key.destroy }
|
before { security_key.destroy }
|
||||||
|
|
||||||
it "raises a NotFoundError" do
|
it "raises a NotFoundError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::NotFoundError,
|
Webauthn::NotFoundError,
|
||||||
I18n.t("webauthn.validation.not_found_error"),
|
I18n.t("webauthn.validation.not_found_error"),
|
||||||
)
|
)
|
||||||
|
@ -127,7 +128,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:security_key_user) { Fabricate(:user) }
|
let(:security_key_user) { Fabricate(:user) }
|
||||||
|
|
||||||
it "raises an OwnershipError" do
|
it "raises an OwnershipError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::OwnershipError,
|
Webauthn::OwnershipError,
|
||||||
I18n.t("webauthn.validation.ownership_error"),
|
I18n.t("webauthn.validation.ownership_error"),
|
||||||
)
|
)
|
||||||
|
@ -138,7 +139,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:client_data_webauthn_type) { "webauthn.explode" }
|
let(:client_data_webauthn_type) { "webauthn.explode" }
|
||||||
|
|
||||||
it "raises an InvalidTypeError" do
|
it "raises an InvalidTypeError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::InvalidTypeError,
|
Webauthn::InvalidTypeError,
|
||||||
I18n.t("webauthn.validation.invalid_type_error"),
|
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") }
|
let(:client_data_challenge) { Base64.strict_encode64("invalid challenge") }
|
||||||
|
|
||||||
it "raises a ChallengeMismatchError" do
|
it "raises a ChallengeMismatchError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::ChallengeMismatchError,
|
Webauthn::ChallengeMismatchError,
|
||||||
I18n.t("webauthn.validation.challenge_mismatch_error"),
|
I18n.t("webauthn.validation.challenge_mismatch_error"),
|
||||||
)
|
)
|
||||||
|
@ -160,7 +161,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:client_data_origin) { "https://someothersite.com" }
|
let(:client_data_origin) { "https://someothersite.com" }
|
||||||
|
|
||||||
it "raises a InvalidOriginError" do
|
it "raises a InvalidOriginError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::InvalidOriginError,
|
Webauthn::InvalidOriginError,
|
||||||
I18n.t("webauthn.validation.invalid_origin_error"),
|
I18n.t("webauthn.validation.invalid_origin_error"),
|
||||||
)
|
)
|
||||||
|
@ -171,7 +172,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:rp_id) { "bad_rp_id" }
|
let(:rp_id) { "bad_rp_id" }
|
||||||
|
|
||||||
it "raises a InvalidRelyingPartyIdError" do
|
it "raises a InvalidRelyingPartyIdError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::InvalidRelyingPartyIdError,
|
Webauthn::InvalidRelyingPartyIdError,
|
||||||
I18n.t("webauthn.validation.invalid_relying_party_id_error"),
|
I18n.t("webauthn.validation.invalid_relying_party_id_error"),
|
||||||
)
|
)
|
||||||
|
@ -182,7 +183,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
let(:signature) { Base64.strict_encode64("badsig") }
|
let(:signature) { Base64.strict_encode64("badsig") }
|
||||||
|
|
||||||
it "raises a PublicKeyError" do
|
it "raises a PublicKeyError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::PublicKeyError,
|
Webauthn::PublicKeyError,
|
||||||
I18n.t("webauthn.validation.public_key_error"),
|
I18n.t("webauthn.validation.public_key_error"),
|
||||||
)
|
)
|
||||||
|
@ -193,7 +194,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
before { COSE::Algorithm.expects(:find).returns(nil) }
|
before { COSE::Algorithm.expects(:find).returns(nil) }
|
||||||
|
|
||||||
it "raises a UnknownCOSEAlgorithmError" do
|
it "raises a UnknownCOSEAlgorithmError" do
|
||||||
expect { subject.authenticate_security_key }.to raise_error(
|
expect { service.authenticate_security_key }.to raise_error(
|
||||||
Webauthn::UnknownCOSEAlgorithmError,
|
Webauthn::UnknownCOSEAlgorithmError,
|
||||||
I18n.t("webauthn.validation.unknown_cose_algorithm_error"),
|
I18n.t("webauthn.validation.unknown_cose_algorithm_error"),
|
||||||
)
|
)
|
||||||
|
@ -230,7 +231,7 @@ RSpec.describe Webauthn::SecurityKeyAuthenticationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "updates last_used when the security key and params are valid" do
|
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)
|
expect(security_key.reload.last_used).not_to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@ require "webauthn"
|
||||||
require "webauthn/security_key_registration_service"
|
require "webauthn/security_key_registration_service"
|
||||||
|
|
||||||
RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
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_challenge) { Base64.encode64(challenge) }
|
||||||
let(:client_data_webauthn_type) { "webauthn.create" }
|
let(:client_data_webauthn_type) { "webauthn.create" }
|
||||||
let(:client_data_origin) { "http://localhost:3000" }
|
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_params) { { challenge: challenge, rp_id: rp_id, origin: "http://localhost:3000" } }
|
||||||
let(:challenge) { "f1e04530f34a1b6a08d032d8550e23eb8330be04e4166008f26c0e1b42ad" }
|
let(:challenge) { "f1e04530f34a1b6a08d032d8550e23eb8330be04e4166008f26c0e1b42ad" }
|
||||||
let(:current_user) { Fabricate(:user) }
|
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
|
context "when the client data webauthn type is not webauthn.create" do
|
||||||
let(:client_data_webauthn_type) { "webauthn.explode" }
|
let(:client_data_webauthn_type) { "webauthn.explode" }
|
||||||
|
|
||||||
it "raises an InvalidTypeError" do
|
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,
|
Webauthn::InvalidTypeError,
|
||||||
I18n.t("webauthn.validation.invalid_type_error"),
|
I18n.t("webauthn.validation.invalid_type_error"),
|
||||||
)
|
)
|
||||||
|
@ -51,7 +52,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
let(:client_data_challenge) { Base64.encode64("invalid challenge") }
|
let(:client_data_challenge) { Base64.encode64("invalid challenge") }
|
||||||
|
|
||||||
it "raises a ChallengeMismatchError" do
|
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,
|
Webauthn::ChallengeMismatchError,
|
||||||
I18n.t("webauthn.validation.challenge_mismatch_error"),
|
I18n.t("webauthn.validation.challenge_mismatch_error"),
|
||||||
)
|
)
|
||||||
|
@ -62,7 +63,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
let(:client_data_origin) { "https://someothersite.com" }
|
let(:client_data_origin) { "https://someothersite.com" }
|
||||||
|
|
||||||
it "raises a InvalidOriginError" do
|
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,
|
Webauthn::InvalidOriginError,
|
||||||
I18n.t("webauthn.validation.invalid_origin_error"),
|
I18n.t("webauthn.validation.invalid_origin_error"),
|
||||||
)
|
)
|
||||||
|
@ -73,7 +74,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
let(:rp_id) { "bad_rp_id" }
|
let(:rp_id) { "bad_rp_id" }
|
||||||
|
|
||||||
it "raises a InvalidRelyingPartyIdError" do
|
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,
|
Webauthn::InvalidRelyingPartyIdError,
|
||||||
I18n.t("webauthn.validation.invalid_relying_party_id_error"),
|
I18n.t("webauthn.validation.invalid_relying_party_id_error"),
|
||||||
)
|
)
|
||||||
|
@ -87,7 +88,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a UnsupportedPublicKeyAlgorithmError" do
|
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,
|
Webauthn::UnsupportedPublicKeyAlgorithmError,
|
||||||
I18n.t("webauthn.validation.unsupported_public_key_algorithm_error"),
|
I18n.t("webauthn.validation.unsupported_public_key_algorithm_error"),
|
||||||
)
|
)
|
||||||
|
@ -103,7 +104,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a UnsupportedAttestationFormatError" do
|
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,
|
Webauthn::UnsupportedAttestationFormatError,
|
||||||
I18n.t("webauthn.validation.unsupported_attestation_format_error"),
|
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
|
context "when the credential id is already in use for any user" do
|
||||||
it "raises a CredentialIdInUseError" do
|
it "raises a CredentialIdInUseError" do
|
||||||
# register the key to the current user
|
# 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
|
# update the key to be on a different user
|
||||||
other_user = Fabricate(:user)
|
other_user = Fabricate(:user)
|
||||||
security_key.update(user: other_user)
|
security_key.update(user: other_user)
|
||||||
|
|
||||||
# error!
|
# error!
|
||||||
expect { subject.register_second_factor_security_key }.to raise_error(
|
expect { service.register_second_factor_security_key }.to raise_error(
|
||||||
Webauthn::CredentialIdInUseError,
|
Webauthn::CredentialIdInUseError,
|
||||||
I18n.t("webauthn.validation.credential_id_in_use_error"),
|
I18n.t("webauthn.validation.credential_id_in_use_error"),
|
||||||
)
|
)
|
||||||
|
@ -137,7 +138,7 @@ RSpec.describe Webauthn::SecurityKeyRegistrationService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a MalformedAttestationError" do
|
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,
|
Webauthn::MalformedAttestationError,
|
||||||
I18n.t("webauthn.validation.malformed_attestation_error"),
|
I18n.t("webauthn.validation.malformed_attestation_error"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe SubscriptionMailer do
|
RSpec.describe SubscriptionMailer do
|
||||||
|
subject(:mail) { SubscriptionMailer.confirm_unsubscribe(user) }
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
subject { SubscriptionMailer.confirm_unsubscribe(user) }
|
|
||||||
|
|
||||||
it "contains the right URL" do
|
it "contains the right URL" do
|
||||||
expect(subject.body).to include(
|
expect(mail.body).to include(
|
||||||
"#{Discourse.base_url}/email/unsubscribe/#{UnsubscribeKey.last.key}",
|
"#{Discourse.base_url}/email/unsubscribe/#{UnsubscribeKey.last.key}",
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,24 +58,24 @@ RSpec.describe UserNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".signup" do
|
describe ".signup" do
|
||||||
subject { UserNotifications.signup(user) }
|
subject(:email) { UserNotifications.signup(user) }
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(subject.to).to eq([user.email])
|
expect(email.to).to eq([user.email])
|
||||||
expect(subject.subject).to be_present
|
expect(email.subject).to be_present
|
||||||
expect(subject.from).to eq([SiteSetting.notification_email])
|
expect(email.from).to eq([SiteSetting.notification_email])
|
||||||
expect(subject.body).to be_present
|
expect(email.body).to be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".forgot_password" do
|
describe ".forgot_password" do
|
||||||
subject { UserNotifications.forgot_password(user) }
|
subject(:email) { UserNotifications.forgot_password(user) }
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(subject.to).to eq([user.email])
|
expect(email.to).to eq([user.email])
|
||||||
expect(subject.subject).to be_present
|
expect(email.subject).to be_present
|
||||||
expect(subject.from).to eq([SiteSetting.notification_email])
|
expect(email.from).to eq([SiteSetting.notification_email])
|
||||||
expect(subject.body).to be_present
|
expect(email.body).to be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -119,20 +119,21 @@ RSpec.describe UserNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".email_login" do
|
describe ".email_login" do
|
||||||
|
subject(:email) { UserNotifications.email_login(user, email_token: email_token) }
|
||||||
|
|
||||||
let(:email_token) do
|
let(:email_token) do
|
||||||
Fabricate(:email_token, user: user, scope: EmailToken.scopes[:email_login]).token
|
Fabricate(:email_token, user: user, scope: EmailToken.scopes[:email_login]).token
|
||||||
end
|
end
|
||||||
subject { UserNotifications.email_login(user, email_token: email_token) }
|
|
||||||
|
|
||||||
it "generates the right email" do
|
it "generates the right email" do
|
||||||
expect(subject.to).to eq([user.email])
|
expect(email.to).to eq([user.email])
|
||||||
expect(subject.from).to eq([SiteSetting.notification_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),
|
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(
|
I18n.t(
|
||||||
"user_notifications.email_login.text_body_template",
|
"user_notifications.email_login.text_body_template",
|
||||||
site_name: SiteSetting.title,
|
site_name: SiteSetting.title,
|
||||||
|
@ -144,13 +145,13 @@ RSpec.describe UserNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".digest" do
|
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) } }
|
after { Discourse.redis.keys("summary-new-users:*").each { |key| Discourse.redis.del(key) } }
|
||||||
|
|
||||||
context "without new topics" do
|
context "without new topics" do
|
||||||
it "doesn't send the email" do
|
it "doesn't send the email" do
|
||||||
expect(subject.to).to be_blank
|
expect(email.to).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -172,8 +173,8 @@ RSpec.describe UserNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns topics from new users if they're more than 24 hours old" do
|
it "returns topics from new users if they're more than 24 hours old" do
|
||||||
expect(subject.to).to eq([user.email])
|
expect(email.to).to eq([user.email])
|
||||||
html = subject.html_part.body.to_s
|
html = email.html_part.body.to_s
|
||||||
expect(html).to include(new_yesterday.title)
|
expect(html).to include(new_yesterday.title)
|
||||||
expect(html).to_not include(new_today.title)
|
expect(html).to_not include(new_today.title)
|
||||||
end
|
end
|
||||||
|
@ -185,18 +186,18 @@ RSpec.describe UserNotifications do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(subject.to).to eq([user.email])
|
expect(email.to).to eq([user.email])
|
||||||
expect(subject.subject).to be_present
|
expect(email.subject).to be_present
|
||||||
expect(subject.from).to eq([SiteSetting.notification_email])
|
expect(email.from).to eq([SiteSetting.notification_email])
|
||||||
expect(subject.html_part.body.to_s).to be_present
|
expect(email.html_part.body.to_s).to be_present
|
||||||
expect(subject.text_part.body.to_s).to be_present
|
expect(email.text_part.body.to_s).to be_present
|
||||||
expect(subject.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/)
|
expect(email.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/)
|
||||||
expect(subject.html_part.body.to_s).to include("New Users")
|
expect(email.html_part.body.to_s).to include("New Users")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't include new user count if digest_after_minutes is low" do
|
it "doesn't include new user count if digest_after_minutes is low" do
|
||||||
user.user_option.digest_after_minutes = 60
|
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
|
end
|
||||||
|
|
||||||
it "works with min_date string" do
|
it "works with min_date string" do
|
||||||
|
@ -210,8 +211,8 @@ RSpec.describe UserNotifications do
|
||||||
SiteSetting.email_prefix = "Try Discourse"
|
SiteSetting.email_prefix = "Try Discourse"
|
||||||
SiteSetting.title = "Discourse Meta"
|
SiteSetting.title = "Discourse Meta"
|
||||||
|
|
||||||
expect(subject.subject).to match(/Try Discourse/)
|
expect(email.subject).to match(/Try Discourse/)
|
||||||
expect(subject.subject).not_to match(/Discourse Meta/)
|
expect(email.subject).not_to match(/Discourse Meta/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes unread likes received count within the since date" do
|
it "includes unread likes received count within the since date" do
|
||||||
|
@ -257,7 +258,7 @@ RSpec.describe UserNotifications do
|
||||||
created_at: 1.hour.ago,
|
created_at: 1.hour.ago,
|
||||||
)
|
)
|
||||||
deleted.trash!
|
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 deleted.title
|
||||||
expect(html).to_not include post.raw
|
expect(html).to_not include post.raw
|
||||||
end
|
end
|
||||||
|
@ -276,7 +277,7 @@ RSpec.describe UserNotifications do
|
||||||
raw: "secret draft content",
|
raw: "secret draft content",
|
||||||
created_at: 1.hour.ago,
|
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 topic.title
|
||||||
expect(html).to_not include post.raw
|
expect(html).to_not include post.raw
|
||||||
end
|
end
|
||||||
|
@ -319,7 +320,7 @@ RSpec.describe UserNotifications do
|
||||||
post_type: Post.types[:small_action],
|
post_type: Post.types[:small_action],
|
||||||
created_at: 1.hour.ago,
|
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 whisper.raw
|
||||||
expect(html).to_not include mod_action.raw
|
expect(html).to_not include mod_action.raw
|
||||||
expect(html).to_not include small_action.raw
|
expect(html).to_not include small_action.raw
|
||||||
|
@ -365,7 +366,7 @@ RSpec.describe UserNotifications do
|
||||||
user_deleted: true,
|
user_deleted: true,
|
||||||
created_at: 1.hour.ago,
|
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 deleted.raw
|
||||||
expect(html).to_not include hidden.raw
|
expect(html).to_not include hidden.raw
|
||||||
expect(html).to_not include user_deleted.raw
|
expect(html).to_not include user_deleted.raw
|
||||||
|
@ -389,7 +390,7 @@ RSpec.describe UserNotifications do
|
||||||
post_number: 1,
|
post_number: 1,
|
||||||
created_at: 1.minute.ago,
|
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
|
expect(html).to_not include too_new.title
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -408,20 +409,20 @@ RSpec.describe UserNotifications do
|
||||||
|
|
||||||
theme.set_default!
|
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 "F0F0F0"
|
||||||
expect(html).to include "1E1E1E"
|
expect(html).to include "1E1E1E"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports subfolder" do
|
it "supports subfolder" do
|
||||||
set_subfolder "/forum"
|
set_subfolder "/forum"
|
||||||
html = subject.html_part.body.to_s
|
html = email.html_part.body.to_s
|
||||||
text = subject.text_part.body.to_s
|
text = email.text_part.body.to_s
|
||||||
expect(html).to be_present
|
expect(html).to be_present
|
||||||
expect(text).to be_present
|
expect(text).to be_present
|
||||||
expect(html).to_not include("/forum/forum")
|
expect(html).to_not include("/forum/forum")
|
||||||
expect(text).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}/,
|
/http:\/\/test.localhost\/forum\/email\/unsubscribe\/\h{64}/,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -432,7 +433,7 @@ RSpec.describe UserNotifications do
|
||||||
|
|
||||||
it "applies lang/xml:lang html attributes" do
|
it "applies lang/xml:lang html attributes" do
|
||||||
SiteSetting.default_locale = "pl_PL"
|
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(' lang="pl-PL"')
|
||||||
expect(html).to match(' xml:lang="pl-PL"')
|
expect(html).to match(' xml:lang="pl-PL"')
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe VersionMailer do
|
RSpec.describe VersionMailer do
|
||||||
subject { VersionMailer.send_notice }
|
subject(:mail) { VersionMailer.send_notice }
|
||||||
|
|
||||||
context "when contact_email is blank" do
|
context "when contact_email is blank" do
|
||||||
before { SiteSetting.contact_email = "" }
|
before { SiteSetting.contact_email = "" }
|
||||||
|
|
||||||
it "doesn't send the email" do
|
it "doesn't send the email" do
|
||||||
expect(subject.to).to be_blank
|
expect(mail.to).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ RSpec.describe VersionMailer do
|
||||||
before { SiteSetting.contact_email = "me@example.com" }
|
before { SiteSetting.contact_email = "me@example.com" }
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
expect(subject.to).to eq(["me@example.com"])
|
expect(mail.to).to eq(["me@example.com"])
|
||||||
expect(subject.subject).to be_present
|
expect(mail.subject).to be_present
|
||||||
expect(subject.from).to eq([SiteSetting.notification_email])
|
expect(mail.from).to eq([SiteSetting.notification_email])
|
||||||
expect(subject.body).to be_present
|
expect(mail.body).to be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -126,93 +126,93 @@ RSpec.describe AdminDashboardData do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "rails_env_check" do
|
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
|
it "returns nil when running in production mode" do
|
||||||
Rails.stubs(env: ActiveSupport::StringInquirer.new("production"))
|
Rails.stubs(env: ActiveSupport::StringInquirer.new("production"))
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when running in development mode" do
|
it "returns a string when running in development mode" do
|
||||||
Rails.stubs(env: ActiveSupport::StringInquirer.new("development"))
|
Rails.stubs(env: ActiveSupport::StringInquirer.new("development"))
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when running in test mode" do
|
it "returns a string when running in test mode" do
|
||||||
Rails.stubs(env: ActiveSupport::StringInquirer.new("test"))
|
Rails.stubs(env: ActiveSupport::StringInquirer.new("test"))
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "host_names_check" do
|
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
|
it "returns nil when host_names is set" do
|
||||||
Discourse.stubs(:current_hostname).returns("something.com")
|
Discourse.stubs(:current_hostname).returns("something.com")
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when host_name is localhost" do
|
it "returns a string when host_name is localhost" do
|
||||||
Discourse.stubs(:current_hostname).returns("localhost")
|
Discourse.stubs(:current_hostname).returns("localhost")
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when host_name is production.localhost" do
|
it "returns a string when host_name is production.localhost" do
|
||||||
Discourse.stubs(:current_hostname).returns("production.localhost")
|
Discourse.stubs(:current_hostname).returns("production.localhost")
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "sidekiq_check" do
|
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
|
it "returns nil when sidekiq processed a job recently" do
|
||||||
Jobs.stubs(:last_job_performed_at).returns(1.minute.ago)
|
Jobs.stubs(:last_job_performed_at).returns(1.minute.ago)
|
||||||
Jobs.stubs(:queued).returns(0)
|
Jobs.stubs(:queued).returns(0)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns nil when last job processed was a long time ago, but no jobs are queued" do
|
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(:last_job_performed_at).returns(7.days.ago)
|
||||||
Jobs.stubs(:queued).returns(0)
|
Jobs.stubs(:queued).returns(0)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns nil when no jobs have ever been processed, but no jobs are queued" do
|
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(:last_job_performed_at).returns(nil)
|
||||||
Jobs.stubs(:queued).returns(0)
|
Jobs.stubs(:queued).returns(0)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when no jobs were processed recently and some jobs are queued" do
|
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(:last_job_performed_at).returns(20.minutes.ago)
|
||||||
Jobs.stubs(:queued).returns(1)
|
Jobs.stubs(:queued).returns(1)
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when no jobs have ever been processed, and some jobs are queued" do
|
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(:last_job_performed_at).returns(nil)
|
||||||
Jobs.stubs(:queued).returns(1)
|
Jobs.stubs(:queued).returns(1)
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "ram_check" do
|
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
|
it "returns nil when total ram is 1 GB" do
|
||||||
MemInfo.any_instance.stubs(:mem_total).returns(1_025_272)
|
MemInfo.any_instance.stubs(:mem_total).returns(1_025_272)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns nil when total ram cannot be determined" do
|
it "returns nil when total ram cannot be determined" do
|
||||||
MemInfo.any_instance.stubs(:mem_total).returns(nil)
|
MemInfo.any_instance.stubs(:mem_total).returns(nil)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when total ram is less than 1 GB" do
|
it "returns a string when total ram is less than 1 GB" do
|
||||||
MemInfo.any_instance.stubs(:mem_total).returns(512_636)
|
MemInfo.any_instance.stubs(:mem_total).returns(512_636)
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ RSpec.describe AdminDashboardData do
|
||||||
context "when disabled" do
|
context "when disabled" do
|
||||||
it "returns nil" do
|
it "returns nil" do
|
||||||
SiteSetting.set(enable_setting, false)
|
SiteSetting.set(enable_setting, false)
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -231,31 +231,32 @@ RSpec.describe AdminDashboardData do
|
||||||
it "returns nil when key and secret are set" do
|
it "returns nil when key and secret are set" do
|
||||||
SiteSetting.set(key, "12313213")
|
SiteSetting.set(key, "12313213")
|
||||||
SiteSetting.set(secret, "12312313123")
|
SiteSetting.set(secret, "12312313123")
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when key is not set" do
|
it "returns a string when key is not set" do
|
||||||
SiteSetting.set(key, "")
|
SiteSetting.set(key, "")
|
||||||
SiteSetting.set(secret, "12312313123")
|
SiteSetting.set(secret, "12312313123")
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when secret is not set" do
|
it "returns a string when secret is not set" do
|
||||||
SiteSetting.set(key, "123123")
|
SiteSetting.set(key, "123123")
|
||||||
SiteSetting.set(secret, "")
|
SiteSetting.set(secret, "")
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a string when key and secret are not set" do
|
it "returns a string when key and secret are not set" do
|
||||||
SiteSetting.set(key, "")
|
SiteSetting.set(key, "")
|
||||||
SiteSetting.set(secret, "")
|
SiteSetting.set(secret, "")
|
||||||
expect(subject).to_not be_nil
|
expect(check).to_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "facebook" do
|
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(:enable_setting) { :enable_facebook_logins }
|
||||||
let(:key) { :facebook_app_id }
|
let(:key) { :facebook_app_id }
|
||||||
let(:secret) { :facebook_app_secret }
|
let(:secret) { :facebook_app_secret }
|
||||||
|
@ -263,7 +264,8 @@ RSpec.describe AdminDashboardData do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "twitter" do
|
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(:enable_setting) { :enable_twitter_logins }
|
||||||
let(:key) { :twitter_consumer_key }
|
let(:key) { :twitter_consumer_key }
|
||||||
let(:secret) { :twitter_consumer_secret }
|
let(:secret) { :twitter_consumer_secret }
|
||||||
|
@ -271,7 +273,8 @@ RSpec.describe AdminDashboardData do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "github" do
|
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(:enable_setting) { :enable_github_logins }
|
||||||
let(:key) { :github_client_id }
|
let(:key) { :github_client_id }
|
||||||
let(:secret) { :github_client_secret }
|
let(:secret) { :github_client_secret }
|
||||||
|
@ -280,28 +283,28 @@ RSpec.describe AdminDashboardData do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "force_https_check" do
|
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
|
it "returns nil if force_https site setting enabled" do
|
||||||
SiteSetting.force_https = true
|
SiteSetting.force_https = true
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns nil if force_https site setting not enabled" do
|
it "returns nil if force_https site setting not enabled" do
|
||||||
SiteSetting.force_https = false
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "ignore force_https_check" do
|
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
|
it "returns nil" do
|
||||||
SiteSetting.force_https = true
|
SiteSetting.force_https = true
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
|
|
||||||
SiteSetting.force_https = false
|
SiteSetting.force_https = false
|
||||||
expect(subject).to be_nil
|
expect(check).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -556,13 +556,13 @@ RSpec.describe Category do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "new" do
|
describe "new" do
|
||||||
subject { Fabricate.build(:category, user: Fabricate(:user)) }
|
subject(:category) { Fabricate.build(:category, user: Fabricate(:user)) }
|
||||||
|
|
||||||
it "triggers a extensibility event" do
|
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[:event_name]).to eq(:category_created)
|
||||||
expect(event[:params].first).to eq(subject)
|
expect(event[:params].first).to eq(category)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -502,13 +502,13 @@ RSpec.describe Group do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "new" do
|
describe "new" do
|
||||||
subject { Fabricate.build(:group) }
|
subject(:group) { Fabricate.build(:group) }
|
||||||
|
|
||||||
it "triggers a extensibility event" do
|
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[:event_name]).to eq(:group_created)
|
||||||
expect(event[:params].first).to eq(subject)
|
expect(event[:params].first).to eq(group)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,13 @@ RSpec.describe Permalink do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "target_url" do
|
describe "target_url" do
|
||||||
|
subject(:target_url) { permalink.target_url }
|
||||||
|
|
||||||
let(:permalink) { Fabricate.build(:permalink) }
|
let(:permalink) { Fabricate.build(:permalink) }
|
||||||
let(:topic) { Fabricate(:topic) }
|
let(:topic) { Fabricate(:topic) }
|
||||||
let(:post) { Fabricate(:post, topic: topic) }
|
let(:post) { Fabricate(:post, topic: topic) }
|
||||||
let(:category) { Fabricate(:category) }
|
let(:category) { Fabricate(:category) }
|
||||||
let(:tag) { Fabricate(:tag) }
|
let(:tag) { Fabricate(:tag) }
|
||||||
subject(:target_url) { permalink.target_url }
|
|
||||||
|
|
||||||
it "returns a topic url when topic_id is set" do
|
it "returns a topic url when topic_id is set" do
|
||||||
permalink.topic_id = topic.id
|
permalink.topic_id = topic.id
|
||||||
|
|
|
@ -46,6 +46,8 @@ RSpec.describe Report do
|
||||||
|
|
||||||
describe "counting" do
|
describe "counting" do
|
||||||
describe "requests" do
|
describe "requests" do
|
||||||
|
subject(:json) { Report.find("http_total_reqs").as_json }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
freeze_time DateTime.parse("2017-03-01 12:00")
|
freeze_time DateTime.parse("2017-03-01 12:00")
|
||||||
|
|
||||||
|
@ -89,8 +91,6 @@ RSpec.describe Report do
|
||||||
ApplicationRequest.insert_all(application_requests)
|
ApplicationRequest.insert_all(application_requests)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:json) { Report.find("http_total_reqs").as_json }
|
|
||||||
|
|
||||||
it "counts the correct records" do
|
it "counts the correct records" do
|
||||||
expect(json[:data].size).to eq(31) # today and 30 full days
|
expect(json[:data].size).to eq(31) # today and 30 full days
|
||||||
expect(json[:data][0..-2].sum { |d| d[:y] }).to eq(300)
|
expect(json[:data][0..-2].sum { |d| d[:y] }).to eq(300)
|
||||||
|
|
|
@ -52,7 +52,7 @@ RSpec.describe ScreenedEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#should_block?" do
|
describe "#should_block?" do
|
||||||
subject { ScreenedEmail.should_block?(email) }
|
subject(:should_block) { ScreenedEmail.should_block?(email) }
|
||||||
|
|
||||||
it "automatically blocks via email canonicalization" do
|
it "automatically blocks via email canonicalization" do
|
||||||
SiteSetting.levenshtein_distance_spammer_emails = 0
|
SiteSetting.levenshtein_distance_spammer_emails = 0
|
||||||
|
@ -63,7 +63,7 @@ RSpec.describe ScreenedEmail do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false if a record with the email doesn't exist" do
|
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
|
end
|
||||||
|
|
||||||
it "returns true when there is a record with the email" do
|
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
|
shared_examples "when a ScreenedEmail record matches" do
|
||||||
it "updates statistics" do
|
it "updates statistics" do
|
||||||
freeze_time 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)
|
expect(screened_email.last_match_at).to eq_time(Time.zone.now)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,27 +25,28 @@ RSpec.describe ScreenedUrl do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "normalize" do
|
describe "normalize" do
|
||||||
let(:record) { described_class.new(@params) }
|
subject(:normalized) do
|
||||||
subject do
|
|
||||||
record.normalize
|
record.normalize
|
||||||
record
|
record
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:record) { described_class.new(@params) }
|
||||||
|
|
||||||
%w[http:// HTTP:// https:// HTTPS://].each do |prefix|
|
%w[http:// HTTP:// https:// HTTPS://].each do |prefix|
|
||||||
it "strips #{prefix}" do
|
it "strips #{prefix}" do
|
||||||
@params = valid_params.merge(url: url.gsub("http://", prefix))
|
@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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "strips trailing slash" do
|
it "strips trailing slash" do
|
||||||
@params = valid_params.merge(url: "silverbullet.in/")
|
@params = valid_params.merge(url: "silverbullet.in/")
|
||||||
expect(subject.url).to eq("silverbullet.in")
|
expect(normalized.url).to eq("silverbullet.in")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "strips trailing slashes" do
|
it "strips trailing slashes" do
|
||||||
@params = valid_params.merge(url: "silverbullet.in/buy///")
|
@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
|
end
|
||||||
|
|
||||||
it "downcases domains" do
|
it "downcases domains" do
|
||||||
|
|
|
@ -35,13 +35,13 @@ RSpec.describe Tag do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "new" do
|
describe "new" do
|
||||||
subject { Fabricate.build(:tag) }
|
subject(:tag) { Fabricate.build(:tag) }
|
||||||
|
|
||||||
it "triggers a extensibility event" do
|
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[:event_name]).to eq(:tag_created)
|
||||||
expect(event[:params].first).to eq(subject)
|
expect(event[:params].first).to eq(tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "prevents case-insensitive duplicates" do
|
it "prevents case-insensitive duplicates" do
|
||||||
|
@ -59,13 +59,13 @@ RSpec.describe Tag do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "destroy" do
|
describe "destroy" do
|
||||||
subject { Fabricate(:tag) }
|
subject(:tag) { Fabricate(:tag) }
|
||||||
|
|
||||||
it "triggers a extensibility event" do
|
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[:event_name]).to eq(:tag_destroyed)
|
||||||
expect(event[:params].first).to eq(subject)
|
expect(event[:params].first).to eq(tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes it from its tag group" do
|
it "removes it from its tag group" do
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe TrustLevel3Requirements do
|
RSpec.describe TrustLevel3Requirements do
|
||||||
fab!(:user) { Fabricate(:user) }
|
|
||||||
subject(:tl3_requirements) { described_class.new(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!(:topic1) { Fabricate(:topic) }
|
||||||
fab!(:topic2) { Fabricate(:topic) }
|
fab!(:topic2) { Fabricate(:topic) }
|
||||||
fab!(:topic3) { Fabricate(:topic) }
|
fab!(:topic3) { Fabricate(:topic) }
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
RSpec.describe UserField do
|
RSpec.describe UserField do
|
||||||
describe "doesn't validate presence of name if field type is 'confirm'" 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 }
|
it { is_expected.not_to validate_presence_of :name }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "validates presence of name for other field types" do
|
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 }
|
it { is_expected.to validate_presence_of :name }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -641,35 +641,33 @@ RSpec.describe User do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "new" do
|
describe "new" do
|
||||||
subject { Fabricate.build(:user) }
|
subject(:user) { Fabricate.build(:user) }
|
||||||
|
|
||||||
it { is_expected.to be_valid }
|
it { is_expected.to be_valid }
|
||||||
it { is_expected.not_to be_admin }
|
it { is_expected.not_to be_admin }
|
||||||
it { is_expected.not_to be_approved }
|
it { is_expected.not_to be_approved }
|
||||||
|
|
||||||
it "is properly initialized" do
|
it "is properly initialized" do
|
||||||
expect(subject.approved_at).to be_blank
|
expect(user.approved_at).to be_blank
|
||||||
expect(subject.approved_by_id).to be_blank
|
expect(user.approved_by_id).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
it "triggers an extensibility event" do
|
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[:event_name]).to eq(:user_created)
|
||||||
expect(event[:params].first).to eq(subject)
|
expect(event[:params].first).to eq(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with after_save" do
|
context "with after_save" do
|
||||||
before { subject.save! }
|
before { user.save! }
|
||||||
|
|
||||||
it "has correct settings" do
|
it "has correct settings" do
|
||||||
expect(subject.email_tokens).to be_present
|
expect(user.email_tokens).to be_present
|
||||||
expect(subject.user_stat).to be_present
|
expect(user.user_stat).to be_present
|
||||||
expect(subject.user_profile).to be_present
|
expect(user.user_profile).to be_present
|
||||||
expect(subject.user_option.email_messages_level).to eq(
|
expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:always])
|
||||||
UserOption.email_level_types[:always],
|
expect(user.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away])
|
||||||
)
|
|
||||||
expect(subject.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -756,41 +754,37 @@ RSpec.describe User do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "staff and regular users" do
|
describe "staff and regular users" do
|
||||||
let(:user) { Fabricate.build(:user) }
|
subject(:user) { Fabricate.build(:user) }
|
||||||
|
|
||||||
describe "#staff?" do
|
describe "#staff?" do
|
||||||
subject { user.staff? }
|
it { is_expected.not_to be_staff }
|
||||||
|
|
||||||
it { is_expected.to eq(false) }
|
|
||||||
|
|
||||||
context "for a moderator user" do
|
context "for a moderator user" do
|
||||||
before { user.moderator = true }
|
before { user.moderator = true }
|
||||||
|
|
||||||
it { is_expected.to eq(true) }
|
it { is_expected.to be_staff }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "for an admin user" do
|
context "for an admin user" do
|
||||||
before { user.admin = true }
|
before { user.admin = true }
|
||||||
|
|
||||||
it { is_expected.to eq(true) }
|
it { is_expected.to be_staff }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#regular?" do
|
describe "#regular?" do
|
||||||
subject { user.regular? }
|
it { is_expected.to be_regular }
|
||||||
|
|
||||||
it { is_expected.to eq(true) }
|
|
||||||
|
|
||||||
context "for a moderator user" do
|
context "for a moderator user" do
|
||||||
before { user.moderator = true }
|
before { user.moderator = true }
|
||||||
|
|
||||||
it { is_expected.to eq(false) }
|
it { is_expected.not_to be_regular }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "for an admin user" do
|
context "for an admin user" do
|
||||||
before { user.admin = true }
|
before { user.admin = true }
|
||||||
|
|
||||||
it { is_expected.to eq(false) }
|
it { is_expected.not_to be_regular }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3251,7 +3245,7 @@ RSpec.describe User do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false if no whispers groups exist" do
|
it "returns false if no whispers groups exist" do
|
||||||
expect(subject.whisperer?).to eq(false)
|
expect(user.whisperer?).to eq(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue