mirror of
https://github.com/discourse/discourse.git
synced 2025-03-05 10:49:24 +00:00
This commit automatically ensures that category channels have slugs when they are created or updated based on the channel name, category name, or existing slug. The behaviour has been copied from the Category model. We also include a backfill here with a simplified version of Slug.for with deduplication to fill the slugs for already created Category chat channels. The channel slug is also now used for chat notifications, and for the UI and navigation for chat. `slugifyChannel` is still used, but now does the following fallback: * Uses channel.slug if it is present * Uses channel.escapedTitle if it is present * Uses channel.title if it is present In future we may want to remove this altogether and always rely on the slug being present, but this is currently not possible because we are not generating slugs for DM channels at this point.
482 lines
16 KiB
Ruby
482 lines
16 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
describe Jobs::ChatNotifyMentioned do
|
|
fab!(:user_1) { Fabricate(:user) }
|
|
fab!(:user_2) { Fabricate(:user) }
|
|
fab!(:public_channel) { Fabricate(:category_channel) }
|
|
|
|
before do
|
|
Group.refresh_automatic_groups!
|
|
user_1.reload
|
|
user_2.reload
|
|
|
|
@chat_group = Fabricate(:group, users: [user_1, user_2])
|
|
@personal_chat_channel =
|
|
Chat::DirectMessageChannelCreator.create!(acting_user: user_1, target_users: [user_1, user_2])
|
|
|
|
[user_1, user_2].each do |u|
|
|
Fabricate(:user_chat_channel_membership, chat_channel: public_channel, user: u)
|
|
end
|
|
end
|
|
|
|
def create_chat_message(channel: public_channel, user: user_1)
|
|
Fabricate(:chat_message, chat_channel: channel, user: user, created_at: 10.minutes.ago)
|
|
end
|
|
|
|
def track_desktop_notification(
|
|
user: user_2,
|
|
message:,
|
|
to_notify_ids_map:,
|
|
already_notified_user_ids: []
|
|
)
|
|
MessageBus
|
|
.track_publish("/chat/notification-alert/#{user.id}") do
|
|
subject.execute(
|
|
chat_message_id: message.id,
|
|
timestamp: message.created_at,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
already_notified_user_ids: already_notified_user_ids,
|
|
)
|
|
end
|
|
.first
|
|
end
|
|
|
|
def track_core_notification(user: user_2, message:, to_notify_ids_map:)
|
|
subject.execute(
|
|
chat_message_id: message.id,
|
|
timestamp: message.created_at,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
)
|
|
|
|
Notification.where(user: user, notification_type: Notification.types[:chat_mention]).last
|
|
end
|
|
|
|
describe "scenarios where we should skip sending notifications" do
|
|
let(:to_notify_ids_map) { { here_mentions: [user_2.id] } }
|
|
|
|
it "does nothing if there is a newer version of the message" do
|
|
message = create_chat_message
|
|
Fabricate(:chat_message_revision, chat_message: message, old_message: "a", new_message: "b")
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
expect(desktop_notification).to be_nil
|
|
|
|
created_notification =
|
|
Notification.where(user: user_2, notification_type: Notification.types[:chat_mention]).last
|
|
expect(created_notification).to be_nil
|
|
end
|
|
|
|
it "does nothing when user is not following the channel" do
|
|
message = create_chat_message
|
|
|
|
UserChatChannelMembership.where(chat_channel: public_channel, user: user_2).update!(
|
|
following: false,
|
|
)
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
expect(desktop_notification).to be_nil
|
|
|
|
created_notification =
|
|
Notification.where(user: user_2, notification_type: Notification.types[:chat_mention]).last
|
|
expect(created_notification).to be_nil
|
|
end
|
|
|
|
it "does nothing when user doesn't have a membership record" do
|
|
message = create_chat_message
|
|
|
|
UserChatChannelMembership.find_by(chat_channel: public_channel, user: user_2).destroy!
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
expect(desktop_notification).to be_nil
|
|
|
|
created_notification =
|
|
Notification.where(user: user_2, notification_type: Notification.types[:chat_mention]).last
|
|
expect(created_notification).to be_nil
|
|
end
|
|
|
|
it "does nothing if user is included in the already_notified_user_ids" do
|
|
message = create_chat_message
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(
|
|
message: message,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
already_notified_user_ids: [user_2.id],
|
|
)
|
|
expect(desktop_notification).to be_nil
|
|
|
|
created_notification =
|
|
Notification.where(user: user_2, notification_type: Notification.types[:chat_mention]).last
|
|
expect(created_notification).to be_nil
|
|
end
|
|
|
|
it "does nothing if user is not participating in a private channel" do
|
|
user_3 = Fabricate(:user)
|
|
@chat_group.add(user_3)
|
|
to_notify_map = { direct_mentions: [user_3.id] }
|
|
|
|
message = create_chat_message(channel: @personal_chat_channel)
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_map)
|
|
expect(desktop_notification).to be_nil
|
|
|
|
created_notification =
|
|
Notification.where(user: user_3, notification_type: Notification.types[:chat_mention]).last
|
|
expect(created_notification).to be_nil
|
|
end
|
|
|
|
it "skips desktop notifications based on user preferences" do
|
|
message = create_chat_message
|
|
UserChatChannelMembership.find_by(chat_channel: public_channel, user: user_2).update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:never],
|
|
)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification).to be_nil
|
|
end
|
|
|
|
it "skips push notifications based on user preferences" do
|
|
message = create_chat_message
|
|
UserChatChannelMembership.find_by(chat_channel: public_channel, user: user_2).update!(
|
|
mobile_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:never],
|
|
)
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
subject.execute(
|
|
chat_message_id: message.id,
|
|
timestamp: message.created_at,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
)
|
|
end
|
|
|
|
it "skips desktop notifications based on user muting preferences" do
|
|
message = create_chat_message
|
|
UserChatChannelMembership.find_by(chat_channel: public_channel, user: user_2).update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
muted: true,
|
|
)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification).to be_nil
|
|
end
|
|
|
|
it "skips push notifications based on user muting preferences" do
|
|
message = create_chat_message
|
|
UserChatChannelMembership.find_by(chat_channel: public_channel, user: user_2).update!(
|
|
mobile_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
muted: true,
|
|
)
|
|
|
|
PostAlerter.expects(:push_notification).never
|
|
|
|
subject.execute(
|
|
chat_message_id: message.id,
|
|
timestamp: message.created_at,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
)
|
|
end
|
|
end
|
|
|
|
shared_examples "creates different notifications with basic data" do
|
|
let(:expected_channel_title) { public_channel.title(user_2) }
|
|
|
|
it "works for desktop notifications" do
|
|
message = create_chat_message
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification).to be_present
|
|
expect(desktop_notification.data[:notification_type]).to eq(Notification.types[:chat_mention])
|
|
expect(desktop_notification.data[:username]).to eq(user_1.username)
|
|
expect(desktop_notification.data[:tag]).to eq(
|
|
Chat::ChatNotifier.push_notification_tag(:mention, public_channel.id),
|
|
)
|
|
expect(desktop_notification.data[:excerpt]).to eq(message.push_notification_excerpt)
|
|
expect(desktop_notification.data[:post_url]).to eq(
|
|
"/chat/channel/#{public_channel.id}/#{public_channel.slug}?messageId=#{message.id}",
|
|
)
|
|
end
|
|
|
|
it "works for push notifications" do
|
|
message = create_chat_message
|
|
|
|
PostAlerter.expects(:push_notification).with(
|
|
user_2,
|
|
{
|
|
notification_type: Notification.types[:chat_mention],
|
|
username: user_1.username,
|
|
tag: Chat::ChatNotifier.push_notification_tag(:mention, public_channel.id),
|
|
excerpt: message.push_notification_excerpt,
|
|
post_url:
|
|
"/chat/channel/#{public_channel.id}/#{public_channel.slug}?messageId=#{message.id}",
|
|
translated_title: payload_translated_title,
|
|
},
|
|
)
|
|
|
|
subject.execute(
|
|
chat_message_id: message.id,
|
|
timestamp: message.created_at,
|
|
to_notify_ids_map: to_notify_ids_map,
|
|
)
|
|
end
|
|
|
|
it "works for core notifications" do
|
|
message = create_chat_message
|
|
|
|
created_notification =
|
|
track_core_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(created_notification).to be_present
|
|
expect(created_notification.high_priority).to eq(true)
|
|
expect(created_notification.read).to eq(false)
|
|
|
|
data_hash = created_notification.data_hash
|
|
|
|
expect(data_hash[:chat_message_id]).to eq(message.id)
|
|
expect(data_hash[:chat_channel_id]).to eq(public_channel.id)
|
|
expect(data_hash[:mentioned_by_username]).to eq(user_1.username)
|
|
expect(data_hash[:is_direct_message_channel]).to eq(false)
|
|
expect(data_hash[:chat_channel_title]).to eq(expected_channel_title)
|
|
expect(data_hash[:chat_channel_slug]).to eq(public_channel.slug)
|
|
|
|
chat_mention =
|
|
ChatMention.where(notification: created_notification, user: user_2, chat_message: message)
|
|
expect(chat_mention).to be_present
|
|
end
|
|
end
|
|
|
|
describe "#execute" do
|
|
describe "global mention notifications" do
|
|
let(:to_notify_ids_map) { { global_mentions: [user_2.id] } }
|
|
|
|
let(:payload_translated_title) do
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@all",
|
|
channel: public_channel.title(user_2),
|
|
)
|
|
end
|
|
|
|
include_examples "creates different notifications with basic data"
|
|
|
|
it "includes global mention specific data to core notifications" do
|
|
message = create_chat_message
|
|
|
|
created_notification =
|
|
track_core_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
data_hash = created_notification.data_hash
|
|
|
|
expect(data_hash[:identifier]).to eq("all")
|
|
end
|
|
|
|
it "includes global mention specific data to desktop notifications" do
|
|
message = create_chat_message
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(payload_translated_title)
|
|
end
|
|
|
|
context "with private channels" do
|
|
it "users a different translated title" do
|
|
message = create_chat_message(channel: @personal_chat_channel)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expected_title =
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.direct_message_chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@all",
|
|
)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(expected_title)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "here mention notifications" do
|
|
let(:to_notify_ids_map) { { here_mentions: [user_2.id] } }
|
|
|
|
let(:payload_translated_title) do
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@here",
|
|
channel: public_channel.title(user_2),
|
|
)
|
|
end
|
|
|
|
include_examples "creates different notifications with basic data"
|
|
|
|
it "includes here mention specific data to core notifications" do
|
|
message = create_chat_message
|
|
|
|
created_notification =
|
|
track_core_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
data_hash = created_notification.data_hash
|
|
|
|
expect(data_hash[:identifier]).to eq("here")
|
|
end
|
|
|
|
it "includes here mention specific data to desktop notifications" do
|
|
message = create_chat_message
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(payload_translated_title)
|
|
end
|
|
|
|
context "with private channels" do
|
|
it "users a different translated title" do
|
|
message = create_chat_message(channel: @personal_chat_channel)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expected_title =
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.direct_message_chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@here",
|
|
)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(expected_title)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "direct mention notifications" do
|
|
let(:to_notify_ids_map) { { direct_mentions: [user_2.id] } }
|
|
|
|
let(:payload_translated_title) do
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.chat_mention.direct",
|
|
username: user_1.username,
|
|
identifier: "",
|
|
channel: public_channel.title(user_2),
|
|
)
|
|
end
|
|
|
|
include_examples "creates different notifications with basic data"
|
|
|
|
it "includes here mention specific data to core notifications" do
|
|
message = create_chat_message
|
|
|
|
created_notification =
|
|
track_core_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
data_hash = created_notification.data_hash
|
|
|
|
expect(data_hash[:identifier]).to be_nil
|
|
end
|
|
|
|
it "includes here mention specific data to desktop notifications" do
|
|
message = create_chat_message
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(payload_translated_title)
|
|
end
|
|
|
|
context "with private channels" do
|
|
it "users a different translated title" do
|
|
message = create_chat_message(channel: @personal_chat_channel)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expected_title =
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.direct_message_chat_mention.direct",
|
|
username: user_1.username,
|
|
identifier: "",
|
|
)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(expected_title)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "group mentions" do
|
|
let(:to_notify_ids_map) { { @chat_group.name.to_sym => [user_2.id] } }
|
|
|
|
let(:payload_translated_title) do
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@#{@chat_group.name}",
|
|
channel: public_channel.title(user_2),
|
|
)
|
|
end
|
|
|
|
include_examples "creates different notifications with basic data"
|
|
|
|
it "includes here mention specific data to core notifications" do
|
|
message = create_chat_message
|
|
|
|
created_notification =
|
|
track_core_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
data_hash = created_notification.data_hash
|
|
|
|
expect(data_hash[:identifier]).to eq(@chat_group.name)
|
|
expect(data_hash[:is_group_mention]).to eq(true)
|
|
end
|
|
|
|
it "includes here mention specific data to desktop notifications" do
|
|
message = create_chat_message
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(payload_translated_title)
|
|
end
|
|
|
|
context "with private channels" do
|
|
it "users a different translated title" do
|
|
message = create_chat_message(channel: @personal_chat_channel)
|
|
|
|
desktop_notification =
|
|
track_desktop_notification(message: message, to_notify_ids_map: to_notify_ids_map)
|
|
|
|
expected_title =
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.direct_message_chat_mention.other_type",
|
|
username: user_1.username,
|
|
identifier: "@#{@chat_group.name}",
|
|
)
|
|
|
|
expect(desktop_notification.data[:translated_title]).to eq(expected_title)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|