DEV: Always create chat mention records (#20470)
Before this commit, we created a chat mention record only in case we wanted to send a notification about that mention to the user. Notifications were the only use case for the chat_mention db table. Now we want to use that table for other features, so we have to always create a chat_mention record.
This commit is contained in:
parent
1f88354c5e
commit
fa543cda06
|
@ -100,7 +100,7 @@ module Jobs
|
||||||
payload
|
payload
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_notification!(membership, notification_data)
|
def create_notification!(membership, notification_data, mention)
|
||||||
is_read = Chat::ChatNotifier.user_has_seen_message?(membership, @chat_message.id)
|
is_read = Chat::ChatNotifier.user_has_seen_message?(membership, @chat_message.id)
|
||||||
|
|
||||||
notification =
|
notification =
|
||||||
|
@ -111,15 +111,15 @@ module Jobs
|
||||||
data: notification_data.to_json,
|
data: notification_data.to_json,
|
||||||
read: is_read,
|
read: is_read,
|
||||||
)
|
)
|
||||||
ChatMention.create!(
|
|
||||||
notification: notification,
|
mention.update!(notification: notification)
|
||||||
user: membership.user,
|
|
||||||
chat_message: @chat_message,
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_notifications(membership, notification_data, os_payload)
|
def send_notifications(membership, notification_data, os_payload)
|
||||||
create_notification!(membership, notification_data)
|
mention = ChatMention.find_by(user: membership.user, chat_message: @chat_message)
|
||||||
|
return if mention.blank?
|
||||||
|
|
||||||
|
create_notification!(membership, notification_data, mention)
|
||||||
|
|
||||||
if !membership.desktop_notifications_never? && !membership.muted?
|
if !membership.desktop_notifications_never? && !membership.muted?
|
||||||
MessageBus.publish(
|
MessageBus.publish(
|
||||||
|
|
|
@ -226,8 +226,36 @@ class ChatMessage < ActiveRecord::Base
|
||||||
"/chat/c/-/#{self.chat_channel_id}/#{self.id}"
|
"/chat/c/-/#{self.chat_channel_id}/#{self.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_mentions(user_ids)
|
||||||
|
return if user_ids.empty?
|
||||||
|
|
||||||
|
now = Time.zone.now
|
||||||
|
mentions = []
|
||||||
|
User
|
||||||
|
.where(id: user_ids)
|
||||||
|
.find_each do |user|
|
||||||
|
mentions << { chat_message_id: self.id, user_id: user.id, created_at: now, updated_at: now }
|
||||||
|
end
|
||||||
|
|
||||||
|
ChatMention.insert_all(mentions)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_mentions(mentioned_user_ids)
|
||||||
|
old_mentions = chat_mentions.pluck(:user_id)
|
||||||
|
updated_mentions = mentioned_user_ids
|
||||||
|
mentioned_user_ids_to_drop = old_mentions - updated_mentions
|
||||||
|
mentioned_user_ids_to_add = updated_mentions - old_mentions
|
||||||
|
|
||||||
|
delete_mentions(mentioned_user_ids_to_drop)
|
||||||
|
create_mentions(mentioned_user_ids_to_add)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def delete_mentions(user_ids)
|
||||||
|
chat_mentions.where(user_id: user_ids).destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
def message_too_short?
|
def message_too_short?
|
||||||
message.length < SiteSetting.chat_minimum_message_length
|
message.length < SiteSetting.chat_minimum_message_length
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class MakeChatMentionNotificationIdNullable < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
change_column_null :chat_mentions, :notification_id, true
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,6 +18,18 @@ class Chat::ChatMessageMentions
|
||||||
:parsed_direct_mentions,
|
:parsed_direct_mentions,
|
||||||
:parsed_group_mentions
|
:parsed_group_mentions
|
||||||
|
|
||||||
|
def all_mentioned_users_ids
|
||||||
|
@all_mentioned_users_ids ||=
|
||||||
|
begin
|
||||||
|
user_ids = global_mentions.pluck(:id)
|
||||||
|
user_ids.concat(direct_mentions.pluck(:id))
|
||||||
|
user_ids.concat(group_mentions.pluck(:id))
|
||||||
|
user_ids.concat(here_mentions.pluck(:id))
|
||||||
|
user_ids.uniq!
|
||||||
|
user_ids
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def global_mentions
|
def global_mentions
|
||||||
return User.none unless @has_global_mention
|
return User.none unless @has_global_mention
|
||||||
channel_members.where.not(username_lower: @parsed_direct_mentions)
|
channel_members.where.not(username_lower: @parsed_direct_mentions)
|
||||||
|
@ -67,7 +79,6 @@ class Chat::ChatMessageMentions
|
||||||
.joins("LEFT OUTER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id")
|
.joins("LEFT OUTER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id")
|
||||||
.joins(:user_option)
|
.joins(:user_option)
|
||||||
.real
|
.real
|
||||||
.not_suspended
|
|
||||||
.where(user_options: { chat_enabled: true })
|
.where(user_options: { chat_enabled: true })
|
||||||
.where.not(username_lower: @message.user.username.downcase)
|
.where.not(username_lower: @message.user.username.downcase)
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,6 +66,10 @@ class Chat::ChatNotifier
|
||||||
### Public API
|
### Public API
|
||||||
|
|
||||||
def notify_new
|
def notify_new
|
||||||
|
if @mentions.all_mentioned_users_ids.present?
|
||||||
|
@chat_message.create_mentions(@mentions.all_mentioned_users_ids)
|
||||||
|
end
|
||||||
|
|
||||||
to_notify = list_users_to_notify
|
to_notify = list_users_to_notify
|
||||||
mentioned_user_ids = to_notify.extract!(:all_mentioned_user_ids)[:all_mentioned_user_ids]
|
mentioned_user_ids = to_notify.extract!(:all_mentioned_user_ids)[:all_mentioned_user_ids]
|
||||||
|
|
||||||
|
@ -82,6 +86,8 @@ class Chat::ChatNotifier
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_edit
|
def notify_edit
|
||||||
|
@chat_message.update_mentions(@mentions.all_mentioned_users_ids)
|
||||||
|
|
||||||
existing_notifications =
|
existing_notifications =
|
||||||
ChatMention.includes(:user, :notification).where(chat_message: @chat_message)
|
ChatMention.includes(:user, :notification).where(chat_message: @chat_message)
|
||||||
already_notified_user_ids = existing_notifications.map(&:user_id)
|
already_notified_user_ids = existing_notifications.map(&:user_id)
|
||||||
|
@ -139,6 +145,7 @@ class Chat::ChatNotifier
|
||||||
if has_all_mention && @chat_channel.allow_channel_wide_mentions && !skip
|
if has_all_mention && @chat_channel.allow_channel_wide_mentions && !skip
|
||||||
to_notify[:global_mentions] = @mentions
|
to_notify[:global_mentions] = @mentions
|
||||||
.global_mentions
|
.global_mentions
|
||||||
|
.not_suspended
|
||||||
.where(user_options: { ignore_channel_wide_mention: [false, nil] })
|
.where(user_options: { ignore_channel_wide_mention: [false, nil] })
|
||||||
.where.not(id: already_covered_ids)
|
.where.not(id: already_covered_ids)
|
||||||
.pluck(:id)
|
.pluck(:id)
|
||||||
|
@ -155,6 +162,7 @@ class Chat::ChatNotifier
|
||||||
if has_here_mention && @chat_channel.allow_channel_wide_mentions && !skip
|
if has_here_mention && @chat_channel.allow_channel_wide_mentions && !skip
|
||||||
to_notify[:here_mentions] = @mentions
|
to_notify[:here_mentions] = @mentions
|
||||||
.here_mentions
|
.here_mentions
|
||||||
|
.not_suspended
|
||||||
.where(user_options: { ignore_channel_wide_mention: [false, nil] })
|
.where(user_options: { ignore_channel_wide_mention: [false, nil] })
|
||||||
.where.not(id: already_covered_ids)
|
.where.not(id: already_covered_ids)
|
||||||
.pluck(:id)
|
.pluck(:id)
|
||||||
|
@ -192,7 +200,7 @@ class Chat::ChatNotifier
|
||||||
if skip
|
if skip
|
||||||
direct_mentions = []
|
direct_mentions = []
|
||||||
else
|
else
|
||||||
direct_mentions = @mentions.direct_mentions.where.not(id: already_covered_ids)
|
direct_mentions = @mentions.direct_mentions.not_suspended.where.not(id: already_covered_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
grouped = group_users_to_notify(direct_mentions)
|
grouped = group_users_to_notify(direct_mentions)
|
||||||
|
@ -209,6 +217,7 @@ class Chat::ChatNotifier
|
||||||
reached_by_group =
|
reached_by_group =
|
||||||
@mentions
|
@mentions
|
||||||
.group_mentions
|
.group_mentions
|
||||||
|
.not_suspended
|
||||||
.where("user_count <= ?", SiteSetting.max_users_notified_per_group_mention)
|
.where("user_count <= ?", SiteSetting.max_users_notified_per_group_mention)
|
||||||
.where.not(id: already_covered_ids)
|
.where.not(id: already_covered_ids)
|
||||||
|
|
||||||
|
|
|
@ -140,16 +140,29 @@ describe Chat::ChatMessageCreator do
|
||||||
expect(events.map { _1[:event_name] }).to include(:chat_message_created)
|
expect(events.map { _1[:event_name] }).to include(:chat_message_created)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates mention notifications for public chat" do
|
it "creates mentions and mention notifications for public chat" do
|
||||||
expect {
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: public_chat_channel,
|
chat_channel: public_chat_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content:
|
content:
|
||||||
"this is a @#{user1.username} message with @system @mentions @#{user2.username} and @#{user3.username}",
|
"this is a @#{user1.username} message with @system @mentions @#{user2.username} and @#{user3.username}",
|
||||||
)
|
).chat_message
|
||||||
# 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 }
|
# a mention for the user himself wasn't created
|
||||||
|
user1_mention = user1.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user1_mention).to be_nil
|
||||||
|
|
||||||
|
system_user_mention = Discourse.system_user.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(system_user_mention).to be_nil
|
||||||
|
|
||||||
|
user2_mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user2_mention).to be_present
|
||||||
|
expect(user2_mention.notification).to be_present
|
||||||
|
|
||||||
|
user3_mention = user3.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user3_mention).to be_present
|
||||||
|
expect(user3_mention.notification).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it "mentions are case insensitive" do
|
it "mentions are case insensitive" do
|
||||||
|
@ -225,58 +238,88 @@ describe Chat::ChatMessageCreator do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't create mention notifications for users without a membership record" do
|
it "doesn't create mention notifications for users without a membership record" do
|
||||||
expect {
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: public_chat_channel,
|
chat_channel: public_chat_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hello @#{user_without_memberships.username}",
|
content: "hello @#{user_without_memberships.username}",
|
||||||
)
|
).chat_message
|
||||||
}.not_to change { ChatMention.count }
|
|
||||||
|
mention = user_without_memberships.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't create mention notifications for users who cannot chat" do
|
it "doesn't create mention notifications for users who cannot chat" do
|
||||||
new_group = Group.create
|
new_group = Group.create
|
||||||
SiteSetting.chat_allowed_groups = new_group.id
|
SiteSetting.chat_allowed_groups = new_group.id
|
||||||
expect {
|
|
||||||
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: public_chat_channel,
|
chat_channel: public_chat_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hi @#{user2.username} @#{user3.username}",
|
content: "hi @#{user2.username} @#{user3.username}",
|
||||||
)
|
).chat_message
|
||||||
}.not_to change { ChatMention.count }
|
|
||||||
|
user2_mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user2_mention.notification).to be_nil
|
||||||
|
|
||||||
|
user3_mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user3_mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't create mention notifications for users with chat disabled" do
|
it "doesn't create mentions for users with chat disabled" do
|
||||||
user2.user_option.update(chat_enabled: false)
|
user2.user_option.update(chat_enabled: false)
|
||||||
expect {
|
|
||||||
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: public_chat_channel,
|
chat_channel: public_chat_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hi @#{user2.username}",
|
content: "hi @#{user2.username}",
|
||||||
)
|
).chat_message
|
||||||
}.not_to change { ChatMention.count }
|
|
||||||
|
mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates only mention notifications for users with access in private chat" do
|
it "creates only mention notifications for users with access in private chat" do
|
||||||
expect {
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: direct_message_channel,
|
chat_channel: direct_message_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hello there @#{user2.username} and @#{user3.username}",
|
content: "hello there @#{user2.username} and @#{user3.username}",
|
||||||
)
|
).chat_message
|
||||||
# Only user2 should be notified
|
|
||||||
}.to change { user2.chat_mentions.count }.by(1).and not_change { user3.chat_mentions.count }
|
# Only user2 should be notified
|
||||||
|
user2_mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user2_mention.notification).to be_present
|
||||||
|
|
||||||
|
user3_mention = user3.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user3_mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a mention notifications for group users that are participating in private chat" do
|
it "creates a mention for group users even if they're not participating in private chat" do
|
||||||
expect {
|
expect {
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: direct_message_channel,
|
chat_channel: direct_message_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hello there @#{user_group.name}",
|
content: "hello there @#{user_group.name}",
|
||||||
)
|
)
|
||||||
# Only user2 should be notified
|
}.to change { user2.chat_mentions.count }.by(1).and change { user3.chat_mentions.count }.by(1)
|
||||||
}.to change { user2.chat_mentions.count }.by(1).and not_change { user3.chat_mentions.count }
|
end
|
||||||
|
|
||||||
|
it "creates a mention notifications only for group users that are participating in private chat" do
|
||||||
|
message =
|
||||||
|
Chat::ChatMessageCreator.create(
|
||||||
|
chat_channel: direct_message_channel,
|
||||||
|
user: user1,
|
||||||
|
content: "hello there @#{user_group.name}",
|
||||||
|
).chat_message
|
||||||
|
|
||||||
|
user2_mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user2_mention.notification).to be_present
|
||||||
|
|
||||||
|
user3_mention = user3.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(user3_mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "publishes inaccessible mentions when user isn't aren't a part of the channel" do
|
it "publishes inaccessible mentions when user isn't aren't a part of the channel" do
|
||||||
|
@ -307,51 +350,64 @@ describe Chat::ChatMessageCreator do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create mentions for suspended users" do
|
it "creates mentions for suspended users" do
|
||||||
user2.update(suspended_till: Time.now + 10.years)
|
user2.update(suspended_till: Time.now + 10.years)
|
||||||
expect {
|
|
||||||
|
message =
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: direct_message_channel,
|
chat_channel: direct_message_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hello @#{user2.username}",
|
content: "hello @#{user2.username}",
|
||||||
)
|
).chat_message
|
||||||
}.not_to change { user2.chat_mentions.count }
|
|
||||||
|
mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create @all mentions for users when ignore_channel_wide_mention is enabled" do
|
it "does not create mention notifications for suspended users" do
|
||||||
expect {
|
user2.update(suspended_till: Time.now + 10.years)
|
||||||
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)
|
message =
|
||||||
expect {
|
|
||||||
Chat::ChatMessageCreator.create(
|
Chat::ChatMessageCreator.create(
|
||||||
chat_channel: public_chat_channel,
|
chat_channel: direct_message_channel,
|
||||||
user: user1,
|
user: user1,
|
||||||
content: "hi! @all",
|
content: "hello @#{user2.username}",
|
||||||
)
|
).chat_message
|
||||||
}.to change { ChatMention.count }.by(3)
|
|
||||||
|
mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create @here mentions for users when ignore_channel_wide_mention is enabled" do
|
context "when ignore_channel_wide_mention is enabled" do
|
||||||
admin1.update(last_seen_at: 1.year.ago)
|
before { user2.user_option.update(ignore_channel_wide_mention: true) }
|
||||||
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 {
|
it "when mentioning @all creates a mention without notification" do
|
||||||
Chat::ChatMessageCreator.create(
|
message =
|
||||||
chat_channel: public_chat_channel,
|
Chat::ChatMessageCreator.create(
|
||||||
user: user1,
|
chat_channel: public_chat_channel,
|
||||||
content: "@here",
|
user: user1,
|
||||||
)
|
content: "hi! @all",
|
||||||
}.to change { ChatMention.count }.by(1)
|
).chat_message
|
||||||
|
|
||||||
|
mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention).to be_present
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when mentioning @here creates a mention without notification" do
|
||||||
|
user2.update(last_seen_at: Time.now)
|
||||||
|
|
||||||
|
message =
|
||||||
|
Chat::ChatMessageCreator.create(
|
||||||
|
chat_channel: public_chat_channel,
|
||||||
|
user: user1,
|
||||||
|
content: "@here",
|
||||||
|
).chat_message
|
||||||
|
|
||||||
|
mention = user2.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention).to be_present
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "replies" do
|
describe "replies" do
|
||||||
|
|
|
@ -150,17 +150,18 @@ describe Chat::ChatMessageUpdater do
|
||||||
}.not_to change { ChatMention.count }
|
}.not_to change { ChatMention.count }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't create mentions for users without access" do
|
it "doesn't create mention notification for users without access" do
|
||||||
message = "ping"
|
message = "ping"
|
||||||
chat_message = create_chat_message(user1, message, public_chat_channel)
|
chat_message = create_chat_message(user1, message, public_chat_channel)
|
||||||
|
|
||||||
expect {
|
Chat::ChatMessageUpdater.update(
|
||||||
Chat::ChatMessageUpdater.update(
|
guardian: guardian,
|
||||||
guardian: guardian,
|
chat_message: chat_message,
|
||||||
chat_message: chat_message,
|
new_content: message + " @#{user_without_memberships.username}",
|
||||||
new_content: message + " @#{user_without_memberships.username}",
|
)
|
||||||
)
|
|
||||||
}.not_to change { ChatMention.count }
|
mention = user_without_memberships.chat_mentions.where(chat_message: chat_message).first
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "destroys mention notifications that should be removed" do
|
it "destroys mention notifications that should be removed" do
|
||||||
|
@ -189,15 +190,17 @@ describe Chat::ChatMessageUpdater do
|
||||||
expect(user4.chat_mentions.where(chat_message: chat_message)).to be_present
|
expect(user4.chat_mentions.where(chat_message: chat_message)).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create new mentions in direct message for users who don't have access" do
|
it "doesn't create mention notification in direct message for users without access" do
|
||||||
chat_message = create_chat_message(user1, "ping nobody", @direct_message_channel)
|
message = create_chat_message(user1, "ping nobody", @direct_message_channel)
|
||||||
expect {
|
|
||||||
Chat::ChatMessageUpdater.update(
|
Chat::ChatMessageUpdater.update(
|
||||||
guardian: guardian,
|
guardian: guardian,
|
||||||
chat_message: chat_message,
|
chat_message: message,
|
||||||
new_content: "ping @#{admin1.username}",
|
new_content: "ping @#{admin1.username}",
|
||||||
)
|
)
|
||||||
}.not_to change { ChatMention.count }
|
|
||||||
|
mention = admin1.chat_mentions.where(chat_message: message).first
|
||||||
|
expect(mention.notification).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "group mentions" do
|
describe "group mentions" do
|
||||||
|
|
|
@ -21,8 +21,11 @@ describe Jobs::ChatNotifyMentioned do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_chat_message(channel: public_channel, user: user_1)
|
def create_chat_message(channel: public_channel, author: user_1, mentioned_user: user_2)
|
||||||
Fabricate(:chat_message, chat_channel: channel, user: user, created_at: 10.minutes.ago)
|
message =
|
||||||
|
Fabricate(:chat_message, chat_channel: channel, user: author, created_at: 10.minutes.ago)
|
||||||
|
Fabricate(:chat_mention, chat_message: message, user: mentioned_user)
|
||||||
|
message
|
||||||
end
|
end
|
||||||
|
|
||||||
def track_desktop_notification(
|
def track_desktop_notification(
|
||||||
|
|
|
@ -139,7 +139,18 @@ RSpec.describe Chat::ChatMessageMentions do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns an empty list if no group was mentioned" do
|
it "returns an empty list if no group was mentioned" do
|
||||||
message = create_message("not mentioning anybody")
|
message = create_message("not mentioning anyone")
|
||||||
|
|
||||||
|
mentions = Chat::ChatMessageMentions.new(message)
|
||||||
|
result = mentions.group_mentions.pluck(:username)
|
||||||
|
|
||||||
|
expect(result).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns an empty list when mentioning an unmentionable group" do
|
||||||
|
group1.mentionable_level = Group::ALIAS_LEVELS[:nobody]
|
||||||
|
group1.save!
|
||||||
|
message = create_message("mentioning @#{group1.name}")
|
||||||
|
|
||||||
mentions = Chat::ChatMessageMentions.new(message)
|
mentions = Chat::ChatMessageMentions.new(message)
|
||||||
result = mentions.group_mentions.pluck(:username)
|
result = mentions.group_mentions.pluck(:username)
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe Chat::ChatNotifier do
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_cooked_msg(message_body, user, chat_channel: channel)
|
def build_cooked_msg(message_body, user, chat_channel: channel)
|
||||||
ChatMessage.new(
|
ChatMessage.create(
|
||||||
chat_channel: chat_channel,
|
chat_channel: chat_channel,
|
||||||
user: user,
|
user: user,
|
||||||
message: message_body,
|
message: message_body,
|
||||||
|
|
|
@ -570,6 +570,68 @@ describe ChatMessage do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#create_mentions" do
|
||||||
|
fab!(:message) { Fabricate(:chat_message) }
|
||||||
|
fab!(:user1) { Fabricate(:user) }
|
||||||
|
fab!(:user2) { Fabricate(:user) }
|
||||||
|
|
||||||
|
it "creates mentions for passed user ids" do
|
||||||
|
mentioned_user_ids = [user1.id, user2.id]
|
||||||
|
message.create_mentions(mentioned_user_ids)
|
||||||
|
message.reload
|
||||||
|
|
||||||
|
expect(message.chat_mentions.pluck(:user_id)).to match_array(mentioned_user_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "ignores duplicates in passed user ids" do
|
||||||
|
mentioned_user_ids = [user1.id, user1.id, user1.id, user1.id, user1.id]
|
||||||
|
message.create_mentions(mentioned_user_ids)
|
||||||
|
message.reload
|
||||||
|
|
||||||
|
expect(message.chat_mentions.pluck(:user_id)).to contain_exactly(user1.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_mentions" do
|
||||||
|
fab!(:message) { Fabricate(:chat_message) }
|
||||||
|
fab!(:user1) { Fabricate(:user) }
|
||||||
|
fab!(:user2) { Fabricate(:user) }
|
||||||
|
fab!(:user3) { Fabricate(:user) }
|
||||||
|
fab!(:user4) { Fabricate(:user) }
|
||||||
|
let(:already_mentioned) { [user1.id, user2.id] }
|
||||||
|
|
||||||
|
before { message.create_mentions(already_mentioned) }
|
||||||
|
|
||||||
|
it "creates newly added mentions" do
|
||||||
|
existing_mention_ids = message.chat_mentions.pluck(:id)
|
||||||
|
|
||||||
|
mentioned_user_ids = [*already_mentioned, user3.id, user4.id]
|
||||||
|
message.update_mentions(mentioned_user_ids)
|
||||||
|
message.reload
|
||||||
|
|
||||||
|
expect(message.chat_mentions.pluck(:user_id)).to match_array(mentioned_user_ids)
|
||||||
|
expect(message.chat_mentions.pluck(:id)).to include(*existing_mention_ids) # existing mentions weren't recreated
|
||||||
|
end
|
||||||
|
|
||||||
|
it "drops removed mentions" do
|
||||||
|
message.update_mentions([user1.id]) # user 2 is not mentioned anymore
|
||||||
|
message.reload
|
||||||
|
|
||||||
|
expect(message.chat_mentions.pluck(:user_id)).to contain_exactly(user1.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "changes nothing if passed mentions are identical to existing mentions" do
|
||||||
|
existing_mention_ids = message.chat_mentions.pluck(:id)
|
||||||
|
|
||||||
|
mentioned_user_ids = [*already_mentioned]
|
||||||
|
message.update_mentions(mentioned_user_ids)
|
||||||
|
message.reload
|
||||||
|
|
||||||
|
expect(message.chat_mentions.pluck(:user_id)).to match_array(mentioned_user_ids)
|
||||||
|
expect(message.chat_mentions.pluck(:id)).to include(*existing_mention_ids) # the mentions weren't recreated
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# TODO (martin) Remove this when we remove ChatUpload completely, 2023-04-01
|
# TODO (martin) Remove this when we remove ChatUpload completely, 2023-04-01
|
||||||
def chat_upload_count(uploads = nil)
|
def chat_upload_count(uploads = nil)
|
||||||
return DB.query_single("SELECT COUNT(*) FROM chat_uploads").first if !uploads
|
return DB.query_single("SELECT COUNT(*) FROM chat_uploads").first if !uploads
|
||||||
|
|
Loading…
Reference in New Issue