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:
Andrei Prigorshnev
2023-03-07 19:07:11 +04:00
committed by GitHub
parent 1f88354c5e
commit fa543cda06
11 changed files with 278 additions and 84 deletions

View File

@ -140,16 +140,29 @@ describe Chat::ChatMessageCreator do
expect(events.map { _1[:event_name] }).to include(:chat_message_created)
end
it "creates mention notifications for public chat" do
expect {
it "creates mentions and mention notifications for public chat" do
message =
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 }
).chat_message
# 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
it "mentions are case insensitive" do
@ -225,58 +238,88 @@ describe Chat::ChatMessageCreator do
end
it "doesn't create mention notifications for users without a membership record" do
expect {
message =
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
user: user1,
content: "hello @#{user_without_memberships.username}",
)
}.not_to change { ChatMention.count }
).chat_message
mention = user_without_memberships.chat_mentions.where(chat_message: message).first
expect(mention.notification).to be_nil
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 {
message =
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
user: user1,
content: "hi @#{user2.username} @#{user3.username}",
)
}.not_to change { ChatMention.count }
).chat_message
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
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)
expect {
message =
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
user: user1,
content: "hi @#{user2.username}",
)
}.not_to change { ChatMention.count }
).chat_message
mention = user2.chat_mentions.where(chat_message: message).first
expect(mention).to be_nil
end
it "creates only mention notifications for users with access in private chat" do
expect {
message =
Chat::ChatMessageCreator.create(
chat_channel: direct_message_channel,
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 }
).chat_message
# 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
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 {
Chat::ChatMessageCreator.create(
chat_channel: direct_message_channel,
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 }
}.to change { user2.chat_mentions.count }.by(1).and change { user3.chat_mentions.count }.by(1)
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
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
it "does not create mentions for suspended users" do
it "creates mentions for suspended users" do
user2.update(suspended_till: Time.now + 10.years)
expect {
message =
Chat::ChatMessageCreator.create(
chat_channel: direct_message_channel,
user: user1,
content: "hello @#{user2.username}",
)
}.not_to change { user2.chat_mentions.count }
).chat_message
mention = user2.chat_mentions.where(chat_message: message).first
expect(mention).to be_present
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)
it "does not create mention notifications for suspended users" do
user2.update(suspended_till: Time.now + 10.years)
user2.user_option.update(ignore_channel_wide_mention: true)
expect {
message =
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
chat_channel: direct_message_channel,
user: user1,
content: "hi! @all",
)
}.to change { ChatMention.count }.by(3)
content: "hello @#{user2.username}",
).chat_message
mention = user2.chat_mentions.where(chat_message: message).first
expect(mention.notification).to be_nil
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)
context "when ignore_channel_wide_mention is enabled" do
before { user2.user_option.update(ignore_channel_wide_mention: true) }
expect {
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
user: user1,
content: "@here",
)
}.to change { ChatMention.count }.by(1)
it "when mentioning @all creates a mention without notification" do
message =
Chat::ChatMessageCreator.create(
chat_channel: public_chat_channel,
user: user1,
content: "hi! @all",
).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
describe "replies" do

View File

@ -150,17 +150,18 @@ describe Chat::ChatMessageUpdater do
}.not_to change { ChatMention.count }
end
it "doesn't create mentions for users without access" do
it "doesn't create mention notification for users without access" do
message = "ping"
chat_message = create_chat_message(user1, message, public_chat_channel)
expect {
Chat::ChatMessageUpdater.update(
guardian: guardian,
chat_message: chat_message,
new_content: message + " @#{user_without_memberships.username}",
)
}.not_to change { ChatMention.count }
Chat::ChatMessageUpdater.update(
guardian: guardian,
chat_message: chat_message,
new_content: message + " @#{user_without_memberships.username}",
)
mention = user_without_memberships.chat_mentions.where(chat_message: chat_message).first
expect(mention.notification).to be_nil
end
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
end
it "does not create new mentions in direct message for users who don't have access" do
chat_message = create_chat_message(user1, "ping nobody", @direct_message_channel)
expect {
Chat::ChatMessageUpdater.update(
guardian: guardian,
chat_message: chat_message,
new_content: "ping @#{admin1.username}",
)
}.not_to change { ChatMention.count }
it "doesn't create mention notification in direct message for users without access" do
message = create_chat_message(user1, "ping nobody", @direct_message_channel)
Chat::ChatMessageUpdater.update(
guardian: guardian,
chat_message: message,
new_content: "ping @#{admin1.username}",
)
mention = admin1.chat_mentions.where(chat_message: message).first
expect(mention.notification).to be_nil
end
describe "group mentions" do