mirror of
https://github.com/discourse/discourse.git
synced 2025-05-12 04:17:25 +08:00

This is just a little clean-up in tests. In the past, when creating a `chat_mention` record, we always created a related notification. Starting from fa543cda notifications and chat_mentions are fully decoupled from each other. So if we're testing just chat mentions there is no need to fabricate notifications for them.
231 lines
9.0 KiB
Ruby
231 lines
9.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
describe Chat::MessageMover do
|
|
fab!(:acting_user) { Fabricate(:admin, username: "testmovechat") }
|
|
fab!(:source_channel) { Fabricate(:category_channel) }
|
|
fab!(:destination_channel) { Fabricate(:category_channel) }
|
|
|
|
fab!(:message1) do
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
created_at: 3.minutes.ago,
|
|
message: "the first to be moved",
|
|
)
|
|
end
|
|
fab!(:message2) do
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
created_at: 2.minutes.ago,
|
|
message: "message deux @testmovechat",
|
|
)
|
|
end
|
|
fab!(:message3) do
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
created_at: 1.minute.ago,
|
|
message: "the third message",
|
|
)
|
|
end
|
|
fab!(:message4) { Fabricate(:chat_message, chat_channel: destination_channel) }
|
|
fab!(:message5) { Fabricate(:chat_message, chat_channel: destination_channel) }
|
|
fab!(:message6) { Fabricate(:chat_message, chat_channel: destination_channel) }
|
|
let(:move_message_ids) { [message1.id, message2.id, message3.id] }
|
|
|
|
describe "#move_to_channel" do
|
|
def move!(move_message_ids = [message1.id, message2.id, message3.id])
|
|
described_class.new(
|
|
acting_user: acting_user,
|
|
source_channel: source_channel,
|
|
message_ids: move_message_ids,
|
|
).move_to_channel(destination_channel)
|
|
end
|
|
|
|
it "raises an error if either the source or destination channels are not public (they cannot be DM channels)" do
|
|
expect {
|
|
described_class.new(
|
|
acting_user: acting_user,
|
|
source_channel: Fabricate(:direct_message_channel),
|
|
message_ids: move_message_ids,
|
|
).move_to_channel(destination_channel)
|
|
}.to raise_error(Chat::MessageMover::InvalidChannel)
|
|
expect {
|
|
described_class.new(
|
|
acting_user: acting_user,
|
|
source_channel: source_channel,
|
|
message_ids: move_message_ids,
|
|
).move_to_channel(Fabricate(:direct_message_channel))
|
|
}.to raise_error(Chat::MessageMover::InvalidChannel)
|
|
end
|
|
|
|
it "raises an error if no messages are found using the message ids" do
|
|
other_channel = Fabricate(:chat_channel)
|
|
message1.update(chat_channel: other_channel)
|
|
message2.update(chat_channel: other_channel)
|
|
message3.update(chat_channel: other_channel)
|
|
expect { move! }.to raise_error(Chat::MessageMover::NoMessagesFound)
|
|
end
|
|
|
|
it "deletes the messages from the source channel and sends messagebus delete messages" do
|
|
messages = MessageBus.track_publish { move! }
|
|
expect(ChatMessage.where(id: move_message_ids)).to eq([])
|
|
deleted_messages = ChatMessage.with_deleted.where(id: move_message_ids).order(:id)
|
|
expect(deleted_messages.count).to eq(3)
|
|
expect(messages.first.channel).to eq("/chat/#{source_channel.id}")
|
|
expect(messages.first.data[:typ]).to eq("bulk_delete")
|
|
expect(messages.first.data[:deleted_ids]).to eq(deleted_messages.map(&:id))
|
|
expect(messages.first.data[:deleted_at]).not_to eq(nil)
|
|
end
|
|
|
|
it "creates a message in the source channel to indicate that the messages have been moved" do
|
|
move!
|
|
placeholder_message = ChatMessage.where(chat_channel: source_channel).order(:created_at).last
|
|
destination_first_moved_message =
|
|
ChatMessage.find_by(chat_channel: destination_channel, message: "the first to be moved")
|
|
expect(placeholder_message.message).to eq(
|
|
I18n.t(
|
|
"chat.channel.messages_moved",
|
|
count: move_message_ids.length,
|
|
acting_username: acting_user.username,
|
|
channel_name: destination_channel.title(acting_user),
|
|
first_moved_message_url: destination_first_moved_message.url,
|
|
),
|
|
)
|
|
end
|
|
|
|
it "preserves the order of the messages in the destination channel" do
|
|
move!
|
|
moved_messages =
|
|
ChatMessage.where(chat_channel: destination_channel).order("created_at ASC, id ASC").last(3)
|
|
expect(moved_messages.map(&:message)).to eq(
|
|
["the first to be moved", "message deux @testmovechat", "the third message"],
|
|
)
|
|
end
|
|
|
|
it "updates references for reactions, uploads, revisions, mentions, etc." do
|
|
reaction = Fabricate(:chat_message_reaction, chat_message: message1)
|
|
upload = Fabricate(:upload_reference, target: message1)
|
|
mention = Fabricate(:chat_mention, chat_message: message2, user: acting_user)
|
|
revision = Fabricate(:chat_message_revision, chat_message: message3)
|
|
webhook_event = Fabricate(:chat_webhook_event, chat_message: message3)
|
|
move!
|
|
|
|
moved_messages =
|
|
ChatMessage.where(chat_channel: destination_channel).order("created_at ASC, id ASC").last(3)
|
|
expect(reaction.reload.chat_message_id).to eq(moved_messages.first.id)
|
|
expect(upload.reload.target_id).to eq(moved_messages.first.id)
|
|
expect(mention.reload.chat_message_id).to eq(moved_messages.second.id)
|
|
expect(revision.reload.chat_message_id).to eq(moved_messages.third.id)
|
|
expect(webhook_event.reload.chat_message_id).to eq(moved_messages.third.id)
|
|
end
|
|
|
|
it "does not preserve reply chains using in_reply_to_id" do
|
|
message3.update!(in_reply_to: message2)
|
|
message2.update!(in_reply_to: message1)
|
|
move!
|
|
moved_messages =
|
|
ChatMessage.where(chat_channel: destination_channel).order("created_at ASC, id ASC").last(3)
|
|
|
|
expect(moved_messages.pluck(:in_reply_to_id).uniq).to eq([nil])
|
|
end
|
|
|
|
it "clears in_reply_to_id for remaining messages when the messages they were replying to are moved" do
|
|
message3.update!(in_reply_to: message2)
|
|
message2.update!(in_reply_to: message1)
|
|
move!([message2.id])
|
|
expect(message3.reload.in_reply_to_id).to eq(nil)
|
|
end
|
|
|
|
context "when there is a thread" do
|
|
fab!(:thread) { Fabricate(:chat_thread, channel: source_channel, original_message: message1) }
|
|
|
|
before do
|
|
message1.update!(thread: thread)
|
|
message2.update!(thread: thread)
|
|
message3.update!(thread: thread)
|
|
end
|
|
|
|
it "does not preserve thread_ids" do
|
|
move!
|
|
moved_messages =
|
|
ChatMessage
|
|
.where(chat_channel: destination_channel)
|
|
.order("created_at ASC, id ASC")
|
|
.last(3)
|
|
|
|
expect(moved_messages.pluck(:thread_id).uniq).to eq([nil])
|
|
end
|
|
|
|
it "deletes the empty thread" do
|
|
move!
|
|
expect(ChatThread.exists?(id: thread.id)).to eq(false)
|
|
end
|
|
|
|
it "clears in_reply_to_id for remaining messages when the messages they were replying to are moved but leaves the thread_id" do
|
|
message3.update!(in_reply_to: message2)
|
|
message2.update!(in_reply_to: message1)
|
|
move!([message2.id])
|
|
expect(message3.reload.in_reply_to_id).to eq(nil)
|
|
expect(message3.reload.thread).to eq(thread)
|
|
end
|
|
|
|
context "when a thread original message is moved" do
|
|
it "creates a new thread for the messages left behind in the old channel" do
|
|
message4 =
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
message: "the fourth message",
|
|
in_reply_to: message3,
|
|
thread: thread,
|
|
)
|
|
message5 =
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
message: "the fifth message",
|
|
thread: thread,
|
|
)
|
|
expect { move! }.to change { ChatThread.count }.by(1)
|
|
new_thread = ChatThread.last
|
|
expect(message4.reload.thread_id).to eq(new_thread.id)
|
|
expect(message5.reload.thread_id).to eq(new_thread.id)
|
|
expect(new_thread.channel).to eq(source_channel)
|
|
expect(new_thread.original_message).to eq(message4)
|
|
end
|
|
end
|
|
|
|
context "when multiple thread original messages are moved" do
|
|
it "works the same as when one is" do
|
|
message4 =
|
|
Fabricate(:chat_message, chat_channel: source_channel, message: "the fourth message")
|
|
message5 =
|
|
Fabricate(
|
|
:chat_message,
|
|
chat_channel: source_channel,
|
|
in_reply_to: message5,
|
|
message: "the fifth message",
|
|
)
|
|
other_thread =
|
|
Fabricate(:chat_thread, channel: source_channel, original_message: message4)
|
|
message4.update!(thread: other_thread)
|
|
message5.update!(thread: other_thread)
|
|
expect { move!([message1.id, message4.id]) }.to change { ChatThread.count }.by(2)
|
|
|
|
new_threads = ChatThread.order(:created_at).last(2)
|
|
expect(message3.reload.thread_id).to eq(new_threads.first.id)
|
|
expect(message5.reload.thread_id).to eq(new_threads.second.id)
|
|
expect(new_threads.first.channel).to eq(source_channel)
|
|
expect(new_threads.second.channel).to eq(source_channel)
|
|
expect(new_threads.first.original_message).to eq(message2)
|
|
expect(new_threads.second.original_message).to eq(message5)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|