2022-11-02 09:41:30 -04:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
require "rails_helper"
|
|
|
|
|
|
|
|
|
|
describe Chat::ChatMessageCreator do
|
|
|
|
|
fab!(:admin1) { Fabricate(:admin) }
|
|
|
|
|
fab!(:admin2) { Fabricate(:admin) }
|
|
|
|
|
fab!(:user1) { Fabricate(:user, group_ids: [Group::AUTO_GROUPS[:everyone]]) }
|
|
|
|
|
fab!(:user2) { Fabricate(:user) }
|
|
|
|
|
fab!(:user3) { Fabricate(:user) }
|
|
|
|
|
fab!(:user4) { Fabricate(:user) }
|
|
|
|
|
fab!(:admin_group) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:public_group,
|
|
|
|
|
users: [admin1, admin2],
|
|
|
|
|
mentionable_level: Group::ALIAS_LEVELS[:everyone],
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
fab!(:user_group) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:public_group,
|
|
|
|
|
users: [user1, user2, user3],
|
|
|
|
|
mentionable_level: Group::ALIAS_LEVELS[:everyone],
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
fab!(:user_without_memberships) { Fabricate(:user) }
|
|
|
|
|
fab!(:public_chat_channel) { Fabricate(:category_channel) }
|
|
|
|
|
fab!(:dm_chat_channel) do
|
|
|
|
|
Fabricate(
|
2022-11-02 10:53:36 -04:00
|
|
|
|
:direct_message_channel,
|
|
|
|
|
chatable: Fabricate(:direct_message, users: [user1, user2, user3]),
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
let(:direct_message_channel) do
|
|
|
|
|
Chat::DirectMessageChannelCreator.create!(acting_user: user1, target_users: [user1, user2])
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
SiteSetting.chat_enabled = true
|
|
|
|
|
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
|
|
|
|
SiteSetting.chat_duplicate_message_sensitivity = 0
|
|
|
|
|
|
|
|
|
|
# Create channel memberships
|
|
|
|
|
[admin1, admin2, user1, user2, user3].each do |user|
|
|
|
|
|
Fabricate(:user_chat_channel_membership, chat_channel: public_chat_channel, user: user)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
Group.refresh_automatic_groups!
|
2022-11-02 10:53:36 -04:00
|
|
|
|
direct_message_channel
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "Integration tests with jobs running immediately" do
|
|
|
|
|
before { Jobs.run_immediately! }
|
|
|
|
|
|
|
|
|
|
it "errors when length is less than `chat_minimum_message_length`" do
|
|
|
|
|
SiteSetting.chat_minimum_message_length = 10
|
|
|
|
|
creator =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "2 short",
|
|
|
|
|
)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to match(
|
|
|
|
|
I18n.t(
|
|
|
|
|
"chat.errors.minimum_length_not_met",
|
2023-02-20 04:31:02 -05:00
|
|
|
|
{ count: SiteSetting.chat_minimum_message_length },
|
2022-11-02 09:41:30 -04:00
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-27 19:48:30 -05:00
|
|
|
|
it "errors when length is greater than `chat_maximum_message_length`" do
|
|
|
|
|
SiteSetting.chat_maximum_message_length = 100
|
|
|
|
|
creator =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "a really long and in depth message that is just too detailed" * 100,
|
|
|
|
|
)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to match(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.message_too_long", { count: SiteSetting.chat_maximum_message_length }),
|
2022-11-27 19:48:30 -05:00
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-02 09:41:30 -04:00
|
|
|
|
it "allows message creation when length is less than `chat_minimum_message_length` when upload is present" do
|
|
|
|
|
upload = Fabricate(:upload, user: user1)
|
|
|
|
|
SiteSetting.chat_minimum_message_length = 10
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "2 short",
|
|
|
|
|
upload_ids: [upload.id],
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMessage.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates messages for users who can see the channel" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMessage.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
2022-12-06 13:33:39 -05:00
|
|
|
|
it "updates the channel’s last message date" do
|
|
|
|
|
previous_last_message_sent_at = public_chat_channel.last_message_sent_at
|
|
|
|
|
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(previous_last_message_sent_at).to be < public_chat_channel.reload.last_message_sent_at
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-06 18:04:47 -05:00
|
|
|
|
it "sets the last_editor_id to the user who created the message" do
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
).chat_message
|
|
|
|
|
expect(message.last_editor_id).to eq(user1.id)
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-07 13:06:10 -05:00
|
|
|
|
it "publishes a DiscourseEvent for new messages" do
|
|
|
|
|
events =
|
|
|
|
|
DiscourseEvent.track_events do
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
)
|
2023-01-06 15:42:16 -05:00
|
|
|
|
end
|
2022-11-07 13:06:10 -05:00
|
|
|
|
expect(events.map { _1[:event_name] }).to include(:chat_message_created)
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-02 09:41:30 -04:00
|
|
|
|
it "creates mention notifications for public chat" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content:
|
|
|
|
|
"this is a @#{user1.username} message with @system @mentions @#{user2.username} and @#{user3.username}",
|
|
|
|
|
)
|
|
|
|
|
# Only 2 mentions are created because user mentioned themselves, system, and an invalid username.
|
|
|
|
|
}.to change { ChatMention.count }.by(2).and not_change { user1.chat_mentions.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "mentions are case insensitive" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Hey @#{user2.username.upcase}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { user2.chat_mentions.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "notifies @all properly" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@all",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(4)
|
|
|
|
|
|
|
|
|
|
UserChatChannelMembership.where(user: user2, chat_channel: public_chat_channel).update_all(
|
|
|
|
|
following: false,
|
|
|
|
|
)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "again! @all",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(3)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "notifies @here properly" do
|
|
|
|
|
admin1.update(last_seen_at: 1.year.ago)
|
|
|
|
|
admin2.update(last_seen_at: 1.year.ago)
|
|
|
|
|
user1.update(last_seen_at: Time.now)
|
|
|
|
|
user2.update(last_seen_at: Time.now)
|
|
|
|
|
user3.update(last_seen_at: Time.now)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@here",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(2)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't sent double notifications when '@here' is mentioned" do
|
|
|
|
|
user2.update(last_seen_at: Time.now)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@here @#{user2.username}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { user2.chat_mentions.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "notifies @here plus other mentions" do
|
|
|
|
|
admin1.update(last_seen_at: Time.now)
|
|
|
|
|
admin2.update(last_seen_at: 1.year.ago)
|
|
|
|
|
user1.update(last_seen_at: 1.year.ago)
|
|
|
|
|
user2.update(last_seen_at: 1.year.ago)
|
|
|
|
|
user3.update(last_seen_at: 1.year.ago)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@here plus @#{user3.username}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { user3.chat_mentions.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't create mention notifications for users without a membership record" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{user_without_memberships.username}",
|
|
|
|
|
)
|
|
|
|
|
}.not_to change { ChatMention.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't create mention notifications for users who cannot chat" do
|
|
|
|
|
new_group = Group.create
|
|
|
|
|
SiteSetting.chat_allowed_groups = new_group.id
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hi @#{user2.username} @#{user3.username}",
|
|
|
|
|
)
|
|
|
|
|
}.not_to change { ChatMention.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't create mention notifications for users with chat disabled" do
|
|
|
|
|
user2.user_option.update(chat_enabled: false)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hi @#{user2.username}",
|
|
|
|
|
)
|
|
|
|
|
}.not_to change { ChatMention.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates only mention notifications for users with access in private chat" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
2022-11-02 10:53:36 -04:00
|
|
|
|
chat_channel: direct_message_channel,
|
2022-11-02 09:41:30 -04:00
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello there @#{user2.username} and @#{user3.username}",
|
|
|
|
|
)
|
|
|
|
|
# Only user2 should be notified
|
|
|
|
|
}.to change { user2.chat_mentions.count }.by(1).and not_change { user3.chat_mentions.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates a mention notifications for group users that are participating in private chat" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
2022-11-02 10:53:36 -04:00
|
|
|
|
chat_channel: direct_message_channel,
|
2022-11-02 09:41:30 -04:00
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello there @#{user_group.name}",
|
|
|
|
|
)
|
|
|
|
|
# Only user2 should be notified
|
|
|
|
|
}.to change { user2.chat_mentions.count }.by(1).and not_change { user3.chat_mentions.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "publishes inaccessible mentions when user isn't aren't a part of the channel" do
|
|
|
|
|
ChatPublisher.expects(:publish_inaccessible_mentions).once
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: admin1,
|
|
|
|
|
content: "hello @#{user4.username}",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "publishes inaccessible mentions when user doesn't have chat access" do
|
|
|
|
|
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff]
|
|
|
|
|
ChatPublisher.expects(:publish_inaccessible_mentions).once
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: admin1,
|
|
|
|
|
content: "hello @#{user3.username}",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't publish inaccessible mentions when user is following channel" do
|
|
|
|
|
ChatPublisher.expects(:publish_inaccessible_mentions).never
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: admin1,
|
|
|
|
|
content: "hello @#{admin2.username}",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not create mentions for suspended users" do
|
|
|
|
|
user2.update(suspended_till: Time.now + 10.years)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
2022-11-02 10:53:36 -04:00
|
|
|
|
chat_channel: direct_message_channel,
|
2022-11-02 09:41:30 -04:00
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{user2.username}",
|
|
|
|
|
)
|
|
|
|
|
}.not_to change { user2.chat_mentions.count }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not create @all mentions for users when ignore_channel_wide_mention is enabled" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@all",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(4)
|
|
|
|
|
|
|
|
|
|
user2.user_option.update(ignore_channel_wide_mention: true)
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hi! @all",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(3)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not create @here mentions for users when ignore_channel_wide_mention is enabled" do
|
|
|
|
|
admin1.update(last_seen_at: 1.year.ago)
|
|
|
|
|
admin2.update(last_seen_at: 1.year.ago)
|
|
|
|
|
user1.update(last_seen_at: Time.now)
|
|
|
|
|
user2.update(last_seen_at: Time.now)
|
|
|
|
|
user2.user_option.update(ignore_channel_wide_mention: true)
|
|
|
|
|
user3.update(last_seen_at: Time.now)
|
|
|
|
|
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "@here",
|
|
|
|
|
)
|
|
|
|
|
}.to change { ChatMention.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
FEATURE: Automatically create chat threads in background (#20206)
Whenever we create a chat message that is `in_reply_to` another
message, we want to lazily populate the thread record for the
message chain.
If there is no thread yet for the root message in the reply chain,
we create a new thread with the appropriate details, and use that
thread ID for every message in the chain that does not yet have
a thread ID.
* Root message (ID 1) - no thread ID
* Message (ID 2, in_reply_to 1) - no thread ID
* When I as a user create a message in reply to ID 2, we create a thread and apply it to ID 1, ID 2, and the new message
If there is a thread for the root message in the reply chain, we
do not create one, and use the thread ID for the newly created chat
message.
* Root message (ID 1) - thread ID 700
* Message (ID 2, in_reply_to 1) - thread ID 700
* When I as a user create a message in reply to ID 2, we use the existing thread ID 700 for the new message
We also support passing in the `thread_id` to `ChatMessageCreator`,
which will be used when replying to a message that is already part of
a thread, and we validate whether that `thread_id` is okay in the context
of the channel and also the reply chain.
This work is always done, regardless of channel `thread_enabled` settings
or the `enable_experimental_chat_threaded_discussions` site setting.
This commit does not include a large data migration to backfill threads for
all existing reply chains, its unnecessary to do this so early in the project,
we can do this later if necessary.
This commit also includes thread considerations in the `MessageMover` class:
* If the original message and N other messages of a thread is moved,
the remaining messages in the thread have a new thread created in
the old channel and are moved to it.
* The reply chain is not preserved for moved messages, so new threads are
not created in the destination channel.
In addition to this, I added a fix to also clear the `in_reply_to_id` of messages
in the old channel which are moved out of that channel for data cleanliness.
2023-02-07 19:22:07 -05:00
|
|
|
|
describe "replies" do
|
|
|
|
|
fab!(:reply_message) do
|
|
|
|
|
Fabricate(:chat_message, chat_channel: public_chat_channel, user: user2)
|
|
|
|
|
end
|
|
|
|
|
fab!(:unrelated_message_1) { Fabricate(:chat_message, chat_channel: public_chat_channel) }
|
|
|
|
|
fab!(:unrelated_message_2) { Fabricate(:chat_message, chat_channel: public_chat_channel) }
|
|
|
|
|
|
|
|
|
|
it "links the message that the user is replying to" do
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
|
|
|
|
|
expect(message.in_reply_to_id).to eq(reply_message.id)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates a thread and includes the original message and the reply" do
|
|
|
|
|
message = nil
|
|
|
|
|
expect {
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
}.to change { ChatThread.count }.by(1)
|
|
|
|
|
|
|
|
|
|
expect(message.reload.thread).not_to eq(nil)
|
|
|
|
|
expect(message.in_reply_to.thread).to eq(message.thread)
|
|
|
|
|
expect(message.thread.original_message).to eq(reply_message)
|
|
|
|
|
expect(message.thread.original_message_user).to eq(reply_message.user)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when the thread_id is provided" do
|
|
|
|
|
fab!(:existing_thread) { Fabricate(:chat_thread, channel: public_chat_channel) }
|
|
|
|
|
|
|
|
|
|
it "does not create a thread when one is passed in" do
|
|
|
|
|
message = nil
|
|
|
|
|
expect {
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
thread_id: existing_thread.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
}.not_to change { ChatThread.count }
|
|
|
|
|
|
|
|
|
|
expect(message.reload.thread).to eq(existing_thread)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "errors when the thread ID is for a different channel" do
|
|
|
|
|
other_channel_thread = Fabricate(:chat_thread, channel: Fabricate(:chat_channel))
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
thread_id: other_channel_thread.id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.thread_invalid_for_channel"))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "errors when the thread does not match the in_reply_to thread" do
|
|
|
|
|
reply_message.update!(thread: existing_thread)
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
thread_id: Fabricate(:chat_thread, channel: public_chat_channel).id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.thread_does_not_match_parent"))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "errors when the root message does not have a thread ID" do
|
|
|
|
|
reply_message.update!(thread: nil)
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
thread_id: existing_thread.id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.thread_does_not_match_parent"))
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "for missing root messages" do
|
|
|
|
|
fab!(:original_message) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:chat_message,
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user2,
|
|
|
|
|
created_at: 1.day.ago,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
before { reply_message.update!(in_reply_to: original_message) }
|
|
|
|
|
|
|
|
|
|
it "raises an error when the root message has been trashed" do
|
|
|
|
|
original_message.trash!
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.original_message_not_found"))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "uses the next message in the chain as the root when the root is deleted" do
|
|
|
|
|
original_message.destroy!
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
)
|
|
|
|
|
expect(reply_message.reload.thread).not_to eq(nil)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when there is an existing reply chain" do
|
|
|
|
|
fab!(:old_message_1) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:chat_message,
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
created_at: 6.hours.ago,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
fab!(:old_message_2) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:chat_message,
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user2,
|
|
|
|
|
in_reply_to: old_message_1,
|
|
|
|
|
created_at: 4.hours.ago,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
fab!(:old_message_3) do
|
|
|
|
|
Fabricate(
|
|
|
|
|
:chat_message,
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
in_reply_to: old_message_2,
|
|
|
|
|
created_at: 1.hour.ago,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
reply_message.update!(
|
|
|
|
|
created_at: old_message_3.created_at + 1.hour,
|
|
|
|
|
in_reply_to: old_message_3,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates a thread and updates all the messages in the chain" do
|
|
|
|
|
thread_count = ChatThread.count
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
|
|
|
|
|
expect(ChatThread.count).to eq(thread_count + 1)
|
|
|
|
|
expect(message.reload.thread).not_to eq(nil)
|
|
|
|
|
expect(message.reload.in_reply_to.thread).to eq(message.thread)
|
|
|
|
|
expect(old_message_1.reload.thread).to eq(message.thread)
|
|
|
|
|
expect(old_message_2.reload.thread).to eq(message.thread)
|
|
|
|
|
expect(old_message_3.reload.thread).to eq(message.thread)
|
|
|
|
|
expect(message.thread.chat_messages.count).to eq(5)
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when a thread already exists and the thread_id is passed in" do
|
|
|
|
|
let!(:last_message) do
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
end
|
|
|
|
|
let!(:existing_thread) { last_message.reload.thread }
|
|
|
|
|
|
|
|
|
|
it "does not create a new thread" do
|
|
|
|
|
thread_count = ChatThread.count
|
|
|
|
|
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message again",
|
|
|
|
|
in_reply_to_id: last_message.id,
|
|
|
|
|
thread_id: existing_thread.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
|
|
|
|
|
expect(ChatThread.count).to eq(thread_count)
|
|
|
|
|
expect(message.reload.thread).to eq(existing_thread)
|
|
|
|
|
expect(message.reload.in_reply_to.thread).to eq(existing_thread)
|
|
|
|
|
expect(message.thread.chat_messages.count).to eq(6)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "errors when the thread does not match the root thread" do
|
|
|
|
|
old_message_1.update!(thread: Fabricate(:chat_thread, channel: public_chat_channel))
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
thread_id: existing_thread.id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.thread_does_not_match_parent"))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "errors when the root message does not have a thread ID" do
|
|
|
|
|
old_message_1.update!(thread: nil)
|
|
|
|
|
result =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
thread_id: existing_thread.id,
|
|
|
|
|
)
|
|
|
|
|
expect(result.error.message).to eq(I18n.t("chat.errors.thread_does_not_match_parent"))
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when there are hundreds of messages in a reply chain already" do
|
|
|
|
|
before do
|
|
|
|
|
previous_message = nil
|
|
|
|
|
1000.times do |i|
|
|
|
|
|
previous_message =
|
|
|
|
|
Fabricate(
|
|
|
|
|
:chat_message,
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: [user1, user2].sample,
|
|
|
|
|
in_reply_to: previous_message,
|
|
|
|
|
created_at: i.hours.ago,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
@last_message_in_chain = previous_message
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
xit "works" do
|
|
|
|
|
thread_count = ChatThread.count
|
|
|
|
|
|
|
|
|
|
message = nil
|
|
|
|
|
puts Benchmark.measure {
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: @last_message_in_chain.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expect(ChatThread.count).to eq(thread_count + 1)
|
|
|
|
|
expect(message.reload.thread).not_to eq(nil)
|
|
|
|
|
expect(message.reload.in_reply_to.thread).to eq(message.thread)
|
|
|
|
|
expect(message.thread.chat_messages.count).to eq(1001)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "if the root message alread had a thread" do
|
|
|
|
|
fab!(:old_thread) { Fabricate(:chat_thread, original_message: old_message_1) }
|
|
|
|
|
fab!(:incorrect_thread) { Fabricate(:chat_thread, channel: public_chat_channel) }
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
old_message_1.update!(thread: old_thread)
|
|
|
|
|
old_message_3.update!(thread: incorrect_thread)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not change any messages in the chain, assumes they have the correct thread ID" do
|
|
|
|
|
thread_count = ChatThread.count
|
|
|
|
|
message =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "this is a message",
|
|
|
|
|
in_reply_to_id: reply_message.id,
|
|
|
|
|
).chat_message
|
|
|
|
|
|
|
|
|
|
expect(ChatThread.count).to eq(thread_count)
|
|
|
|
|
expect(message.reload.thread).to eq(old_thread)
|
|
|
|
|
expect(message.reload.in_reply_to.thread).to eq(old_thread)
|
|
|
|
|
expect(old_message_1.reload.thread).to eq(old_thread)
|
|
|
|
|
expect(old_message_2.reload.thread).to eq(old_thread)
|
|
|
|
|
expect(old_message_3.reload.thread).to eq(incorrect_thread)
|
|
|
|
|
expect(message.thread.chat_messages.count).to eq(4)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2022-11-02 09:41:30 -04:00
|
|
|
|
describe "group mentions" do
|
|
|
|
|
it "creates chat mentions for group mentions where the group is mentionable" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{admin_group.name}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { admin1.chat_mentions.count }.by(1).and change {
|
|
|
|
|
admin2.chat_mentions.count
|
|
|
|
|
}.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't mention users twice if they are direct mentioned and group mentioned" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{admin_group.name} @#{admin1.username} and @#{admin2.username}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { admin1.chat_mentions.count }.by(1).and change {
|
|
|
|
|
admin2.chat_mentions.count
|
|
|
|
|
}.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates chat mentions for group mentions and direct mentions" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{admin_group.name} @#{user2.username}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { admin1.chat_mentions.count }.by(1).and change {
|
|
|
|
|
admin2.chat_mentions.count
|
|
|
|
|
}.by(1).and change { user2.chat_mentions.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "creates chat mentions for group mentions and direct mentions" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{admin_group.name} @#{user_group.name}",
|
|
|
|
|
)
|
|
|
|
|
}.to change { admin1.chat_mentions.count }.by(1).and change {
|
|
|
|
|
admin2.chat_mentions.count
|
|
|
|
|
}.by(1).and change { user2.chat_mentions.count }.by(1).and change {
|
|
|
|
|
user3.chat_mentions.count
|
|
|
|
|
}.by(1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't create chat mentions for group mentions where the group is un-mentionable" do
|
|
|
|
|
admin_group.update(mentionable_level: Group::ALIAS_LEVELS[:nobody])
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "hello @#{admin_group.name}",
|
|
|
|
|
)
|
|
|
|
|
}.not_to change { ChatMention.count }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "push notifications" do
|
|
|
|
|
before do
|
|
|
|
|
UserChatChannelMembership.where(user: user1, chat_channel: public_chat_channel).update(
|
|
|
|
|
mobile_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
|
|
|
)
|
|
|
|
|
PresenceChannel.clear_all!
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "sends a push notification to watching users who are not in chat" do
|
|
|
|
|
PostAlerter.expects(:push_notification).once
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user2,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not send a push notification to watching users who are in chat" do
|
|
|
|
|
PresenceChannel.new("/chat/online").present(user_id: user1.id, client_id: 1)
|
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user2,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "with uploads" do
|
|
|
|
|
fab!(:upload1) { Fabricate(:upload, user: user1) }
|
|
|
|
|
fab!(:upload2) { Fabricate(:upload, user: user1) }
|
|
|
|
|
fab!(:private_upload) { Fabricate(:upload, user: user2) }
|
|
|
|
|
|
|
|
|
|
it "can attach 1 upload to a new message" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
upload_ids: [upload1.id],
|
|
|
|
|
)
|
2023-01-23 22:28:21 -05:00
|
|
|
|
}.to not_change { chat_upload_count([upload1]) }.and change {
|
|
|
|
|
UploadReference.where(upload_id: upload1.id).count
|
|
|
|
|
}.by(1)
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "can attach multiple uploads to a new message" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
upload_ids: [upload1.id, upload2.id],
|
|
|
|
|
)
|
2023-01-23 22:28:21 -05:00
|
|
|
|
}.to not_change { chat_upload_count([upload1, upload2]) }.and change {
|
|
|
|
|
UploadReference.where(upload_id: [upload1.id, upload2.id]).count
|
|
|
|
|
}.by(2)
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "filters out uploads that weren't uploaded by the user" do
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
upload_ids: [private_upload.id],
|
|
|
|
|
)
|
2023-01-23 22:28:21 -05:00
|
|
|
|
}.not_to change { chat_upload_count([private_upload]) }
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "doesn't attach uploads when `chat_allow_uploads` is false" do
|
|
|
|
|
SiteSetting.chat_allow_uploads = false
|
|
|
|
|
expect {
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Beep boop",
|
|
|
|
|
upload_ids: [upload1.id],
|
|
|
|
|
)
|
2023-01-23 22:28:21 -05:00
|
|
|
|
}.to not_change { chat_upload_count([upload1]) }.and not_change {
|
|
|
|
|
UploadReference.where(upload_id: upload1.id).count
|
|
|
|
|
}
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "destroys draft after message was created" do
|
|
|
|
|
ChatDraft.create!(user: user1, chat_channel: public_chat_channel, data: "{}")
|
|
|
|
|
|
|
|
|
|
expect do
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "Hi @#{user2.username}",
|
|
|
|
|
)
|
|
|
|
|
end.to change { ChatDraft.count }.by(-1)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "watched words" do
|
|
|
|
|
fab!(:watched_word) { Fabricate(:watched_word) }
|
|
|
|
|
|
|
|
|
|
it "errors when a blocked word is present" do
|
|
|
|
|
creator =
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user1,
|
|
|
|
|
content: "bad word - #{watched_word.word}",
|
|
|
|
|
)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to match(
|
|
|
|
|
I18n.t("contains_blocked_word", { word: watched_word.word }),
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "channel statuses" do
|
|
|
|
|
def create_message(user)
|
|
|
|
|
Chat::ChatMessageCreator.create(
|
|
|
|
|
chat_channel: public_chat_channel,
|
|
|
|
|
user: user,
|
|
|
|
|
content: "test message",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when channel is closed" do
|
|
|
|
|
before { public_chat_channel.update(status: :closed) }
|
|
|
|
|
|
|
|
|
|
it "errors when trying to create the message for non-staff" do
|
|
|
|
|
creator = create_message(user1)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to eq(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.channel_new_message_disallowed.closed"),
|
2022-11-02 09:41:30 -04:00
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not error when trying to create a message for staff" do
|
|
|
|
|
expect { create_message(admin1) }.to change { ChatMessage.count }.by(1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when channel is read_only" do
|
|
|
|
|
before { public_chat_channel.update(status: :read_only) }
|
|
|
|
|
|
|
|
|
|
it "errors when trying to create the message for all users" do
|
|
|
|
|
creator = create_message(user1)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to eq(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.channel_new_message_disallowed.read_only"),
|
2022-11-02 09:41:30 -04:00
|
|
|
|
)
|
|
|
|
|
creator = create_message(admin1)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to eq(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.channel_new_message_disallowed.read_only"),
|
2022-11-02 09:41:30 -04:00
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when channel is archived" do
|
|
|
|
|
before { public_chat_channel.update(status: :archived) }
|
|
|
|
|
|
|
|
|
|
it "errors when trying to create the message for all users" do
|
|
|
|
|
creator = create_message(user1)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to eq(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.channel_new_message_disallowed.archived"),
|
2022-11-02 09:41:30 -04:00
|
|
|
|
)
|
|
|
|
|
creator = create_message(admin1)
|
|
|
|
|
expect(creator.failed?).to eq(true)
|
|
|
|
|
expect(creator.error.message).to eq(
|
2023-02-20 04:31:02 -05:00
|
|
|
|
I18n.t("chat.errors.channel_new_message_disallowed.archived"),
|
2022-11-02 09:41:30 -04:00
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2023-01-23 22:28:21 -05:00
|
|
|
|
|
|
|
|
|
# TODO (martin) Remove this when we remove ChatUpload completely, 2023-04-01
|
|
|
|
|
def chat_upload_count(uploads)
|
|
|
|
|
DB.query_single(
|
|
|
|
|
"SELECT COUNT(*) FROM chat_uploads WHERE upload_id IN (#{uploads.map(&:id).join(",")})",
|
|
|
|
|
).first
|
|
|
|
|
end
|
2022-11-02 09:41:30 -04:00
|
|
|
|
end
|