discourse/spec/models/notification_spec.rb
Mark VanLandingham 1e5e20ffc5
FEATURE: Notification/tracking changes for nested replies (#39750)
Reply consolidation by bucket for nested view. Replies under the same
parent now collapse into one notification ("3 new replies in your topic"
/ "to your post"). Clicking lands you at that bucket's level with
sort=new&collapse_replies=true so you only see the new content. Flat
topics keep the existing single-row consolidated shape (specs guard
against regression). Root posts that don't explicitly reply to
anyone resolve to the OP, so the OP still gets notified for fresh roots
in their own topic.
                                                                  
Auto-Track instead of auto-Watch for the OP. PMs and flat topics are
unchanged.
  
Topic-list "new replies" dot. Replaces the unread/new count badges for
nested topics when there's new content since the user's last visit. The
count-based UI doesn't fit nested's read pattern.
                                                                  
collapse_replies=true URL param. On the nested view, starts replies
hidden behind an Expand button. Set automatically by consolidated
notifications.

---------

Co-authored-by: Rafael Silva <xfalcox@gmail.com>
2026-05-07 12:33:56 -05:00

977 lines
31 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe Notification do
fab!(:user)
fab!(:coding_horror)
before { NotificationEmailer.enable }
it { is_expected.to validate_presence_of :notification_type }
it { is_expected.to validate_presence_of :data }
it { is_expected.to belong_to :user }
it { is_expected.to belong_to :topic }
describe "#types" do
subject(:types) { Notification.types }
context "when verifying enum sequence" do
it "has a correct position for each type" do
expect(types[:mentioned]).to eq(1)
expect(types[:replied]).to eq(2)
expect(types[:quoted]).to eq(3)
expect(types[:edited]).to eq(4)
expect(types[:liked]).to eq(5)
expect(types[:private_message]).to eq(6)
expect(types[:invited_to_private_message]).to eq(7)
expect(types[:invitee_accepted]).to eq(8)
expect(types[:posted]).to eq(9)
expect(types[:moved_post]).to eq(10)
expect(types[:linked]).to eq(11)
expect(types[:granted_badge]).to eq(12)
expect(types[:invited_to_topic]).to eq(13)
expect(types[:custom]).to eq(14)
expect(types[:group_mentioned]).to eq(15)
expect(types[:group_message_summary]).to eq(16)
expect(types[:watching_first_post]).to eq(17)
expect(types[:topic_reminder]).to eq(18)
expect(types[:liked_consolidated]).to eq(19)
expect(types[:post_approved]).to eq(20)
expect(types[:code_review_commit_approved]).to eq(21)
expect(types[:membership_request_accepted]).to eq(22)
expect(types[:membership_request_consolidated]).to eq(23)
expect(types[:bookmark_reminder]).to eq(24)
expect(types[:reaction]).to eq(25)
expect(types[:votes_released]).to eq(26)
expect(types[:event_reminder]).to eq(27)
expect(types[:event_invitation]).to eq(28)
expect(types[:chat_mention]).to eq(29)
expect(types[:chat_message]).to eq(30)
expect(types[:assigned]).to eq(34)
end
end
end
describe "post" do
let(:topic) { Fabricate(:topic) }
let(:post_args) { { user: topic.user, topic: topic } }
describe "replies" do
def process_alerts(post)
PostAlerter.post_created(post)
end
let(:post) { process_alerts(Fabricate(:post, post_args.merge(raw: "Hello @CodingHorror"))) }
it "notifies the poster on reply" do
expect {
reply = Fabricate(:basic_reply, user: coding_horror, topic: post.topic)
process_alerts(reply)
}.to change(post.user.notifications, :count).by(1)
end
it "doesn't notify the poster when they reply to their own post" do
expect {
reply = Fabricate(:basic_reply, user: post.user, topic: post.topic)
process_alerts(reply)
}.not_to change(post.user.notifications, :count)
end
end
describe "watching" do
it "does notify watching users of new posts" do
post = PostAlerter.post_created(Fabricate(:post, post_args))
user2 = coding_horror
post_args[:topic].notify_watch!(user2)
expect {
PostAlerter.post_created(Fabricate(:post, user: post.user, topic: post.topic))
}.to change(user2.notifications, :count).by(1)
end
end
describe "muting" do
it "does not notify users of new posts" do
post = Fabricate(:post, post_args)
user = post_args[:user]
user2 = coding_horror
post_args[:topic].notify_muted!(user)
expect {
Fabricate(:post, user: user2, topic: post.topic, raw: "hello @" + user.username)
}.not_to change(user.notifications, :count)
end
end
end
describe "high priority creation" do
fab!(:user)
it "automatically marks the notification as high priority if it is a high priority type" do
notif =
Notification.create(
user: user,
notification_type: Notification.types[:bookmark_reminder],
data: {
},
)
expect(notif.high_priority).to eq(true)
notif =
Notification.create(
user: user,
notification_type: Notification.types[:private_message],
data: {
},
)
expect(notif.high_priority).to eq(true)
notif =
Notification.create(user: user, notification_type: Notification.types[:liked], data: {})
expect(notif.high_priority).to eq(false)
end
it "allows manually specifying a notification is high priority" do
notif =
Notification.create(
user: user,
notification_type: Notification.types[:liked],
data: {
},
high_priority: true,
)
expect(notif.high_priority).to eq(true)
end
end
describe "unread counts" do
fab!(:user)
context "with a regular notification" do
it "increases unread_notifications" do
expect {
Fabricate(:notification, user: user)
user.reload
}.to change(user, :unread_notifications)
end
it "increases total_unread_notifications" do
expect {
Fabricate(:notification, user: user)
user.reload
}.to change(user, :total_unread_notifications)
end
it "doesn't increase unread_high_priority_notifications" do
expect {
Fabricate(:notification, user: user)
user.reload
}.not_to change(user, :unread_high_priority_notifications)
end
end
context "with a private message" do
it "doesn't increase unread_notifications" do
expect {
Fabricate(:private_message_notification, user: user)
user.reload
}.not_to change(user, :unread_notifications)
end
it "increases total_unread_notifications" do
expect {
Fabricate(:notification, user: user)
user.reload
}.to change(user, :total_unread_notifications)
end
it "increases unread_high_priority_notifications" do
expect {
Fabricate(:private_message_notification, user: user)
user.reload
}.to change(user, :unread_high_priority_notifications)
end
end
context "with a bookmark reminder message" do
it "doesn't increase unread_notifications" do
expect {
Fabricate(:bookmark_reminder_notification, user: user)
user.reload
}.not_to change(user, :unread_notifications)
end
it "increases total_unread_notifications" do
expect {
Fabricate(:notification, user: user)
user.reload
}.to change(user, :total_unread_notifications)
end
it "increases unread_high_priority_notifications" do
expect {
Fabricate(:bookmark_reminder_notification, user: user)
user.reload
}.to change(user, :unread_high_priority_notifications)
end
end
end
describe "message bus" do
fab!(:user) { Fabricate(:user, last_seen_at: 1.day.ago) }
it "updates the notification count on create" do
Notification.any_instance.expects(:refresh_notification_count).returns(nil)
Fabricate(:notification)
end
it "works" do
messages =
MessageBus.track_publish do
user.notifications.create!(notification_type: Notification.types[:mentioned], data: "{}")
user.notifications.create!(notification_type: Notification.types[:mentioned], data: "{}")
end
expect(messages.size).to eq(2)
expect(messages[0].channel).to eq("/notification/#{user.id}")
expect(messages[0].data[:unread_notifications]).to eq(1)
expect(messages[1].channel).to eq("/notification/#{user.id}")
expect(messages[1].data[:unread_notifications]).to eq(2)
end
it "works for partial model instances" do
NotificationEmailer.disable
partial_user = User.select(:id).find_by(id: user.id)
partial_user.notifications.create!(
notification_type: Notification.types[:mentioned],
data: "{}",
)
end
context "when destroying" do
let!(:notification) { Fabricate(:notification) }
it "updates the notification count on destroy" do
Notification.any_instance.expects(:refresh_notification_count).returns(nil)
notification.destroy!
end
end
end
describe "private message" do
let(:topic) { Fabricate(:private_message_topic) }
let(:post) { Fabricate(:post, topic:, user: topic.user) }
let(:target) { post.topic.topic_allowed_users.reject { |a| a.user_id == post.user_id }[0].user }
before do
TopicUser.change(
target.id,
topic.id,
notification_level: TopicUser.notification_levels[:watching],
)
PostAlerter.post_created(post)
end
it "should create and roll up private message notifications" do
expect(target.notifications.first.notification_type).to eq(
Notification.types[:private_message],
)
expect(post.user.unread_notifications).to eq(0)
expect(post.user.total_unread_notifications).to eq(0)
expect(target.unread_high_priority_notifications).to eq(1)
Fabricate(:post, topic:, user: topic.user)
target.reload
expect(target.unread_high_priority_notifications).to eq(1)
end
end
describe ".post" do
let(:post) { Fabricate(:post) }
let!(:notification) do
Fabricate(:notification, user: post.user, topic: post.topic, post_number: post.post_number)
end
it "returns the post" do
expect(notification.post).to eq(post)
end
end
describe "#url" do
fab!(:topic)
fab!(:post) { Fabricate(:post, topic: topic, post_number: 5) }
it "returns the relative topic url for a regular reply notification" do
notification =
Fabricate(
:notification,
notification_type: Notification.types[:replied],
topic: topic,
post_number: 5,
data: { topic_title: topic.title, display_username: "u" }.to_json,
)
expect(notification.url).to eq(topic.relative_url(5))
end
it "returns the topic root with sort=new&collapse_replies=true for a consolidated topic-bucket notification" do
notification =
Fabricate(
:notification,
notification_type: Notification.types[:replied],
topic: topic,
post_number: 7,
data: {
topic_title: topic.title,
display_username: "3 replies",
reply_to_post_number: 1,
consolidated_count: 3,
}.to_json,
)
expect(notification.url).to eq("/n/#{topic.slug}/#{topic.id}?sort=new&collapse_replies=true")
end
it "returns the bucket parent's context with sort=new&collapse_replies=true for a consolidated per-post-bucket notification" do
notification =
Fabricate(
:notification,
notification_type: Notification.types[:replied],
topic: topic,
post_number: 7,
data: {
topic_title: topic.title,
display_username: "2 replies",
reply_to_post_number: 4,
consolidated_count: 2,
}.to_json,
)
expect(notification.url).to eq(
"/n/#{topic.slug}/#{topic.id}/4?sort=new&collapse_replies=true",
)
end
it "uses the legacy specific-post URL for a singular nested-bucket notification" do
notification =
Fabricate(
:notification,
notification_type: Notification.types[:replied],
topic: topic,
post_number: 5,
data: {
topic_title: topic.title,
display_username: "u",
reply_to_post_number: 1,
}.to_json,
)
expect(notification.url).to eq(topic.relative_url(5))
end
end
describe "data" do
let(:notification) { Fabricate.build(:notification) }
it "should have a data hash" do
expect(notification.data_hash).to be_present
end
it "should have the data within the json" do
expect(notification.data_hash[:poison]).to eq("ivy")
end
end
describe "saw_regular_notification_id" do
it "correctly updates the read state" do
t = Fabricate(:topic)
Notification.create!(
read: false,
user_id: user.id,
topic_id: t.id,
post_number: 1,
data: "{}",
notification_type: Notification.types[:private_message],
)
Notification.create!(
read: false,
user_id: user.id,
topic_id: t.id,
post_number: 1,
data: "{}",
notification_type: Notification.types[:bookmark_reminder],
)
other =
Notification.create!(
read: false,
user_id: user.id,
topic_id: t.id,
post_number: 1,
data: "{}",
notification_type: Notification.types[:mentioned],
)
user.bump_last_seen_notification!
user.reload
expect(user.unread_notifications).to eq(0)
expect(user.total_unread_notifications).to eq(3)
expect(user.unread_high_priority_notifications).to eq(2)
end
end
describe "mark_posts_read" do
it "marks multiple posts as read if needed" do
(1..3).map do |i|
Notification.create!(
read: false,
user_id: user.id,
topic_id: 2,
post_number: i,
data: "{}",
notification_type: 1,
)
end
Notification.create!(
read: true,
user_id: user.id,
topic_id: 2,
post_number: 4,
data: "{}",
notification_type: 1,
)
expect { Notification.mark_posts_read(user, 2, [1, 2, 3, 4]) }.to change {
Notification.where(read: true).count
}.by(3)
end
end
describe "#ensure_consistency!" do
it "deletes notifications if post is missing or deleted" do
NotificationEmailer.disable
p = Fabricate(:post)
p2 = Fabricate(:post)
Notification.create!(
read: false,
user_id: p.user_id,
topic_id: p.topic_id,
post_number: p.post_number,
data: "[]",
notification_type: Notification.types[:private_message],
)
Notification.create!(
read: false,
user_id: p2.user_id,
topic_id: p2.topic_id,
post_number: p2.post_number,
data: "[]",
notification_type: Notification.types[:private_message],
)
Notification.create!(
read: false,
user_id: p2.user_id,
topic_id: p2.topic_id,
post_number: p2.post_number,
data: "[]",
notification_type: Notification.types[:bookmark_reminder],
)
Notification.create!(
read: false,
user_id: p2.user_id,
topic_id: p2.topic_id,
post_number: p2.post_number,
data: "[]",
notification_type: Notification.types[:liked],
)
p2.trash!(p.user)
# we may want to make notification "trashable" but for now we nuke pm notifications from deleted topics/posts
Notification.ensure_consistency!
expect(Notification.count).to eq(2)
end
it "does not delete notifications that do not have a topic_id" do
Notification.create!(
read: false,
user_id: user.id,
topic_id: nil,
post_number: nil,
data: "[]",
notification_type: Notification.types[:chat_mention],
high_priority: true,
)
expect { Notification.ensure_consistency! }.to_not change { Notification.count }
end
end
describe "do not disturb" do
it "calls NotificationEmailer.process_notification when user is not in 'do not disturb'" do
notification =
Notification.new(
read: false,
user_id: user.id,
topic_id: 2,
post_number: 1,
data: "{}",
notification_type: 1,
)
NotificationEmailer.expects(:process_notification).with(notification)
notification.save!
end
it "doesn't call NotificationEmailer.process_notification when user is in 'do not disturb'" do
freeze_time
Fabricate(
:do_not_disturb_timing,
user: user,
starts_at: Time.zone.now,
ends_at: 1.day.from_now,
)
notification =
Notification.new(
read: false,
user_id: user.id,
topic_id: 2,
post_number: 1,
data: "{}",
notification_type: 1,
)
NotificationEmailer.expects(:process_notification).with(notification).never
notification.save!
end
end
end
# pulling this out cause I don't want an observer
RSpec.describe Notification do
fab!(:user)
describe ".prioritized_list" do
def create(**opts)
opts[:user] = user if !opts[:user]
Fabricate(:notification, user: user, **opts)
end
fab!(:unread_high_priority_1) do
create(high_priority: true, read: false, created_at: 8.minutes.ago)
end
fab!(:read_high_priority_1) do
create(high_priority: true, read: true, created_at: 7.minutes.ago)
end
fab!(:unread_regular_1) { create(high_priority: false, read: false, created_at: 6.minutes.ago) }
fab!(:read_regular_1) { create(high_priority: false, read: true, created_at: 5.minutes.ago) }
fab!(:unread_like) do
create(
high_priority: false,
read: false,
created_at: 130.seconds.ago,
notification_type: Notification.types[:liked],
)
end
fab!(:unread_high_priority_2) do
create(high_priority: true, read: false, created_at: 1.minute.ago)
end
fab!(:read_high_priority_2) do
create(high_priority: true, read: true, created_at: 2.minutes.ago)
end
fab!(:unread_regular_2) { create(high_priority: false, read: false, created_at: 3.minutes.ago) }
fab!(:read_regular_2) { create(high_priority: false, read: true, created_at: 4.minutes.ago) }
it "puts unread high_priority on top followed by unread normal notifications and then everything else in reverse chronological order" do
expect(Notification.prioritized_list(user).map(&:id)).to eq(
[
unread_high_priority_2,
unread_high_priority_1,
unread_regular_2,
unread_regular_1,
read_high_priority_2,
unread_like,
read_regular_2,
read_regular_1,
read_high_priority_1,
].map(&:id),
)
end
it "doesn't include notifications from other users" do
another_user_notification = create(high_priority: true, read: false, user: Fabricate(:user))
expect(Notification.prioritized_list(user).map(&:id)).to contain_exactly(
*[
unread_high_priority_2,
unread_high_priority_1,
unread_regular_2,
unread_regular_1,
read_high_priority_2,
unread_like,
read_regular_2,
read_regular_1,
read_high_priority_1,
].map(&:id),
)
expect(
Notification.prioritized_list(another_user_notification.user).map(&:id),
).to contain_exactly(another_user_notification.id)
end
it "doesn't include notifications from deleted topics" do
unread_high_priority_1.topic.trash!
unread_regular_2.topic.trash!
read_regular_1.topic.trash!
expect(Notification.prioritized_list(user).map(&:id)).to contain_exactly(
*[
unread_high_priority_2,
unread_regular_1,
read_high_priority_2,
unread_like,
read_regular_2,
read_high_priority_1,
].map(&:id),
)
end
it "doesn't include like notifications if the user doesn't want like notifications" do
user.user_option.update!(
like_notification_frequency: UserOption.like_notification_frequency_type[:never],
)
unread_regular_1.update!(notification_type: Notification.types[:liked])
read_regular_2.update!(notification_type: Notification.types[:liked_consolidated])
expect(Notification.prioritized_list(user).map(&:id)).to eq(
[
unread_high_priority_2,
unread_high_priority_1,
unread_regular_2,
read_high_priority_2,
read_regular_1,
read_high_priority_1,
].map(&:id),
)
end
it "respects the count param" do
expect(Notification.prioritized_list(user, count: 1).map(&:id)).to eq(
[unread_high_priority_2].map(&:id),
)
expect(Notification.prioritized_list(user, count: 3).map(&:id)).to eq(
[unread_high_priority_2, unread_high_priority_1, unread_regular_2].map(&:id),
)
end
it "can filter the list by specific types" do
unread_regular_1.update!(notification_type: Notification.types[:liked])
read_regular_2.update!(notification_type: Notification.types[:liked_consolidated])
expect(
Notification.prioritized_list(
user,
types: [Notification.types[:liked], Notification.types[:liked_consolidated]],
).map(&:id),
).to eq([unread_like, unread_regular_1, read_regular_2].map(&:id))
end
it "includes like notifications when filtering by like types even if the user doesn't want like notifications" do
user.user_option.update!(
like_notification_frequency: UserOption.like_notification_frequency_type[:never],
)
unread_regular_1.update!(notification_type: Notification.types[:liked])
read_regular_2.update!(notification_type: Notification.types[:liked_consolidated])
expect(
Notification.prioritized_list(
user,
types: [Notification.types[:liked], Notification.types[:liked_consolidated]],
).map(&:id),
).to eq([unread_like, unread_regular_1, read_regular_2].map(&:id))
expect(
Notification.prioritized_list(user, types: [Notification.types[:liked]]).map(&:id),
).to contain_exactly(unread_like.id, unread_regular_1.id)
end
end
describe "#recent_report" do
let(:post) { Fabricate(:post) }
let(:vars) { { i: 0 } }
def fab(type, read)
vars[:i] += 1
Notification.create!(
read: read,
user_id: user.id,
topic_id: post.topic_id,
post_number: post.post_number,
data: "[]",
notification_type: type,
created_at: vars[:i].days.from_now,
)
end
def unread_pm
fab(Notification.types[:private_message], false)
end
def unread_bookmark_reminder
fab(Notification.types[:bookmark_reminder], false)
end
def pm
fab(Notification.types[:private_message], true)
end
def regular
fab(Notification.types[:liked], true)
end
def liked_consolidated
fab(Notification.types[:liked_consolidated], true)
end
it "correctly finds visible notifications" do
pm
expect(Notification.visible.count).to eq(1)
post.topic.trash!
expect(Notification.visible.count).to eq(0)
end
it "orders stuff by creation descending, bumping unread high priority (pms, bookmark reminders) to top" do
# note we expect the final order to read bottom-up for this list of variables,
# with unread pm + bookmark reminder at the top of that list
a = unread_pm
regular
b = unread_bookmark_reminder
c = pm
d = regular
notifications = Notification.recent_report(user, 4)
expect(notifications.map { |n| n.id }).to eq([b.id, a.id, d.id, c.id])
end
describe "for a user that does not want to be notify on liked" do
before do
user.user_option.update!(
like_notification_frequency: UserOption.like_notification_frequency_type[:never],
)
end
it "should not return any form of liked notifications" do
notification = pm
regular
liked_consolidated
expect(Notification.recent_report(user)).to contain_exactly(notification)
end
end
describe "#consolidate_membership_requests" do
fab!(:group) { Fabricate(:group, name: "XXsssssddd") }
fab!(:user)
fab!(:post)
def create_membership_request_notification
Notification.consolidate_or_create!(
notification_type: Notification.types[:private_message],
user_id: user.id,
data: {
topic_title: I18n.t("groups.request_membership_pm.title", group_name: group.name),
original_post_id: post.id,
}.to_json,
updated_at: Time.zone.now,
created_at: Time.zone.now,
)
end
before do
PostCustomField.create!(post_id: post.id, name: "requested_group_id", value: group.id)
2.times { create_membership_request_notification }
end
it "should consolidate membership requests to a new notification" do
original_notification = create_membership_request_notification
starting_count = SiteSetting.notification_consolidation_threshold
consolidated_notification = create_membership_request_notification
expect { original_notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect(consolidated_notification.notification_type).to eq(
Notification.types[:membership_request_consolidated],
)
data = consolidated_notification.data_hash
expect(data[:group_name]).to eq(group.name)
expect(data[:count]).to eq(starting_count + 1)
updated_consolidated_notification = create_membership_request_notification
expect(updated_consolidated_notification.data_hash[:count]).to eq(starting_count + 2)
end
it 'consolidates membership requests with "processed" false if user is in DND' do
user.do_not_disturb_timings.create(starts_at: Time.now, ends_at: 3.days.from_now)
create_membership_request_notification
create_membership_request_notification
notification = Notification.last
expect(notification.notification_type).to eq(
Notification.types[:membership_request_consolidated],
)
expect(notification.shelved_notification).to be_present
end
end
end
describe "purge_old!" do
fab!(:user)
fab!(:notification1) { Fabricate(:notification, user: user) }
fab!(:notification2) { Fabricate(:notification, user: user) }
fab!(:notification3) { Fabricate(:notification, user: user) }
fab!(:notification4) { Fabricate(:notification, user: user) }
it "does nothing if set to 0" do
SiteSetting.max_notifications_per_user = 0
Notification.purge_old!
expect(Notification.where(user_id: user.id).count).to eq(4)
end
it "correctly limits" do
SiteSetting.max_notifications_per_user = 2
Notification.purge_old!
expect(Notification.where(user_id: user.id).pluck(:id)).to contain_exactly(
notification4.id,
notification3.id,
)
end
end
describe "do not disturb" do
fab!(:user)
it "creates a shelved_notification record when created while user is in DND" do
user.do_not_disturb_timings.create(starts_at: Time.now, ends_at: 3.days.from_now)
notification =
Notification.create(
read: false,
user_id: user.id,
topic_id: 2,
post_number: 1,
data: "{}",
notification_type: 1,
)
expect(notification.shelved_notification).to be_present
end
it "doesn't create a shelved_notification record when created while user is isn't DND" do
notification =
Notification.create(
read: false,
user_id: user.id,
topic_id: 2,
post_number: 1,
data: "{}",
notification_type: 1,
)
expect(notification.shelved_notification).to be_nil
end
end
describe ".populate_acting_user" do
SiteSetting.enable_names = true
fab!(:user1, :user)
fab!(:user2, :user)
fab!(:user3, :user)
fab!(:user4, :user)
fab!(:user5, :user)
fab!(:user6, :user)
fab!(:notification1) do
Fabricate(:notification, user: user, data: { username: user1.username }.to_json)
end
fab!(:notification2) do
Fabricate(:notification, user: user, data: { display_username: user2.username }.to_json)
end
fab!(:notification3) do
Fabricate(:notification, user: user, data: { mentioned_by_username: user3.username }.to_json)
end
fab!(:notification4) do
Fabricate(:notification, user: user, data: { invited_by_username: user4.username }.to_json)
end
fab!(:notification5) do
Fabricate(:notification, user: user, data: { original_username: user5.username }.to_json)
end
fab!(:notification6) do
Fabricate(:notification, user: user, data: { original_username: user6.username }.to_json)
end
it "Sets the acting_user correctly for each notification" do
SiteSetting.prioritize_full_name_in_ux = true
Notification.populate_acting_user(
[notification1, notification2, notification3, notification4, notification5],
)
expect(notification1.acting_user).to eq(user1)
expect(notification2.acting_user).to eq(user2)
expect(notification3.acting_user).to eq(user3)
expect(notification4.acting_user).to eq(user4)
expect(notification5.acting_user).to eq(user5)
expect(notification5.data_hash[:original_name]).to eq user5.name
end
context "with SiteSettings.enable_names=false" do
it "doesn't set the :original_name property" do
SiteSetting.enable_names = false
Notification.populate_acting_user([notification6])
expect(notification6.data_hash[:original_name]).to be_nil
SiteSetting.enable_names = true
end
end
end
describe ".filter_disabled_badge_notifications" do
fab!(:enabled_badge) { Fabricate(:badge, enabled: true) }
fab!(:disabled_badge) { Fabricate(:badge, enabled: false) }
fab!(:enabled_badge_notification) do
BadgeGranter.send_notification(user.id, user.username, user.locale, enabled_badge)
end
fab!(:disabled_badge_notification) do
BadgeGranter.send_notification(user.id, user.username, user.locale, disabled_badge)
end
fab!(:regular_notification) { Fabricate(:notification, user: user) }
it "filters all badge notifications when enable_badges is false" do
SiteSetting.enable_badges = false
result =
Notification.filter_disabled_badge_notifications(
[enabled_badge_notification, disabled_badge_notification, regular_notification],
)
expect(result).to contain_exactly(regular_notification)
end
it "filters badge notifications for badges that are disabled" do
result =
Notification.filter_disabled_badge_notifications(
[enabled_badge_notification, disabled_badge_notification, regular_notification],
)
expect(result).to contain_exactly(enabled_badge_notification, regular_notification)
end
it "filters badge notifications for badges that do not exist" do
enabled_badge.destroy!
result = Notification.filter_disabled_badge_notifications([enabled_badge_notification])
expect(result).to eq([])
end
end
end