mirror of
https://github.com/discourse/discourse.git
synced 2025-03-04 02:09:30 +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.
311 lines
10 KiB
Ruby
311 lines
10 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe Jobs::ChatNotifyWatching do
|
|
fab!(:user1) { Fabricate(:user) }
|
|
fab!(:user2) { Fabricate(:user) }
|
|
fab!(:user3) { Fabricate(:user) }
|
|
fab!(:group) { Fabricate(:group) }
|
|
let(:except_user_ids) { [] }
|
|
|
|
before do
|
|
SiteSetting.chat_enabled = true
|
|
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
|
end
|
|
|
|
def run_job
|
|
described_class.new.execute(chat_message_id: message.id, except_user_ids: except_user_ids)
|
|
end
|
|
|
|
def notification_messages_for(user)
|
|
MessageBus
|
|
.track_publish { run_job }
|
|
.filter { |m| m.channel == "/chat/notification-alert/#{user.id}" }
|
|
end
|
|
|
|
context "for a category channel" do
|
|
fab!(:channel) { Fabricate(:category_channel) }
|
|
fab!(:membership1) do
|
|
Fabricate(:user_chat_channel_membership, user: user1, chat_channel: channel)
|
|
end
|
|
fab!(:membership2) do
|
|
Fabricate(:user_chat_channel_membership, user: user2, chat_channel: channel)
|
|
end
|
|
fab!(:membership3) do
|
|
Fabricate(:user_chat_channel_membership, user: user3, chat_channel: channel)
|
|
end
|
|
fab!(:message) do
|
|
Fabricate(:chat_message, chat_channel: channel, user: user1, message: "this is a new message")
|
|
end
|
|
|
|
before do
|
|
membership2.update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
)
|
|
end
|
|
|
|
it "sends a desktop notification" do
|
|
messages = notification_messages_for(user2)
|
|
|
|
expect(messages.first.data).to include(
|
|
{
|
|
username: user1.username,
|
|
notification_type: Notification.types[:chat_message],
|
|
post_url: channel.relative_url,
|
|
translated_title:
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.new_chat_message",
|
|
{ username: user1.username, channel: channel.title(user2) },
|
|
),
|
|
tag: Chat::ChatNotifier.push_notification_tag(:message, channel.id),
|
|
excerpt: message.message,
|
|
},
|
|
)
|
|
end
|
|
|
|
context "when the channel is muted via membership preferences" do
|
|
before { membership2.update!(muted: true) }
|
|
|
|
it "does not send a desktop or mobile notification" do
|
|
PostAlerter.expects(:push_notification).never
|
|
messages = notification_messages_for(user2)
|
|
expect(messages).to be_empty
|
|
end
|
|
end
|
|
|
|
context "when mobile_notification_level is always and desktop_notification_level is none" do
|
|
before do
|
|
membership2.update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:never],
|
|
mobile_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
)
|
|
end
|
|
|
|
it "sends a mobile notification" do
|
|
PostAlerter.expects(:push_notification).with(
|
|
user2,
|
|
has_entries(
|
|
{
|
|
username: user1.username,
|
|
notification_type: Notification.types[:chat_message],
|
|
post_url: channel.relative_url,
|
|
translated_title:
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.new_chat_message",
|
|
{ username: user1.username, channel: channel.title(user2) },
|
|
),
|
|
tag: Chat::ChatNotifier.push_notification_tag(:message, channel.id),
|
|
excerpt: message.message,
|
|
},
|
|
),
|
|
)
|
|
messages = notification_messages_for(user2)
|
|
expect(messages.length).to be_zero
|
|
end
|
|
|
|
context "when the channel is muted via membership preferences" do
|
|
before { membership2.update!(muted: true) }
|
|
|
|
it "does not send a desktop or mobile notification" do
|
|
PostAlerter.expects(:push_notification).never
|
|
messages = notification_messages_for(user2)
|
|
expect(messages).to be_empty
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the target user cannot chat" do
|
|
before { SiteSetting.chat_allowed_groups = group.id }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user cannot see the chat channel" do
|
|
before { channel.update!(chatable: Fabricate(:private_category, group: group)) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user has seen the message already" do
|
|
before { membership2.update!(last_read_message_id: message.id) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is online via presence channel" do
|
|
before { PresenceChannel.any_instance.expects(:user_ids).returns([user2.id]) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is suspended" do
|
|
before { user2.update!(suspended_till: 1.year.from_now) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is inside the except_user_ids array" do
|
|
let(:except_user_ids) { [user2.id] }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
end
|
|
|
|
context "for a direct message channel" do
|
|
fab!(:channel) { Fabricate(:direct_message_channel, users: [user1, user2, user3]) }
|
|
fab!(:membership1) do
|
|
Fabricate(:user_chat_channel_membership, user: user1, chat_channel: channel)
|
|
end
|
|
fab!(:membership2) do
|
|
Fabricate(:user_chat_channel_membership, user: user2, chat_channel: channel)
|
|
end
|
|
fab!(:membership3) do
|
|
Fabricate(:user_chat_channel_membership, user: user3, chat_channel: channel)
|
|
end
|
|
fab!(:message) { Fabricate(:chat_message, chat_channel: channel, user: user1) }
|
|
|
|
before do
|
|
membership2.update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
)
|
|
end
|
|
|
|
it "sends a desktop notification" do
|
|
messages = notification_messages_for(user2)
|
|
|
|
expect(messages.first.data).to include(
|
|
{
|
|
username: user1.username,
|
|
notification_type: Notification.types[:chat_message],
|
|
post_url: channel.relative_url,
|
|
translated_title:
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.new_direct_chat_message",
|
|
{ username: user1.username, channel: channel.title(user2) },
|
|
),
|
|
tag: Chat::ChatNotifier.push_notification_tag(:message, channel.id),
|
|
excerpt: message.message,
|
|
},
|
|
)
|
|
end
|
|
|
|
context "when the channel is muted via membership preferences" do
|
|
before { membership2.update!(muted: true) }
|
|
|
|
it "does not send a desktop or mobile notification" do
|
|
PostAlerter.expects(:push_notification).never
|
|
messages = notification_messages_for(user2)
|
|
expect(messages).to be_empty
|
|
end
|
|
end
|
|
|
|
context "when mobile_notification_level is always and desktop_notification_level is none" do
|
|
before do
|
|
membership2.update!(
|
|
desktop_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:never],
|
|
mobile_notification_level: UserChatChannelMembership::NOTIFICATION_LEVELS[:always],
|
|
)
|
|
end
|
|
|
|
it "sends a mobile notification" do
|
|
PostAlerter.expects(:push_notification).with(
|
|
user2,
|
|
has_entries(
|
|
{
|
|
username: user1.username,
|
|
notification_type: Notification.types[:chat_message],
|
|
post_url: channel.relative_url,
|
|
translated_title:
|
|
I18n.t(
|
|
"discourse_push_notifications.popup.new_direct_chat_message",
|
|
{ username: user1.username, channel: channel.title(user2) },
|
|
),
|
|
tag: Chat::ChatNotifier.push_notification_tag(:message, channel.id),
|
|
excerpt: message.message,
|
|
},
|
|
),
|
|
)
|
|
messages = notification_messages_for(user2)
|
|
expect(messages.length).to be_zero
|
|
end
|
|
|
|
context "when the channel is muted via membership preferences" do
|
|
before { membership2.update!(muted: true) }
|
|
|
|
it "does not send a desktop or mobile notification" do
|
|
PostAlerter.expects(:push_notification).never
|
|
messages = notification_messages_for(user2)
|
|
expect(messages).to be_empty
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the target user cannot chat" do
|
|
before { SiteSetting.chat_allowed_groups = group.id }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user cannot see the chat channel" do
|
|
before { membership2.destroy! }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user has seen the message already" do
|
|
before { membership2.update!(last_read_message_id: message.id) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is online via presence channel" do
|
|
before { PresenceChannel.any_instance.expects(:user_ids).returns([user2.id]) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is suspended" do
|
|
before { user2.update!(suspended_till: 1.year.from_now) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is inside the except_user_ids array" do
|
|
let(:except_user_ids) { [user2.id] }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
|
|
context "when the target user is preventing communication from the message creator" do
|
|
before { UserCommScreener.any_instance.expects(:allowing_actor_communication).returns([]) }
|
|
|
|
it "does not send a desktop notification" do
|
|
expect(notification_messages_for(user2).count).to be_zero
|
|
end
|
|
end
|
|
end
|
|
end
|