discourse/spec/jobs/notify_mailing_list_subscribers_spec.rb
Martin Brennan e43a8af3bd
FIX: Do not send emails to mailing_list_mode subscribers for PMs (#14159)
This bug was introduced by f66007ec83.

In PostJobsEnqueuer we previously did not fire the after_post_create
event and after_topic_create event for private message topics. This was
changed in the above commit in order to publish message bus messages
for topic tracking state updates. Unfortunately this caused the
NotifyMailingListSubscribers job to be enqueued for all posts including
private messages, and admins and the users involved in the PMs got
emailed the contents of the PMs if they had mailing list mode enabled.

Luckily the impact of this was mitigated by a Guardian#can_see? check
for each mailing list mode user in the NotifyMailingListSubscribers job.
We never want to notify mailing list mode subscribers for private messages
so an early return has been added there, plus the logic in PostJobsEnqueuer
has been fixed, and tests have been added to that class where there were
none before.
2021-08-26 15:16:35 +10:00

272 lines
9.1 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
describe Jobs::NotifyMailingListSubscribers do
fab!(:mailing_list_user) { Fabricate(:user) }
before { mailing_list_user.user_option.update(mailing_list_mode: true, mailing_list_mode_frequency: 1) }
before do
SiteSetting.tagging_enabled = true
end
fab!(:tag) { Fabricate(:tag) }
fab!(:topic) { Fabricate(:topic, tags: [tag]) }
fab!(:user) { Fabricate(:user) }
fab!(:post) { Fabricate(:post, topic: topic, user: user) }
shared_examples "no emails" do
it "doesn't send any emails" do
UserNotifications.expects(:mailing_list_notify).with(mailing_list_user, post).never
Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
end
end
shared_examples "one email" do
it "sends the email" do
UserNotifications.expects(:mailing_list_notify).with(mailing_list_user, post).once
Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
end
it "triggers :notify_mailing_list_subscribers" do
events = DiscourseEvent.track_events do
Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
end
expect(events).to include(event_name: :notify_mailing_list_subscribers, params: [[mailing_list_user], post])
end
end
context "when mailing list mode is globally disabled" do
before { SiteSetting.disable_mailing_list_mode = true }
include_examples "no emails"
end
context "when mailing list mode is globally enabled" do
before { SiteSetting.disable_mailing_list_mode = false }
context "when site requires approval and user is not approved" do
before do
SiteSetting.login_required = true
SiteSetting.must_approve_users = true
User.update_all(approved: false)
end
include_examples "no emails"
end
context "with an invalid post_id" do
before { post.update(deleted_at: Time.now) }
include_examples "no emails"
end
context "with a deleted post" do
before { post.update(deleted_at: Time.now) }
include_examples "no emails"
end
context "with a empty post" do
before { post.update_columns(raw: "") }
include_examples "no emails"
end
context "with a user_deleted post" do
before { post.update(user_deleted: true) }
include_examples "no emails"
end
context "with a deleted topic" do
before { post.topic.update(deleted_at: Time.now) }
include_examples "no emails"
end
context "with a private message" do
before do
post.topic.update!(archetype: Archetype.private_message, category: nil)
TopicAllowedUser.create(topic: post.topic, user: mailing_list_user)
post.topic.reload
end
include_examples "no emails"
end
context "with a valid post from another user" do
context "to an inactive user" do
before { mailing_list_user.update(active: false) }
include_examples "no emails"
end
context "to a silenced user" do
before { mailing_list_user.update(silenced_till: 1.year.from_now) }
include_examples "no emails"
end
context "to a suspended user" do
before { mailing_list_user.update(suspended_till: 1.day.from_now) }
include_examples "no emails"
end
context "to an anonymous user" do
fab!(:mailing_list_user) { Fabricate(:anonymous) }
include_examples "no emails"
end
context "to an user who has disabled mailing list mode" do
before { mailing_list_user.user_option.update(mailing_list_mode: false) }
include_examples "no emails"
end
context "to an user who has frequency set to 'always'" do
before { mailing_list_user.user_option.update(mailing_list_mode_frequency: 1) }
include_examples "one email"
end
context "to an user who has frequency set to 'no echo'" do
before { mailing_list_user.user_option.update(mailing_list_mode_frequency: 2) }
include_examples "one email"
end
context "from a muted user" do
before { MutedUser.create(user: mailing_list_user, muted_user: user) }
include_examples "no emails"
end
context "from an ignored user" do
before { Fabricate(:ignored_user, user: mailing_list_user, ignored_user: user) }
include_examples "no emails"
end
context "from a muted topic" do
before { TopicUser.create(user: mailing_list_user, topic: post.topic, notification_level: TopicUser.notification_levels[:muted]) }
include_examples "no emails"
end
context "from a muted category" do
before { CategoryUser.create(user: mailing_list_user, category: post.topic.category, notification_level: CategoryUser.notification_levels[:muted]) }
include_examples "no emails"
end
context "mute all categories by default setting" do
before { SiteSetting.mute_all_categories_by_default = true }
include_examples "no emails"
end
context "mute all categories by default setting but user is watching category" do
before do
SiteSetting.mute_all_categories_by_default = true
CategoryUser.create(user: mailing_list_user, category: post.topic.category, notification_level: CategoryUser.notification_levels[:watching])
end
include_examples "one email"
end
context "mute all categories by default setting but user is watching tag" do
before do
SiteSetting.mute_all_categories_by_default = true
TagUser.create(user: mailing_list_user, tag: tag, notification_level: TagUser.notification_levels[:watching])
end
include_examples "one email"
end
context "mute all categories by default setting but user is watching topic" do
before do
SiteSetting.mute_all_categories_by_default = true
TopicUser.create(user: mailing_list_user, topic: post.topic, notification_level: TopicUser.notification_levels[:watching])
end
include_examples "one email"
end
context "from a muted tag" do
before { TagUser.create(user: mailing_list_user, tag: tag, notification_level: TagUser.notification_levels[:muted]) }
include_examples "no emails"
end
context "max emails per day was reached" do
before { SiteSetting.max_emails_per_day_per_user = 2 }
it "doesn't send any emails" do
(SiteSetting.max_emails_per_day_per_user + 1).times {
mailing_list_user.email_logs.create(email_type: 'foobar', to_address: mailing_list_user.email)
}
expect do
UserNotifications.expects(:mailing_list_notify)
.with(mailing_list_user, post)
.never
2.times do
Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
end
Jobs::NotifyMailingListSubscribers.new.execute(
post_id: Fabricate(:post, user: user).id
)
end.to change { SkippedEmailLog.count }.by(1)
expect(SkippedEmailLog.exists?(
email_type: "mailing_list",
user: mailing_list_user,
post: post,
to_address: mailing_list_user.email,
reason_type: SkippedEmailLog.reason_types[:exceeded_emails_limit]
)).to eq(true)
freeze_time(Time.zone.now.tomorrow + 1.second)
expect do
post = Fabricate(:post, user: user)
UserNotifications.expects(:mailing_list_notify)
.with(mailing_list_user, post)
.once
Jobs::NotifyMailingListSubscribers.new.execute(
post_id: post.id
)
end.to change { SkippedEmailLog.count }.by(0)
end
end
context "bounce score was reached" do
it "doesn't send any emails" do
mailing_list_user.user_stat.update(bounce_score: SiteSetting.bounce_score_threshold + 1)
Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id)
UserNotifications.expects(:mailing_list_notify).with(mailing_list_user, post).never
expect(SkippedEmailLog.exists?(
email_type: "mailing_list",
user: mailing_list_user,
post: post,
to_address: mailing_list_user.email,
reason_type: SkippedEmailLog.reason_types[:exceeded_bounces_limit]
)).to eq(true)
end
end
end
context "with a valid post from same user" do
fab!(:post) { Fabricate(:post, user: mailing_list_user) }
context "to an user who has frequency set to 'daily'" do
before { mailing_list_user.user_option.update(mailing_list_mode_frequency: 0) }
include_examples "no emails"
end
context "to an user who has frequency set to 'always'" do
before { mailing_list_user.user_option.update(mailing_list_mode_frequency: 1) }
include_examples "one email"
end
context "to an user who has frequency set to 'no echo'" do
before { mailing_list_user.user_option.update(mailing_list_mode_frequency: 2) }
include_examples "no emails"
end
end
end
end