DEV: Extract leave logic to the Chat::Channel model

Extracted from https://github.com/discourse/discourse/pull/29129.
This commit is contained in:
Loïc Guitaut 2024-10-11 12:44:59 +02:00 committed by Loïc Guitaut
parent f05b984208
commit af6788fd33
5 changed files with 54 additions and 8 deletions

View File

@ -141,6 +141,7 @@ module Chat
def remove(user)
Chat::ChannelMembershipManager.new(self).unfollow(user)
end
alias leave remove
def url
"#{Discourse.base_url}/chat/c/#{self.slug || "-"}/#{self.id}"

View File

@ -3,6 +3,9 @@
module Chat
class DirectMessageChannel < Channel
alias_method :direct_message, :chatable
delegate :group?, to: :direct_message, prefix: true, allow_nil: true
before_validation(on: :create) { self.threading_enabled = true }
def direct_message_channel?
@ -24,5 +27,13 @@ module Chat
def generate_auto_slug
self.slug.blank?
end
def leave(user)
return super unless direct_message_group?
transaction do
membership_for(user)&.destroy!
direct_message.users.delete(user)
end
end
end
end

View File

@ -33,14 +33,7 @@ module Chat
end
def leave(channel:, guardian:)
ActiveRecord::Base.transaction do
if channel.direct_message_channel? && channel.chatable&.group
channel.membership_for(guardian.user)&.destroy!
channel.chatable.direct_message_users.where(user_id: guardian.user.id).destroy_all
else
channel.remove(guardian.user)
end
end
channel.leave(guardian.user)
end
def recompute_users_count(channel:)

View File

@ -88,6 +88,16 @@ RSpec.describe Chat::CategoryChannel do
end
end
describe "#leave" do
let(:original_method) { channel.method(:remove) }
let(:aliased_method) { channel.method(:leave) }
it "is an alias to '#remove'" do
expect(original_method.original_name).to eq(aliased_method.original_name)
expect(original_method.source_location).to eq(aliased_method.source_location)
end
end
describe "slug generation" do
subject(:channel) { Fabricate(:category_channel) }

View File

@ -6,6 +6,7 @@ RSpec.describe Chat::DirectMessageChannel do
it_behaves_like "a chat channel model"
it { is_expected.to delegate_method(:allowed_user_ids).to(:direct_message).as(:user_ids) }
it { is_expected.to delegate_method(:group?).to(:direct_message).with_prefix.allow_nil }
it { is_expected.to validate_length_of(:description).is_at_most(500) }
it { is_expected.to validate_length_of(:chatable_type).is_at_most(100) }
it { is_expected.to validate_length_of(:type).is_at_most(100) }
@ -70,6 +71,36 @@ RSpec.describe Chat::DirectMessageChannel do
end
end
describe "#leave" do
subject(:leave) { channel.leave(user) }
let(:channel) { Fabricate(:direct_message_channel, group:) }
let(:user) { channel.chatable.users.first }
let(:membership) { channel.membership_for(user) }
context "when DM is not a group" do
let(:group) { false }
it "unfollows the channel for the provided user" do
expect { leave }.to change { membership.reload.following? }.to(false)
end
end
context "when DM is a group" do
let(:group) { true }
it "destroys the provided users membership" do
expect { leave }.to change { channel.user_chat_channel_memberships.where(user:).count }.by(
-1,
)
end
it "removes the provided user from the DM" do
expect { leave }.to change { channel.chatable.users.where(id: user).count }.by(-1)
end
end
end
describe "slug generation" do
subject(:channel) { Fabricate(:direct_message_channel) }