diff --git a/plugins/chat/app/services/chat/auto_leave_channels.rb b/plugins/chat/app/services/chat/auto_leave_channels.rb index 3adf8efeb1e..96e5239edb4 100644 --- a/plugins/chat/app/services/chat/auto_leave_channels.rb +++ b/plugins/chat/app/services/chat/auto_leave_channels.rb @@ -17,6 +17,8 @@ module Chat attribute :group_id, :integer attribute :channel_id, :integer attribute :category_id, :integer + + validates :event, presence: true end step :remove_memberships @@ -34,6 +36,7 @@ module Chat if !group_ids.include?(Group::AUTO_GROUPS[:everyone]) sql = <<~SQL + -- event = #{params.event} DELETE FROM user_chat_channel_memberships uccm WHERE NOT EXISTS ( SELECT 1 @@ -41,6 +44,7 @@ module Chat WHERE gu.user_id = uccm.user_id AND gu.group_id IN (:group_ids) ) + #{params.user_id ? "AND uccm.user_id = #{params.user_id}" : ""} RETURNING chat_channel_id, user_id SQL @@ -54,6 +58,7 @@ module Chat category_sql = params.category_id ? "AND c.id = #{params.category_id}" : "" sql = <<~SQL + -- event = #{params.event} WITH valid_permissions AS ( SELECT gu.user_id, cg.category_id FROM group_users gu diff --git a/plugins/chat/spec/integration/auto_channel_user_removal_spec.rb b/plugins/chat/spec/integration/auto_channel_user_removal_spec.rb index d05b74f5f73..8573fd499f4 100644 --- a/plugins/chat/spec/integration/auto_channel_user_removal_spec.rb +++ b/plugins/chat/spec/integration/auto_channel_user_removal_spec.rb @@ -2,9 +2,10 @@ describe "Automatic user removal from channels" do fab!(:user_1) { Fabricate(:user, trust_level: 1) } - let(:user_1_guardian) { Guardian.new(user_1) } fab!(:user_2) { Fabricate(:user, trust_level: 3) } + fab!(:user_1_guardian) { Guardian.new(user_1) } + fab!(:secret_group) { Fabricate(:group) } fab!(:private_category) { Fabricate(:private_category, group: secret_group) } @@ -145,6 +146,7 @@ describe "Automatic user removal from channels" do context "when a user is removed from a private category group" do context "when the user is in another group that can interact with the channel" do fab!(:stealth_group) { Fabricate(:group) } + before do CategoryGroup.create!( category: private_category, diff --git a/plugins/chat/spec/services/chat/auto_leave_channels_spec.rb b/plugins/chat/spec/services/chat/auto_leave_channels_spec.rb index 65696c21c62..0397ae625be 100644 --- a/plugins/chat/spec/services/chat/auto_leave_channels_spec.rb +++ b/plugins/chat/spec/services/chat/auto_leave_channels_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Chat::AutoLeaveChannels do describe ".call" do - subject(:result) { described_class.call(params: {}) } + subject(:result) { described_class.call(params: { event: :generic_event }) } let!(:previous_events) { DiscourseEvent.events.dup } @@ -26,6 +26,12 @@ RSpec.describe Chat::AutoLeaveChannels do expect { result }.to change { ::Chat::UserChatChannelMembership.count }.from(2).to(0) end + it "only removes memberships for a user when filtering by user_id" do + expect { + described_class.call(params: { event: :generic_event, user_id: uccm_1.user_id }) + }.to change { ::Chat::UserChatChannelMembership.count }.from(2).to(1) + end + it "publishes automatically removed users" do ::Chat::Action::PublishAutoRemovedUser .expects(:call) @@ -72,7 +78,12 @@ RSpec.describe Chat::AutoLeaveChannels do ::Chat::Action::PublishAutoRemovedUser .expects(:call) .once - .with(event: nil, users_removed_map: { uccm.chat_channel_id => [uccm.user_id] }) + .with( + event: :generic_event, + users_removed_map: { + uccm.chat_channel_id => [uccm.user_id], + }, + ) result end @@ -99,6 +110,7 @@ RSpec.describe Chat::AutoLeaveChannels do end context "with another category/channel/user" do + let(:params) { { event: :generic_event } } fab!(:user_2) { Fabricate(:user, trust_level: 1) } fab!(:category_2) { Fabricate(:private_category, group:) } fab!(:chat_channel_2) { Fabricate(:chat_channel, chatable: category_2) } @@ -107,21 +119,21 @@ RSpec.describe Chat::AutoLeaveChannels do end it "supports filtering by user_id" do - expect { described_class.call(params: { user_id: user.id }) }.to change { + expect { described_class.call(params: params.merge(user_id: user.id)) }.to change { ::Chat::UserChatChannelMembership.count }.from(2).to(1) end it "supports filtering by channel_id" do - expect { described_class.call(params: { channel_id: chat_channel.id }) }.to change { - ::Chat::UserChatChannelMembership.count - }.from(2).to(1) + expect { + described_class.call(params: params.merge(channel_id: chat_channel.id)) + }.to change { ::Chat::UserChatChannelMembership.count }.from(2).to(1) end it "supports filtering by category_id" do - expect { described_class.call(params: { category_id: category.id }) }.to change { - ::Chat::UserChatChannelMembership.count - }.from(2).to(1) + expect { + described_class.call(params: params.merge(category_id: category.id)) + }.to change { ::Chat::UserChatChannelMembership.count }.from(2).to(1) end end end