discourse/plugins/chat/spec/components/chat_mailer_spec.rb
Roman Rizzi 698c3ced15
FIX: Deliver chat summaries when allowed groups include "everyone" (#18955)
The mailer in charge of sending chat summary emails applies a filter to ensure only members of groups listed in the `chat allowed groups` setting receive them. However, when you set it to `everyone`, nobody will be notified because
we treat this group differently and don't create `GroupUser` records for every user on the site.

This commit changes the mailer to skip the filter when the `everyone` ID is in the list.
2022-11-09 10:54:47 -03:00

287 lines
9.4 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
require "rails_helper"
describe Chat::ChatMailer do
fab!(:chatters_group) { Fabricate(:group) }
fab!(:sender) { Fabricate(:user, group_ids: [chatters_group.id]) }
fab!(:user_1) { Fabricate(:user, group_ids: [chatters_group.id], last_seen_at: 15.minutes.ago) }
fab!(:chat_channel) { Fabricate(:category_channel) }
fab!(:chat_message) { Fabricate(:chat_message, user: sender, chat_channel: chat_channel) }
fab!(:user_1_chat_channel_membership) do
Fabricate(
:user_chat_channel_membership,
user: user_1,
chat_channel: chat_channel,
last_read_message_id: nil,
)
end
fab!(:private_chat_channel) do
Group.refresh_automatic_groups!
Chat::DirectMessageChannelCreator.create!(acting_user: sender, target_users: [sender, user_1])
end
before do
SiteSetting.chat_enabled = true
SiteSetting.chat_allowed_groups = chatters_group.id
Fabricate(:user_chat_channel_membership, user: sender, chat_channel: chat_channel)
end
def assert_summary_skipped
expect(
job_enqueued?(job: :user_email, args: { type: "chat_summary", user_id: user_1.id }),
).to eq(false)
end
def assert_only_queued_once
expect_job_enqueued(job: :user_email, args: { type: "chat_summary", user_id: user_1.id })
expect(Jobs::UserEmail.jobs.size).to eq(1)
end
describe "for chat mentions" do
fab!(:mention) { Fabricate(:chat_mention, user: user_1, chat_message: chat_message) }
it "skips users without chat access" do
chatters_group.remove(user_1)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "skips users with summaries disabled" do
user_1.user_option.update(chat_email_frequency: UserOption.chat_email_frequencies[:never])
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "skips a job if the user haven't read the channel since the last summary" do
user_1_chat_channel_membership.update!(last_unread_mention_when_emailed_id: chat_message.id)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "skips without chat enabled" do
user_1.user_option.update(
chat_enabled: false,
chat_email_frequency: UserOption.chat_email_frequencies[:when_away],
)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "queues a job for users that was mentioned and never read the channel before" do
described_class.send_unread_mentions_summary
assert_only_queued_once
end
it "skips the job when the user was mentioned but already read the message" do
user_1_chat_channel_membership.update!(last_read_message_id: chat_message.id)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "skips the job when the user is not following a public channel anymore" do
user_1_chat_channel_membership.update!(
last_read_message_id: chat_message.id - 1,
following: false,
)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "doesnt skip the job when the user is not following a direct channel" do
private_chat_channel
.user_chat_channel_memberships
.where(user_id: user_1.id)
.update!(last_read_message_id: chat_message.id - 1, following: false)
described_class.send_unread_mentions_summary
assert_only_queued_once
end
it "skips users with unread messages from a different channel" do
user_1_chat_channel_membership.update!(last_read_message_id: chat_message.id)
second_channel = Fabricate(:category_channel)
Fabricate(
:user_chat_channel_membership,
user: user_1,
chat_channel: second_channel,
last_read_message_id: chat_message.id - 1,
)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "only queues the job once for users who are member of multiple groups with chat access" do
chatters_group_2 = Fabricate(:group, users: [user_1])
SiteSetting.chat_allowed_groups = [chatters_group, chatters_group_2].map(&:id).join("|")
described_class.send_unread_mentions_summary
assert_only_queued_once
end
it "skips users when the mention was deleted" do
chat_message.trash!
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "queues the job if the user has unread mentions and already read all the messages in the previous summary" do
user_1_chat_channel_membership.update!(
last_read_message_id: chat_message.id,
last_unread_mention_when_emailed_id: chat_message.id,
)
unread_message = Fabricate(:chat_message, chat_channel: chat_channel, user: sender)
Fabricate(:chat_mention, user: user_1, chat_message: unread_message)
described_class.send_unread_mentions_summary
expect_job_enqueued(job: :user_email, args: { type: "chat_summary", user_id: user_1.id })
expect(Jobs::UserEmail.jobs.size).to eq(1)
end
it "skips users who were seen recently" do
user_1.update!(last_seen_at: 2.minutes.ago)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "doesn't mix mentions from other users" do
mention.destroy!
user_2 = Fabricate(:user, groups: [chatters_group], last_seen_at: 20.minutes.ago)
user_2_membership =
Fabricate(
:user_chat_channel_membership,
user: user_2,
chat_channel: chat_channel,
last_read_message_id: nil,
)
new_message = Fabricate(:chat_message, chat_channel: chat_channel, user: sender)
Fabricate(:chat_mention, user: user_2, chat_message: new_message)
described_class.send_unread_mentions_summary
expect(
job_enqueued?(job: :user_email, args: { type: "chat_summary", user_id: user_1.id }),
).to eq(false)
expect_job_enqueued(job: :user_email, args: { type: "chat_summary", user_id: user_2.id })
expect(Jobs::UserEmail.jobs.size).to eq(1)
end
it "skips users when the message is older than 1 week" do
chat_message.update!(created_at: 1.5.weeks.ago)
described_class.send_unread_mentions_summary
assert_summary_skipped
end
it "queues a job when the chat_allowed_groups is set to everyone" do
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:everyone]
described_class.send_unread_mentions_summary
assert_only_queued_once
end
describe "update the user membership after we send the email" do
before { Jobs.run_immediately! }
it "doesn't send the same summary the summary again if the user haven't read any channel messages since the last one" do
user_1_chat_channel_membership.update!(last_read_message_id: chat_message.id - 1)
described_class.send_unread_mentions_summary
expect(user_1_chat_channel_membership.reload.last_unread_mention_when_emailed_id).to eq(
chat_message.id,
)
another_channel_message = Fabricate(:chat_message, chat_channel: chat_channel, user: sender)
Fabricate(:chat_mention, user: user_1, chat_message: another_channel_message)
expect { described_class.send_unread_mentions_summary }.not_to change(
Jobs::UserEmail.jobs,
:size,
)
end
it "only updates the last_message_read_when_emailed_id on the channel with unread mentions" do
another_channel = Fabricate(:category_channel)
another_channel_message =
Fabricate(:chat_message, chat_channel: another_channel, user: sender)
Fabricate(:chat_mention, user: user_1, chat_message: another_channel_message)
another_channel_membership =
Fabricate(
:user_chat_channel_membership,
user: user_1,
chat_channel: another_channel,
last_read_message_id: another_channel_message.id,
)
user_1_chat_channel_membership.update!(last_read_message_id: chat_message.id - 1)
described_class.send_unread_mentions_summary
expect(user_1_chat_channel_membership.reload.last_unread_mention_when_emailed_id).to eq(
chat_message.id,
)
expect(another_channel_membership.reload.last_unread_mention_when_emailed_id).to be_nil
end
end
end
describe "for direct messages" do
before { Fabricate(:chat_message, user: sender, chat_channel: private_chat_channel) }
it "queue a job when the user has unread private mentions" do
described_class.send_unread_mentions_summary
assert_only_queued_once
end
it "only queues the job once when the user has mentions and private messages" do
Fabricate(:chat_mention, user: user_1, chat_message: chat_message)
described_class.send_unread_mentions_summary
assert_only_queued_once
end
it "Doesn't mix or update mentions from other users when joining tables" do
user_2 = Fabricate(:user, groups: [chatters_group], last_seen_at: 20.minutes.ago)
user_2_membership =
Fabricate(
:user_chat_channel_membership,
user: user_2,
chat_channel: chat_channel,
last_read_message_id: chat_message.id,
)
Fabricate(:chat_mention, user: user_2, chat_message: chat_message)
described_class.send_unread_mentions_summary
assert_only_queued_once
expect(user_2_membership.reload.last_unread_mention_when_emailed_id).to be_nil
end
end
end