mirror of
https://github.com/discourse/discourse.git
synced 2025-05-28 13:51:18 +08:00

Followup b5147a4634f0fd5c98262f949a8c766bfd73d290 When we aliased `leave` to `remove` and renamed the method in `DirectMessageChannel` in the previous commit, this inadvertantly caused an error when unfollowing group channels in the channel list. When clicking the X in the channel list, we hit ChannelsCurrentUserMembershipFollowsController for the current user and the channel, which is supposed to only unfollow the channel for all channel types including DMs. Group DMs have a different Leave behaviour vs Unfollow. Leaving the channel altogether is done from the channel settings page, the "Leave channel" button, and that deletes the user's membership and DM user record from that channel. So, we were trying to do the leave channel behaviour in the unfollow channel controller, which was returning the wrong record for the serializer (a User not a Membership) This fixes the issue and removes a bit of delegate/alias indirection which was making the code a bit harder to fllow and search, even though it was more succinct. Also adds missing specs that would have caught this regression.
288 lines
8.3 KiB
Ruby
288 lines
8.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
Fabricator(:chat_channel, class_name: "Chat::Channel") do
|
|
name do
|
|
sequence(:name) do |n|
|
|
random_name = [
|
|
"Gaming Lounge",
|
|
"Music Lodge",
|
|
"Random",
|
|
"Politics",
|
|
"Sports Center",
|
|
"Kino Buffs",
|
|
].sample
|
|
"#{random_name} #{n}"
|
|
end
|
|
end
|
|
chatable { Fabricate(:category) }
|
|
type do |attrs|
|
|
if attrs[:chatable_type] == "Category" || attrs[:chatable].is_a?(Category)
|
|
"CategoryChannel"
|
|
else
|
|
"DirectMessageChannel"
|
|
end
|
|
end
|
|
status { :open }
|
|
end
|
|
|
|
Fabricator(:category_channel, from: :chat_channel) {}
|
|
|
|
Fabricator(:private_category_channel, from: :category_channel) do
|
|
transient :group
|
|
chatable { |attrs| Fabricate(:private_category, group: attrs[:group] || Group[:staff]) }
|
|
end
|
|
|
|
Fabricator(:direct_message_channel, from: :chat_channel) do
|
|
transient :users, :group, following: true, with_membership: true
|
|
chatable do |attrs|
|
|
users = attrs[:users]
|
|
Fabricate(
|
|
:direct_message,
|
|
users: users || [Fabricate(:user), Fabricate(:user)],
|
|
group: attrs[:group] || (users ? users.length > 2 : false),
|
|
)
|
|
end
|
|
status { :open }
|
|
name nil
|
|
threading_enabled true
|
|
after_create do |channel, attrs|
|
|
if attrs[:with_membership]
|
|
channel.chatable.users.each do |user|
|
|
membership = channel.add(user)
|
|
membership.update!(following: false) if attrs[:following] == false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def fake_chat_message
|
|
Faker::Alphanumeric.alpha(number: [15, SiteSetting.chat_minimum_message_length].max)
|
|
end
|
|
|
|
Fabricator(:chat_message, class_name: "Chat::Message") do
|
|
transient use_service: false
|
|
|
|
initialize_with do |transients|
|
|
Fabricate(
|
|
transients[:use_service] ? :chat_message_with_service : :chat_message_without_service,
|
|
**to_params,
|
|
)
|
|
end
|
|
end
|
|
|
|
Fabricator(:chat_message_without_service, class_name: "Chat::Message") do
|
|
user
|
|
chat_channel
|
|
message { fake_chat_message }
|
|
|
|
after_build { |message, attrs| message.cook }
|
|
after_create { |message, attrs| message.upsert_mentions }
|
|
end
|
|
|
|
Fabricator(:chat_message_with_service, class_name: "Chat::CreateMessage") do
|
|
transient :chat_channel,
|
|
:user,
|
|
:message,
|
|
:in_reply_to,
|
|
:thread,
|
|
:upload_ids,
|
|
:incoming_chat_webhook,
|
|
:blocks
|
|
|
|
initialize_with do |transients|
|
|
channel =
|
|
transients[:chat_channel] || transients[:thread]&.channel ||
|
|
transients[:in_reply_to]&.chat_channel || Fabricate(:chat_channel)
|
|
user = transients[:user] || Fabricate(:user)
|
|
Group.refresh_automatic_groups!
|
|
channel.add(user)
|
|
|
|
if !transients[:user] && channel.direct_message_channel?
|
|
channel.chatable.direct_message_users.find_or_create_by!(user: user)
|
|
end
|
|
|
|
result =
|
|
resolved_class.call(
|
|
params: {
|
|
chat_channel_id: channel.id,
|
|
message: transients[:message].presence || fake_chat_message,
|
|
thread_id: transients[:thread]&.id,
|
|
in_reply_to_id: transients[:in_reply_to]&.id,
|
|
upload_ids: transients[:upload_ids],
|
|
blocks: transients[:blocks],
|
|
},
|
|
options: {
|
|
process_inline: true,
|
|
},
|
|
guardian: user.guardian,
|
|
incoming_chat_webhook: transients[:incoming_chat_webhook],
|
|
)
|
|
|
|
if result.failure?
|
|
raise RSpec::Expectations::ExpectationNotMetError.new(
|
|
"Service `#{resolved_class}` failed, see below for step details:\n\n" +
|
|
result.inspect_steps,
|
|
)
|
|
end
|
|
|
|
result.message_instance
|
|
end
|
|
end
|
|
|
|
Fabricator(:chat_mention_notification, class_name: "Chat::MentionNotification") do
|
|
chat_mention { Fabricate(:user_chat_mention) }
|
|
notification { Fabricate(:notification) }
|
|
end
|
|
|
|
Fabricator(:user_chat_mention, class_name: "Chat::UserMention") do
|
|
transient read: false
|
|
transient high_priority: true
|
|
transient identifier: :direct_mentions
|
|
|
|
user { Fabricate(:user) }
|
|
chat_message { Fabricate(:chat_message) }
|
|
end
|
|
|
|
Fabricator(:group_chat_mention, class_name: "Chat::GroupMention") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
group { Fabricate(:group) }
|
|
end
|
|
|
|
Fabricator(:all_chat_mention, class_name: "Chat::AllMention") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
end
|
|
|
|
Fabricator(:here_chat_mention, class_name: "Chat::HereMention") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
end
|
|
|
|
Fabricator(:chat_message_reaction, class_name: "Chat::MessageReaction") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
user { Fabricate(:user) }
|
|
emoji { %w[+1 tada heart joffrey_facepalm].sample }
|
|
after_build do |chat_message_reaction|
|
|
chat_message_reaction.chat_message.chat_channel.add(chat_message_reaction.user)
|
|
end
|
|
end
|
|
|
|
Fabricator(:chat_message_revision, class_name: "Chat::MessageRevision") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
old_message { "something old" }
|
|
new_message { "something new" }
|
|
user { |attrs| attrs[:chat_message].user }
|
|
end
|
|
|
|
Fabricator(:chat_reviewable_message, class_name: "Chat::ReviewableMessage") do
|
|
reviewable_by_moderator true
|
|
type "ReviewableChatMessage"
|
|
created_by { Fabricate(:user) }
|
|
target { Fabricate(:chat_message) }
|
|
reviewable_scores { |p| [Fabricate.build(:reviewable_score, reviewable_id: p[:id])] }
|
|
end
|
|
|
|
Fabricator(:chat_message_interaction, class_name: "Chat::MessageInteraction") do
|
|
message { Fabricate(:chat_message) }
|
|
user { Fabricate(:user) }
|
|
end
|
|
|
|
Fabricator(:direct_message, class_name: "Chat::DirectMessage") do
|
|
users { [Fabricate(:user), Fabricate(:user)] }
|
|
end
|
|
|
|
Fabricator(:chat_webhook_event, class_name: "Chat::WebhookEvent") do
|
|
chat_message { Fabricate(:chat_message) }
|
|
incoming_chat_webhook do |attrs|
|
|
Fabricate(:incoming_chat_webhook, chat_channel: attrs[:chat_message].chat_channel)
|
|
end
|
|
end
|
|
|
|
Fabricator(:incoming_chat_webhook, class_name: "Chat::IncomingWebhook") do
|
|
name { sequence(:name) { |i| "Test webhook #{i + 1}" } }
|
|
emoji { %w[:joy: :rocket: :handshake:].sample }
|
|
chat_channel { Fabricate(:chat_channel, chatable: Fabricate(:category)) }
|
|
end
|
|
|
|
Fabricator(:user_chat_channel_membership, class_name: "Chat::UserChatChannelMembership") do
|
|
user
|
|
chat_channel
|
|
following true
|
|
end
|
|
|
|
Fabricator(:user_chat_channel_membership_for_dm, from: :user_chat_channel_membership) do
|
|
user
|
|
chat_channel
|
|
following true
|
|
notification_level 2
|
|
end
|
|
|
|
Fabricator(:chat_draft, class_name: "Chat::Draft") do
|
|
user
|
|
chat_channel
|
|
|
|
transient :value, "chat draft message"
|
|
transient :uploads, []
|
|
transient :reply_to_msg
|
|
|
|
data do |attrs|
|
|
{ value: attrs[:value], replyToMsg: attrs[:reply_to_msg], uploads: attrs[:uploads] }.to_json
|
|
end
|
|
end
|
|
|
|
Fabricator(:chat_thread, class_name: "Chat::Thread") do
|
|
before_create do |thread, transients|
|
|
thread.original_message_user = original_message.user
|
|
thread.channel = original_message.chat_channel
|
|
end
|
|
|
|
transient :with_replies,
|
|
:channel,
|
|
:original_message_user,
|
|
:old_om,
|
|
use_service: false,
|
|
notification_level: :tracking
|
|
|
|
original_message do |attrs|
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: attrs[:channel] || Fabricate(:chat_channel, threading_enabled: true),
|
|
user: attrs[:original_message_user] || Fabricate(:user),
|
|
use_service: attrs[:use_service],
|
|
)
|
|
end
|
|
|
|
after_create do |thread, transients|
|
|
attrs = { thread_id: thread.id }
|
|
|
|
# Sometimes we make this older via created_at so any messages fabricated for this thread
|
|
# afterwards are not created earlier in time than the OM.
|
|
attrs[:created_at] = 1.week.ago if transients[:old_om]
|
|
|
|
thread.original_message.update!(**attrs)
|
|
thread.add(thread.original_message_user, notification_level: transients[:notification_level])
|
|
|
|
if transients[:with_replies]
|
|
Fabricate
|
|
.times(
|
|
transients[:with_replies],
|
|
:chat_message,
|
|
thread: thread,
|
|
chat_channel_id: thread.channel_id,
|
|
use_service: transients[:use_service],
|
|
)
|
|
.each { |message| thread.add(message.user) }
|
|
|
|
thread.update!(replies_count: transients[:with_replies])
|
|
end
|
|
end
|
|
end
|
|
|
|
Fabricator(:user_chat_thread_membership, class_name: "Chat::UserChatThreadMembership") do
|
|
user
|
|
after_create do |membership|
|
|
Chat::UserChatChannelMembership.find_or_create_by!(
|
|
user: membership.user,
|
|
chat_channel: membership.thread.channel,
|
|
).update!(following: true)
|
|
end
|
|
end
|