DEV: Use run_successfully matcher in service specs

This commit is contained in:
Loïc Guitaut 2024-08-28 14:54:10 +02:00 committed by Loïc Guitaut
parent 0977f9fb47
commit d26d45540e
40 changed files with 189 additions and 181 deletions

View File

@ -4,14 +4,10 @@ class UpdateSiteSetting
include Service::Base include Service::Base
policy :current_user_is_admin policy :current_user_is_admin
contract contract
step :convert_name_to_sym step :convert_name_to_sym
policy :setting_is_visible policy :setting_is_visible
policy :setting_is_configurable policy :setting_is_configurable
step :cleanup_value step :cleanup_value
step :save step :save

View File

@ -28,6 +28,8 @@ RSpec.describe Chat::AddUsersToChannel do
context "when all steps pass" do context "when all steps pass" do
before { channel.add(current_user) } before { channel.add(current_user) }
it { is_expected.to run_successfully }
it "fetches users to add" do it "fetches users to add" do
expect(result.target_users.map(&:username)).to contain_exactly(*users.map(&:username)) expect(result.target_users.map(&:username)).to contain_exactly(*users.map(&:username))
end end

View File

@ -86,6 +86,8 @@ describe Chat::AutoJoinChannelBatch do
context "when more than one membership is created" do context "when more than one membership is created" do
let(:user_ids) { Fabricate.times(2, :user).map(&:id) } let(:user_ids) { Fabricate.times(2, :user).map(&:id) }
it { is_expected.to run_successfully }
it "does not recalculate user count" do it "does not recalculate user count" do
::Chat::ChannelMembershipManager.any_instance.expects(:recalculate_user_count).never ::Chat::ChannelMembershipManager.any_instance.expects(:recalculate_user_count).never
result result
@ -101,6 +103,8 @@ describe Chat::AutoJoinChannelBatch do
end end
context "when only one membership is created" do context "when only one membership is created" do
it { is_expected.to run_successfully }
it "recalculates user count" do it "recalculates user count" do
::Chat::ChannelMembershipManager.any_instance.expects(:recalculate_user_count).once ::Chat::ChannelMembershipManager.any_instance.expects(:recalculate_user_count).once
result result

View File

@ -60,6 +60,8 @@ RSpec.describe Chat::CreateCategoryChannel do
end end
context "when all steps pass" do context "when all steps pass" do
it { is_expected.to run_successfully }
it "creates the channel" do it "creates the channel" do
expect { result }.to change { Chat::Channel.count }.by(1) expect { result }.to change { Chat::Channel.count }.by(1)
expect(result.channel).to have_attributes( expect(result.channel).to have_attributes(

View File

@ -17,6 +17,7 @@ RSpec.describe Chat::CreateDirectMessageChannel do
expect(contract.target_usernames).to eq(%w[lechuck elaine]) expect(contract.target_usernames).to eq(%w[lechuck elaine])
end end
end end
context "when the target_groups argument is a string" do context "when the target_groups argument is a string" do
let(:params) { { target_groups: "admins,moderators" } } let(:params) { { target_groups: "admins,moderators" } }
@ -42,6 +43,8 @@ RSpec.describe Chat::CreateDirectMessageChannel do
let(:params) { { guardian: guardian, target_usernames: target_usernames, name: name } } let(:params) { { guardian: guardian, target_usernames: target_usernames, name: name } }
context "when all steps pass" do context "when all steps pass" do
it { is_expected.to run_successfully }
it "sets the service result as successful" do it "sets the service result as successful" do
expect(result).to be_a_success expect(result).to be_a_success
end end

View File

@ -237,7 +237,7 @@ RSpec.describe Chat::CreateMessage do
context "when user is a bot" do context "when user is a bot" do
fab!(:user) { Discourse.system_user } fab!(:user) { Discourse.system_user }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when membership is enforced" do context "when membership is enforced" do
@ -248,7 +248,7 @@ RSpec.describe Chat::CreateMessage do
params[:enforce_membership] = true params[:enforce_membership] = true
end end
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when user can join channel" do context "when user can join channel" do
@ -291,6 +291,8 @@ RSpec.describe Chat::CreateMessage do
it_behaves_like "creating a new message" it_behaves_like "creating a new message"
it_behaves_like "a message in a thread" it_behaves_like "a message in a thread"
it { is_expected.to run_successfully }
it "assigns the thread to the new message" do it "assigns the thread to the new message" do
expect(message).to have_attributes( expect(message).to have_attributes(
in_reply_to: an_object_having_attributes(thread: thread), in_reply_to: an_object_having_attributes(thread: thread),
@ -312,6 +314,8 @@ RSpec.describe Chat::CreateMessage do
let(:original_user) { reply_to.user } let(:original_user) { reply_to.user }
end end
it { is_expected.to run_successfully }
it "creates a new thread" do it "creates a new thread" do
expect { result }.to change { Chat::Thread.count }.by(1) expect { result }.to change { Chat::Thread.count }.by(1)
expect(message).to have_attributes( expect(message).to have_attributes(
@ -389,6 +393,8 @@ RSpec.describe Chat::CreateMessage do
it_behaves_like "creating a new message" it_behaves_like "creating a new message"
it_behaves_like "a message in a thread" it_behaves_like "a message in a thread"
it { is_expected.to run_successfully }
it "does not publish the thread" do it "does not publish the thread" do
Chat::Publisher.expects(:publish_thread_created!).never Chat::Publisher.expects(:publish_thread_created!).never
result result
@ -400,6 +406,8 @@ RSpec.describe Chat::CreateMessage do
it_behaves_like "creating a new message" it_behaves_like "creating a new message"
it_behaves_like "a message in a thread" it_behaves_like "a message in a thread"
it { is_expected.to run_successfully }
it "does not publish the thread" do it "does not publish the thread" do
Chat::Publisher.expects(:publish_thread_created!).never Chat::Publisher.expects(:publish_thread_created!).never
result result
@ -418,6 +426,8 @@ RSpec.describe Chat::CreateMessage do
context "when message is valid" do context "when message is valid" do
it_behaves_like "creating a new message" it_behaves_like "creating a new message"
it { is_expected.to run_successfully }
it "updates membership last_read_message attribute" do it "updates membership last_read_message attribute" do
expect { result }.to change { membership.reload.last_read_message } expect { result }.to change { membership.reload.last_read_message }
end end

View File

@ -25,9 +25,7 @@ RSpec.describe Chat::CreateThread do
end end
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "creates a thread" do it "creates a thread" do
result result

View File

@ -44,6 +44,8 @@ RSpec.describe Chat::FlagMessage do
context "when all steps pass" do context "when all steps pass" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it { is_expected.to run_successfully }
it "flags the message" do it "flags the message" do
expect { result }.to change { Reviewable.count }.by(1) expect { result }.to change { Reviewable.count }.by(1)

View File

@ -29,9 +29,7 @@ RSpec.describe Chat::InviteUsersToChannel do
end end
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to run_service_successfully
end
it "creates the notifications for allowed users" do it "creates the notifications for allowed users" do
result result

View File

@ -28,6 +28,8 @@ RSpec.describe Chat::LeaveChannel do
Chat::Channel.ensure_consistency! Chat::Channel.ensure_consistency!
end end
it { is_expected.to run_successfully }
it "unfollows the channel" do it "unfollows the channel" do
membership = channel_1.membership_for(current_user) membership = channel_1.membership_for(current_user)
@ -40,6 +42,8 @@ RSpec.describe Chat::LeaveChannel do
end end
context "with no existing membership" do context "with no existing membership" do
it { is_expected.to run_successfully }
it "does nothing" do it "does nothing" do
expect { result }.to_not change { Chat::UserChatChannelMembership } expect { result }.to_not change { Chat::UserChatChannelMembership }
end end
@ -54,6 +58,8 @@ RSpec.describe Chat::LeaveChannel do
before { Chat::Channel.ensure_consistency! } before { Chat::Channel.ensure_consistency! }
it { is_expected.to run_successfully }
it "leaves the channel" do it "leaves the channel" do
membership = channel_1.membership_for(current_user) membership = channel_1.membership_for(current_user)
@ -71,6 +77,8 @@ RSpec.describe Chat::LeaveChannel do
end end
context "with no existing membership" do context "with no existing membership" do
it { is_expected.to run_successfully }
it "does nothing" do it "does nothing" do
expect { result }.to_not change { Chat::UserChatChannelMembership } expect { result }.to_not change { Chat::UserChatChannelMembership }
end end
@ -85,6 +93,8 @@ RSpec.describe Chat::LeaveChannel do
before { Chat::Channel.ensure_consistency! } before { Chat::Channel.ensure_consistency! }
it { is_expected.to run_successfully }
it "unfollows the channel" do it "unfollows the channel" do
membership = channel_1.membership_for(current_user) membership = channel_1.membership_for(current_user)
@ -100,6 +110,8 @@ RSpec.describe Chat::LeaveChannel do
end end
context "with no existing membership" do context "with no existing membership" do
it { is_expected.to run_successfully }
it "does nothing" do it "does nothing" do
expect { result }.to_not change { Chat::UserChatChannelMembership } expect { result }.to_not change { Chat::UserChatChannelMembership }
end end

View File

@ -29,6 +29,8 @@ RSpec.describe Chat::ListChannelMessages do
end end
context "when channel exists" do context "when channel exists" do
it { is_expected.to run_successfully }
it "finds the correct channel" do it "finds the correct channel" do
expect(result.channel).to eq(channel) expect(result.channel).to eq(channel)
end end
@ -37,6 +39,8 @@ RSpec.describe Chat::ListChannelMessages do
context "when fetch_eventual_membership" do context "when fetch_eventual_membership" do
context "when user has membership" do context "when user has membership" do
it { is_expected.to run_successfully }
it "finds the correct membership" do it "finds the correct membership" do
expect(result.membership).to eq(channel.membership_for(user)) expect(result.membership).to eq(channel.membership_for(user))
end end
@ -45,6 +49,8 @@ RSpec.describe Chat::ListChannelMessages do
context "when user has no membership" do context "when user has no membership" do
before { channel.membership_for(user).destroy! } before { channel.membership_for(user).destroy! }
it { is_expected.to run_successfully }
it "finds no membership" do it "finds no membership" do
expect(result.membership).to be_blank expect(result.membership).to be_blank
end end
@ -86,7 +92,7 @@ RSpec.describe Chat::ListChannelMessages do
context "when target_message_exists" do context "when target_message_exists" do
context "when no target_message_id is given" do context "when no target_message_id is given" do
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when target message is not found" do context "when target message is not found" do
@ -99,7 +105,7 @@ RSpec.describe Chat::ListChannelMessages do
fab!(:target_message) { Fabricate(:chat_message, chat_channel: channel) } fab!(:target_message) { Fabricate(:chat_message, chat_channel: channel) }
let(:optional_params) { { target_message_id: target_message.id } } let(:optional_params) { { target_message_id: target_message.id } }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when target message is trashed" do context "when target message is trashed" do
@ -117,13 +123,13 @@ RSpec.describe Chat::ListChannelMessages do
context "when user is the message creator" do context "when user is the message creator" do
fab!(:target_message) { Fabricate(:chat_message, chat_channel: channel, user: user) } fab!(:target_message) { Fabricate(:chat_message, chat_channel: channel, user: user) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when user is admin" do context "when user is admin" do
fab!(:user) { Fabricate(:admin) } fab!(:user) { Fabricate(:admin) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end
@ -132,6 +138,8 @@ RSpec.describe Chat::ListChannelMessages do
context "with no params" do context "with no params" do
fab!(:messages) { Fabricate.times(20, :chat_message, chat_channel: channel) } fab!(:messages) { Fabricate.times(20, :chat_message, chat_channel: channel) }
it { is_expected.to be_a_success }
it "returns messages" do it "returns messages" do
expect(result.can_load_more_past).to eq(false) expect(result.can_load_more_past).to eq(false)
expect(result.can_load_more_future).to eq(false) expect(result.can_load_more_future).to eq(false)
@ -149,6 +157,8 @@ RSpec.describe Chat::ListChannelMessages do
let(:optional_params) { { target_date: 2.days.ago } } let(:optional_params) { { target_date: 2.days.ago } }
it { is_expected.to be_a_success }
it "includes past and future messages" do it "includes past and future messages" do
expect(result.messages).to eq([past_message, future_message]) expect(result.messages).to eq([past_message, future_message])
end end
@ -164,6 +174,8 @@ RSpec.describe Chat::ListChannelMessages do
thread_1.add(user) thread_1.add(user)
end end
it { is_expected.to be_a_success }
it "returns tracking" do it "returns tracking" do
Fabricate(:chat_message, chat_channel: channel, thread: thread_1) Fabricate(:chat_message, chat_channel: channel, thread: thread_1)
@ -175,6 +187,8 @@ RSpec.describe Chat::ListChannelMessages do
context "when thread is forced" do context "when thread is forced" do
before { thread_1.update!(force: true) } before { thread_1.update!(force: true) }
it { is_expected.to be_a_success }
it "returns tracking" do it "returns tracking" do
Fabricate(:chat_message, chat_channel: channel, thread: thread_1) Fabricate(:chat_message, chat_channel: channel, thread: thread_1)
@ -193,6 +207,8 @@ RSpec.describe Chat::ListChannelMessages do
thread_1.add(user) thread_1.add(user)
end end
it { is_expected.to be_a_success }
it "returns tracking" do it "returns tracking" do
Fabricate(:chat_message, chat_channel: channel, thread: thread_1) Fabricate(:chat_message, chat_channel: channel, thread: thread_1)

View File

@ -29,6 +29,8 @@ RSpec.describe Chat::ListChannelThreadMessages do
end end
context "when thread exists" do context "when thread exists" do
it { is_expected.to run_successfully }
it "finds the correct channel" do it "finds the correct channel" do
expect(result.thread).to eq(thread) expect(result.thread).to eq(thread)
end end
@ -44,7 +46,7 @@ RSpec.describe Chat::ListChannelThreadMessages do
context "with system user" do context "with system user" do
fab!(:user) { Discourse.system_user } fab!(:user) { Discourse.system_user }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end
@ -80,7 +82,7 @@ RSpec.describe Chat::ListChannelThreadMessages do
context "when target_message_exists" do context "when target_message_exists" do
context "when no target_message_id is given" do context "when no target_message_id is given" do
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when target message is not found" do context "when target message is not found" do
@ -95,7 +97,7 @@ RSpec.describe Chat::ListChannelThreadMessages do
end end
let(:optional_params) { { target_message_id: target_message.id } } let(:optional_params) { { target_message_id: target_message.id } }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when target message is trashed" do context "when target message is trashed" do
@ -115,13 +117,13 @@ RSpec.describe Chat::ListChannelThreadMessages do
Fabricate(:chat_message, chat_channel: thread.channel, thread: thread, user: user) Fabricate(:chat_message, chat_channel: thread.channel, thread: thread, user: user)
end end
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when user is admin" do context "when user is admin" do
fab!(:user) { Fabricate(:admin) } fab!(:user) { Fabricate(:admin) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end

View File

@ -11,6 +11,8 @@ RSpec.describe Chat::ListUserChannels do
before { channel_1.add(current_user) } before { channel_1.add(current_user) }
it { is_expected.to run_successfully }
it "returns the structured data" do it "returns the structured data" do
expect(result.structured[:post_allowed_category_ids]).to eq(nil) expect(result.structured[:post_allowed_category_ids]).to eq(nil)
expect(result.structured[:unread_thread_overview]).to eq({}) expect(result.structured[:unread_thread_overview]).to eq({})

View File

@ -125,7 +125,7 @@ RSpec.describe ::Chat::LookupChannelThreads do
describe "model - threads" do describe "model - threads" do
before { channel_1.add(current_user) } before { channel_1.add(current_user) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
it "orders threads by the last reply created_at timestamp" do it "orders threads by the last reply created_at timestamp" do
[ [

View File

@ -19,9 +19,7 @@ RSpec.describe Chat::LookupThread do
let(:params) { { guardian: guardian, thread_id: thread.id, channel_id: thread.channel_id } } let(:params) { { guardian: guardian, thread_id: thread.id, channel_id: thread.channel_id } }
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "fetches the thread" do it "fetches the thread" do
expect(result.thread).to eq(thread) expect(result.thread).to eq(thread)
@ -60,7 +58,7 @@ RSpec.describe Chat::LookupThread do
context "when thread is forced" do context "when thread is forced" do
before { thread.update!(force: true) } before { thread.update!(force: true) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end

View File

@ -5,6 +5,7 @@ RSpec.describe ::Chat::LookupUserThreads do
fab!(:current_user) { Fabricate(:user) } fab!(:current_user) { Fabricate(:user) }
fab!(:channel_1) { Fabricate(:chat_channel, threading_enabled: true) } fab!(:channel_1) { Fabricate(:chat_channel, threading_enabled: true) }
fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1, with_replies: 1) }
let(:guardian) { Guardian.new(current_user) } let(:guardian) { Guardian.new(current_user) }
let(:channel_id) { channel_1.id } let(:channel_id) { channel_1.id }
@ -12,15 +13,15 @@ RSpec.describe ::Chat::LookupUserThreads do
let(:offset) { 0 } let(:offset) { 0 }
let(:params) { { guardian: guardian, limit: limit, offset: offset } } let(:params) { { guardian: guardian, limit: limit, offset: offset } }
before { channel_1.add(current_user) } before do
channel_1.add(current_user)
thread_1.add(current_user)
end
context "when all steps pass" do context "when all steps pass" do
it "returns threads" do it { is_expected.to run_successfully }
thread_1 =
Fabricate(:chat_thread, channel: channel_1, with_replies: 1).tap do |thread|
thread.add(current_user)
end
it "returns threads" do
expect(result.threads).to eq([thread_1]) expect(result.threads).to eq([thread_1])
end end
@ -65,6 +66,7 @@ RSpec.describe ::Chat::LookupUserThreads do
it "can offset" do it "can offset" do
params[:offset] = 1 params[:offset] = 1
Chat::Thread.destroy_all
threads = threads =
Fabricate Fabricate
.times(2, :chat_thread, channel: channel_1, with_replies: 1) .times(2, :chat_thread, channel: channel_1, with_replies: 1)
@ -77,21 +79,16 @@ RSpec.describe ::Chat::LookupUserThreads do
it "has a min offset" do it "has a min offset" do
params[:offset] = -99 params[:offset] = -99
threads = Chat::Thread.destroy_all
Fabricate Fabricate
.times(2, :chat_thread, channel: channel_1, with_replies: 1) .times(2, :chat_thread, channel: channel_1, with_replies: 1)
.each { |thread| thread.add(current_user) } .each { |thread| thread.add(current_user) }
# 0 because we sort by last_message.created_at, so the last created thread is the first one # 0 because we sort by last_message.created_at, so the last created thread is the first one
expect(result.threads.length).to eq(2) expect(result.threads.length).to eq(2)
end end
it "fetches tracking" do it "fetches tracking" do
thread_1 =
Fabricate(:chat_thread, channel: channel_1, with_replies: 1).tap do |thread|
thread.add(current_user)
end
expect(result.tracking).to eq( expect(result.tracking).to eq(
::Chat::TrackingStateReportQuery.call( ::Chat::TrackingStateReportQuery.call(
guardian: current_user.guardian, guardian: current_user.guardian,
@ -102,58 +99,39 @@ RSpec.describe ::Chat::LookupUserThreads do
end end
it "fetches memberships" do it "fetches memberships" do
thread_1 =
Fabricate(:chat_thread, channel: channel_1, with_replies: 1).tap do |thread|
thread.add(current_user)
end
expect(result.memberships).to eq([thread_1.membership_for(current_user)]) expect(result.memberships).to eq([thread_1.membership_for(current_user)])
end end
it "fetches participants" do it "fetches participants" do
thread_1 =
Fabricate(:chat_thread, channel: channel_1, with_replies: 1).tap do |thread|
thread.add(current_user)
end
expect(result.participants).to eq( expect(result.participants).to eq(
::Chat::ThreadParticipantQuery.call(thread_ids: [thread_1.id]), ::Chat::ThreadParticipantQuery.call(thread_ids: [thread_1.id]),
) )
end end
it "builds a load_more_url" do it "builds a load_more_url" do
Fabricate(:chat_thread, channel: channel_1, with_replies: 1).tap do |thread|
thread.add(current_user)
end
expect(result.load_more_url).to eq("/chat/api/me/threads?limit=10&offset=10") expect(result.load_more_url).to eq("/chat/api/me/threads?limit=10&offset=10")
end end
end end
it "doesn't return threads with no replies" do it "doesn't return threads with no replies" do
thread_1 = Fabricate(:chat_thread, channel: channel_1) Fabricate(:chat_thread, channel: channel_1).tap { _1.add(current_user) }
thread_1.add(current_user)
expect(result.threads).to eq([]) expect(result.threads).to eq([thread_1])
end end
it "doesn't return threads with no membership" do it "doesn't return threads with no membership" do
thread_1 = Fabricate(:chat_thread, channel: channel_1, with_replies: 1) Fabricate(:chat_thread, channel: channel_1, with_replies: 1)
expect(result.threads).to eq([]) expect(result.threads).to eq([thread_1])
end end
it "doesn't return threads when the channel has not threading enabled" do it "doesn't return threads when the channel has not threading enabled" do
channel_1.update!(threading_enabled: false) channel_1.update!(threading_enabled: false)
thread_1 = Fabricate(:chat_thread, channel: channel_1, with_replies: 1)
thread_1.add(current_user)
expect(result.threads).to eq([]) expect(result.threads).to eq([])
end end
it "doesn't return muted threads" do it "doesn't return muted threads" do
thread_1 = Fabricate(:chat_thread, channel: channel_1, with_replies: 1)
thread_1.add(current_user)
thread_1.membership_for(current_user).update!( thread_1.membership_for(current_user).update!(
notification_level: ::Chat::UserChatThreadMembership.notification_levels[:muted], notification_level: ::Chat::UserChatThreadMembership.notification_levels[:muted],
) )
@ -163,16 +141,11 @@ RSpec.describe ::Chat::LookupUserThreads do
it "doesn't return threads when the channel it not open" do it "doesn't return threads when the channel it not open" do
channel_1.update!(status: Chat::Channel.statuses[:closed]) channel_1.update!(status: Chat::Channel.statuses[:closed])
thread_1 = Fabricate(:chat_thread, channel: channel_1, with_replies: 1)
thread_1.add(current_user)
expect(result.threads).to eq([]) expect(result.threads).to eq([])
end end
it "returns threads from muted channels" do it "returns threads from muted channels" do
thread_1 = Fabricate(:chat_thread, channel: channel_1, with_replies: 1)
thread_1.add(current_user)
channel_1.membership_for(current_user).update!(muted: true) channel_1.membership_for(current_user).update!(muted: true)
expect(result.threads).to eq([thread_1]) expect(result.threads).to eq([thread_1])

View File

@ -56,12 +56,10 @@ RSpec.describe Chat::MarkAllUserChannelsRead do
context "when the user has no memberships" do context "when the user has no memberships" do
let(:guardian) { Guardian.new(Fabricate(:user)) } let(:guardian) { Guardian.new(Fabricate(:user)) }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "returns the updated_memberships in context" do it "returns the updated_memberships in context" do
expect(result.updated_memberships).to eq([]) expect(result.updated_memberships).to be_empty
end end
end end
@ -96,9 +94,7 @@ RSpec.describe Chat::MarkAllUserChannelsRead do
) )
end end
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "updates the last_read_message_ids" do it "updates the last_read_message_ids" do
result result

View File

@ -23,9 +23,7 @@ RSpec.describe Chat::MarkThreadTitlePromptSeen do
before { thread.update!(last_message: last_reply) } before { thread.update!(last_message: last_reply) }
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
context "when the user is a member of the thread" do context "when the user is a member of the thread" do
fab!(:membership) { thread.add(current_user) } fab!(:membership) { thread.add(current_user) }

View File

@ -41,9 +41,7 @@ RSpec.describe Chat::RestoreMessage do
end end
context "when the user has permission to restore" do context "when the user has permission to restore" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "restores the message" do it "restores the message" do
result result

View File

@ -43,9 +43,7 @@ RSpec.describe Chat::SearchChatable do
end end
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "cleans the term" do it "cleans the term" do
params[:term] = "#bob" params[:term] = "#bob"

View File

@ -19,7 +19,7 @@ RSpec.describe Chat::StopMessageStreaming do
context "with valid params" do context "with valid params" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
it "updates the streaming attribute to false" do it "updates the streaming attribute to false" do
expect { result }.to change { message_1.reload.streaming }.to eq(false) expect { result }.to change { message_1.reload.streaming }.to eq(false)
@ -42,7 +42,7 @@ RSpec.describe Chat::StopMessageStreaming do
context "when the user is a bot" do context "when the user is a bot" do
fab!(:current_user) { Discourse.system_user } fab!(:current_user) { Discourse.system_user }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
@ -69,7 +69,7 @@ RSpec.describe Chat::StopMessageStreaming do
before { params[:message_id] = reply.id } before { params[:message_id] = reply.id }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when the OM is not from current user" do context "when the OM is not from current user" do
@ -89,13 +89,13 @@ RSpec.describe Chat::StopMessageStreaming do
context "when current user is a bot" do context "when current user is a bot" do
fab!(:current_user) { Discourse.system_user } fab!(:current_user) { Discourse.system_user }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when current user is an admin" do context "when current user is an admin" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end
@ -112,13 +112,13 @@ RSpec.describe Chat::StopMessageStreaming do
context "when current user is a bot" do context "when current user is a bot" do
fab!(:current_user) { Discourse.system_user } fab!(:current_user) { Discourse.system_user }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
context "when current user is an admin" do context "when current user is an admin" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it { is_expected.to be_a_success } it { is_expected.to run_successfully }
end end
end end
end end

View File

@ -25,9 +25,7 @@ RSpec.describe(Chat::TrashChannel) do
context "when user is allowed to perform the action" do context "when user is allowed to perform the action" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "trashes the channel" do it "trashes the channel" do
expect(result[:channel]).to be_trashed expect(result[:channel]).to be_trashed

View File

@ -34,9 +34,7 @@ RSpec.describe Chat::TrashMessage do
end end
context "when the user has permission to delete" do context "when the user has permission to delete" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "trashes the message" do it "trashes the message" do
result result

View File

@ -40,9 +40,7 @@ RSpec.describe Chat::TrashMessages do
end end
context "when the user has permission to delete" do context "when the user has permission to delete" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "trashes the messages" do it "trashes the messages" do
result result

View File

@ -24,6 +24,8 @@ RSpec.describe Chat::UnfollowChannel do
context "with existing membership" do context "with existing membership" do
before { channel_1.add(current_user) } before { channel_1.add(current_user) }
it { is_expected.to run_successfully }
it "unfollows the channel" do it "unfollows the channel" do
membership = channel_1.membership_for(current_user) membership = channel_1.membership_for(current_user)
@ -32,6 +34,8 @@ RSpec.describe Chat::UnfollowChannel do
end end
context "with no existing membership" do context "with no existing membership" do
it { is_expected.to run_successfully }
it "does nothing" do it "does nothing" do
expect { result }.to_not change { Chat::UserChatChannelMembership } expect { result }.to_not change { Chat::UserChatChannelMembership }
end end

View File

@ -31,9 +31,7 @@ RSpec.describe Chat::UpdateChannel do
.first .first
end end
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "updates the channel accordingly" do it "updates the channel accordingly" do
result result

View File

@ -42,9 +42,7 @@ RSpec.describe(Chat::UpdateChannelStatus) do
context "when status is allowed" do context "when status is allowed" do
let(:status) { "closed" } let(:status) { "closed" }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "changes the status" do it "changes the status" do
result result

View File

@ -879,9 +879,7 @@ RSpec.describe Chat::UpdateMessage do
end end
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to run_service_successfully
end
it "updates the message" do it "updates the message" do
expect(result.message.message).to eq("new") expect(result.message.message).to eq("new")

View File

@ -29,9 +29,7 @@ RSpec.describe Chat::UpdateThreadNotificationSettings do
before { thread.update!(last_message: last_reply) } before { thread.update!(last_message: last_reply) }
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
context "when the user is a member of the thread" do context "when the user is a member of the thread" do
fab!(:membership) { thread.add(current_user) } fab!(:membership) { thread.add(current_user) }

View File

@ -19,9 +19,7 @@ RSpec.describe Chat::UpdateThread do
let(:params) { { guardian: guardian, thread_id: thread.id, title: title } } let(:params) { { guardian: guardian, thread_id: thread.id, title: title } }
context "when all steps pass" do context "when all steps pass" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "updates the title of the thread" do it "updates the title of the thread" do
result result

View File

@ -91,9 +91,7 @@ RSpec.describe Chat::UpdateUserChannelLastRead do
) )
end end
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "updates the last_read message id" do it "updates the last_read message id" do
expect { result }.to change { membership.reload.last_read_message_id }.to(message_1.id) expect { result }.to change { membership.reload.last_read_message_id }.to(message_1.id)

View File

@ -55,9 +55,7 @@ RSpec.describe Chat::UpdateUserThreadLastRead do
end end
context "when params are valid" do context "when params are valid" do
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "publishes new last read to clients" do it "publishes new last read to clients" do
messages = MessageBus.track_publish { result } messages = MessageBus.track_publish { result }

View File

@ -29,6 +29,8 @@ RSpec.describe Chat::UpsertDraft do
end end
context "when all steps pass" do context "when all steps pass" do
it { is_expected.to run_successfully }
it "creates draft if data provided and not existing draft" do it "creates draft if data provided and not existing draft" do
params[:data] = MultiJson.dump(message: "a") params[:data] = MultiJson.dump(message: "a")

View File

@ -69,11 +69,10 @@ RSpec.describe(Flags::CreateFlag) do
OpenStruct.new(enabled?: true), OpenStruct.new(enabled?: true),
) )
end end
after { Flag.destroy_by(name: "custom flag name") } after { Flag.destroy_by(name: "custom flag name") }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "creates the flag" do it "creates the flag" do
result result

View File

@ -1,10 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe(Flags::DestroyFlag) do RSpec.describe(Flags::DestroyFlag) do
fab!(:flag)
subject(:result) { described_class.call(id: flag.id, guardian: current_user.guardian) } subject(:result) { described_class.call(id: flag.id, guardian: current_user.guardian) }
fab!(:flag)
after { flag.destroy } after { flag.destroy }
context "when user is not allowed to perform the action" do context "when user is not allowed to perform the action" do
@ -16,6 +16,8 @@ RSpec.describe(Flags::DestroyFlag) do
context "when user is allowed to perform the action" do context "when user is allowed to perform the action" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it { is_expected.to run_successfully }
it "sets the service result as successful" do it "sets the service result as successful" do
expect(result).to be_a_success expect(result).to be_a_success
end end

View File

@ -35,9 +35,7 @@ RSpec.describe(Flags::ReorderFlag) do
described_class.call(flag_id: flag.id, guardian: current_user.guardian, direction: "down") described_class.call(flag_id: flag.id, guardian: current_user.guardian, direction: "down")
end end
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "moves the flag" do it "moves the flag" do
expect(Flag.order(:position).map(&:name)).to eq( expect(Flag.order(:position).map(&:name)).to eq(

View File

@ -16,9 +16,7 @@ RSpec.describe(Flags::ToggleFlag) do
after { flag.reload.update!(enabled: true) } after { flag.reload.update!(enabled: true) }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "toggles the flag" do it "toggles the flag" do
expect(result[:flag].enabled).to be false expect(result[:flag].enabled).to be false

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe(Flags::UpdateFlag) do RSpec.describe(Flags::UpdateFlag) do
fab!(:flag)
subject(:result) do subject(:result) do
described_class.call( described_class.call(
id: flag.id, id: flag.id,
@ -15,6 +13,8 @@ RSpec.describe(Flags::UpdateFlag) do
) )
end end
fab!(:flag)
after { flag.destroy } after { flag.destroy }
let(:name) { "edited custom flag name" } let(:name) { "edited custom flag name" }
@ -67,9 +67,7 @@ RSpec.describe(Flags::UpdateFlag) do
context "when user is allowed to perform the action" do context "when user is allowed to perform the action" do
fab!(:current_user) { Fabricate(:admin) } fab!(:current_user) { Fabricate(:admin) }
it "sets the service result as successful" do it { is_expected.to run_successfully }
expect(result).to be_a_success
end
it "updates the flag" do it "updates the flag" do
result result

View File

@ -1,71 +1,74 @@
# frozen_string_literal: true # frozen_string_literal: true
describe(UpdateSiteSetting) do RSpec.describe UpdateSiteSetting do
fab!(:admin) subject(:result) { described_class.call(params) }
def call_service(name, value, user: admin, allow_changing_hidden: false) describe described_class::Contract, type: :model do
described_class.call( subject(:contract) { described_class.new }
setting_name: name,
new_value: value, it { is_expected.to validate_presence_of :setting_name }
guardian: user.guardian,
allow_changing_hidden:,
)
end end
context "when setting_name is blank" do fab!(:admin)
it "fails the service contract" do let(:params) { { setting_name:, new_value:, guardian:, allow_changing_hidden: } }
expect(call_service(nil, "blah whatever")).to fail_a_contract let(:setting_name) { :title }
let(:new_value) { "blah whatever" }
let(:guardian) { admin.guardian }
let(:allow_changing_hidden) { false }
expect(call_service(:"", "blah whatever")).to fail_a_contract context "when setting_name is blank" do
end let(:setting_name) { nil }
it { is_expected.to fail_a_contract }
end end
context "when a non-admin user tries to change a setting" do context "when a non-admin user tries to change a setting" do
it "fails the current_user_is_admin policy" do let(:guardian) { Guardian.new }
expect(call_service(:title, "some new title", user: Fabricate(:moderator))).to fail_a_policy(
:current_user_is_admin, it { is_expected.to fail_a_policy(:current_user_is_admin) }
)
expect(SiteSetting.title).not_to eq("some new title")
end
end end
context "when the user changes a hidden setting" do context "when the user changes a hidden setting" do
let(:setting_name) { :max_category_nesting }
let(:new_value) { 3 }
context "when allow_changing_hidden is false" do context "when allow_changing_hidden is false" do
it "fails the setting_is_visible policy" do it { is_expected.to fail_a_policy(:setting_is_visible) }
expect(call_service(:max_category_nesting, 3)).to fail_a_policy(:setting_is_visible)
expect(SiteSetting.max_category_nesting).not_to eq(3)
end
end end
context "when allow_changing_hidden is true" do context "when allow_changing_hidden is true" do
let(:allow_changing_hidden) { true }
it { is_expected.to run_successfully }
it "updates the specified setting" do it "updates the specified setting" do
expect(call_service(:max_category_nesting, 3, allow_changing_hidden: true)).to be_success expect { result }.to change { SiteSetting.max_category_nesting }.to(3)
expect(SiteSetting.max_category_nesting).to eq(3)
end end
end end
end end
context "when the user changes a visible setting" do context "when the user changes a visible setting" do
let(:new_value) { "hello this is title" }
it { is_expected.to run_successfully }
it "updates the specified setting" do it "updates the specified setting" do
expect(call_service(:title, "hello this is title")).to be_success expect { result }.to change { SiteSetting.title }.to(new_value)
expect(SiteSetting.title).to eq("hello this is title")
end
it "cleans up the new setting value before using it" do
expect(call_service(:suggested_topics, "308viu")).to be_success
expect(SiteSetting.suggested_topics).to eq(308)
expect(call_service(:max_image_size_kb, "8zf843")).to be_success
expect(SiteSetting.max_image_size_kb).to eq(8843)
end end
it "creates an entry in the staff action logs" do it "creates an entry in the staff action logs" do
expect do expect(call_service(:max_image_size_kb, 44_543)).to be_success end.to change { expect { result }.to change {
UserHistory.where( UserHistory.where(action: UserHistory.actions[:change_site_setting], subject: "title").count
action: UserHistory.actions[:change_site_setting],
subject: "max_image_size_kb",
).count
}.by(1) }.by(1)
end end
context "when value needs cleanup" do
let(:setting_name) { :max_image_size_kb }
let(:new_value) { "8zf843" }
it "cleans up the new setting value before using it" do
expect { result }.to change { SiteSetting.max_image_size_kb }.to(8843)
end
end
end end
end end

View File

@ -10,8 +10,24 @@ module ServiceMatchers
end end
def failure_message def failure_message
message = "Expected the service to succeed but it failed."
error_message_with_inspection(message)
end
def failure_message_when_negated
message = "Expected the service to fail but it succeeded."
error_message_with_inspection(message)
end
def description
"run the service successfully"
end
private
def error_message_with_inspection(message)
inspector = StepsInspector.new(result) inspector = StepsInspector.new(result)
"Expected to run the service sucessfully but failed:\n\n#{inspector.inspect}\n\n#{inspector.error}" "#{message}\n\n#{inspector.inspect}\n\n#{inspector.error}"
end end
end end
@ -137,7 +153,7 @@ module ServiceMatchers
FailStep.new(name) FailStep.new(name)
end end
def run_service_successfully def run_successfully
RunServiceSuccessfully.new RunServiceSuccessfully.new
end end