0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/plugins/discourse-reactions/spec/services/reaction_notification_spec.rb
Jarek Radosz 71834c898f
DEV: Update rubocop-discourse to 3.13 and autofix issues (#35073)
Co-authored-by: Loïc Guitaut <loic@discourse.org>
2025-10-06 16:11:01 +02:00

282 lines
12 KiB
Ruby
Vendored

# frozen_string_literal: true
require_relative "../fabricators/reaction_fabricator"
require_relative "../fabricators/reaction_user_fabricator"
describe DiscourseReactions::ReactionNotification do
before do
SiteSetting.discourse_reactions_enabled = true
PostActionNotifier.enable
end
fab!(:post_1, :post)
fab!(:thumbsup) { Fabricate(:reaction, post: post_1, reaction_value: "thumbsup") }
fab!(:user_1) { Fabricate(:user, name: "Bruce Wayne Jr.") }
fab!(:user_2, :user)
fab!(:user_3) { Fabricate(:user, name: "Bruce Wayne Sr.") }
fab!(:reaction_user1) { Fabricate(:reaction_user, reaction: thumbsup, user: user_1) }
fab!(:like_reaction) { Fabricate(:reaction, post: post_1, reaction_value: "heart") }
it "does not create notification when user is muted" do
MutedUser.create!(user_id: post_1.user.id, muted_user_id: user_1.id)
expect { described_class.new(thumbsup, user_1).create }.not_to change { Notification.count }
end
it "does not create notification when topic is muted" do
TopicUser.create!(
topic: post_1.topic,
user: post_1.user,
notification_level: TopicUser.notification_levels[:muted],
)
MutedUser.create!(user_id: post_1.user.id, muted_user_id: user_1.id)
described_class.new(thumbsup, user_1).create
expect { described_class.new(thumbsup, user_1).create }.not_to change { Notification.count }
end
it "does not create notification when notification setting is never" do
post_1.user.user_option.update!(
like_notification_frequency: UserOption.like_notification_frequency_type[:never],
)
MutedUser.create!(user_id: post_1.user.id, muted_user_id: user_1.id)
expect { described_class.new(thumbsup, user_1).create }.not_to change { Notification.count }
end
it "correctly creates notification when notification setting is first time and daily" do
post_1.user.user_option.update!(
like_notification_frequency:
UserOption.like_notification_frequency_type[:first_time_and_daily],
)
expect { described_class.new(thumbsup, user_1).create }.to change { Notification.count }.by(1)
expect(Notification.last.user_id).to eq(post_1.user.id)
expect(Notification.last.notification_type).to eq(Notification.types[:reaction])
expect(JSON.parse(Notification.last.data)["original_username"]).to eq(user_1.username)
user_2 = Fabricate(:user)
Fabricate(:reaction_user, reaction: thumbsup, user: user_2)
expect { described_class.new(thumbsup, user_2).create }.not_to change { Notification.count }
freeze_time(1.day.from_now)
cry = Fabricate(:reaction, post: post_1, reaction_value: "cry")
Fabricate(:reaction_user, reaction: cry, user: user_2)
expect { described_class.new(cry, user_2).create }.to change { Notification.count }.by(1)
end
it "deletes notification when all reactions are removed" do
expect { described_class.new(thumbsup, user_1).create }.to change { Notification.count }.by(1)
cry = Fabricate(:reaction, post: post_1, reaction_value: "cry")
Fabricate(:reaction_user, reaction: cry, user: user_1)
expect { described_class.new(cry, user_1).create }.not_to change { Notification.count }
user_2 = Fabricate(:user)
Fabricate(:reaction_user, reaction: cry, user: user_2)
expect { described_class.new(cry, user_1).create }.not_to change { Notification.count }
expect(JSON.parse(Notification.last.data)["display_username"]).to eq(user_1.username)
DiscourseReactions::ReactionUser.find_by(reaction: cry, user: user_1).destroy
DiscourseReactions::ReactionUser.find_by(reaction: thumbsup, user: user_1).destroy
expect do
described_class.new(cry, user_1).delete
described_class.new(thumbsup, user_1).delete
end.not_to change { Notification.count }
expect(JSON.parse(Notification.last.data)["display_username"]).to eq(user_2.username)
expect(Notification.last.notification_type).to eq(Notification.types[:reaction])
DiscourseReactions::ReactionUser.find_by(reaction: cry, user: user_2).destroy
expect { described_class.new(cry, user_2).delete }.to change { Notification.count }.by(-1)
end
it "displays the full name" do
cry_p1 = Fabricate(:reaction, post: post_1, reaction_value: "cry")
described_class.new(cry_p1, user_2).create
expect(
Notification.where(notification_type: Notification.types[:reaction], user: post_1.user).count,
).to eq(1)
notification = Notification.where(notification_type: Notification.types[:reaction]).last
expect(notification.data_hash[:display_name]).to eq(user_2.name)
end
it "adds the heart icon when the remaining notification is a like" do
Fabricate(:reaction_user, reaction: like_reaction, user: user_2)
described_class.new(like_reaction, user_2).create
DiscourseReactions::ReactionUser.find_by(reaction: thumbsup, user: user_1).destroy!
described_class.new(thumbsup, user_1).delete
remaining_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(remaining_notification.data_hash[:reaction_icon]).to eq(like_reaction.reaction_value)
end
it "doesn't add the heart icon when not all remaining notifications are likes" do
Fabricate(:reaction_user, reaction: like_reaction, user: user_2)
described_class.new(like_reaction, user_2).create
cry = Fabricate(:reaction, post: post_1, reaction_value: "cry")
Fabricate(:reaction_user, reaction: cry, user: user_3)
described_class.new(cry, user_3).create
DiscourseReactions::ReactionUser.find_by(reaction: thumbsup, user: user_1).destroy!
described_class.new(thumbsup, user_1).delete
remaining_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(remaining_notification.data_hash[:reaction_icon]).to be_nil
end
describe "consolidating reaction notifications" do
fab!(:post_2) { Fabricate(:post, user: post_1.user) }
let!(:cry_p1) { Fabricate(:reaction, post: post_1, reaction_value: "cry") }
let!(:cry_p2) { Fabricate(:reaction, post: post_2, reaction_value: "cry") }
describe "multiple reactions from the same user" do
before { SiteSetting.notification_consolidation_threshold = 1 }
it "consolidates notifications from the same user" do
described_class.new(cry_p1, user_2).create
described_class.new(cry_p2, user_2).create
expect(
Notification.where(
notification_type: Notification.types[:reaction],
user: post_1.user,
).count,
).to eq(1)
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:consolidated]).to eq(true)
expect(consolidated_notification.data_hash[:username]).to eq(user_2.username)
end
it "doesn't update a consolidated notification when a different user reacts to a post" do
described_class.new(cry_p1, user_2).create
described_class.new(cry_p2, user_2).create
described_class.new(cry_p2, user_3).create
expect(
Notification.where(
notification_type: Notification.types[:reaction],
user: post_1.user,
).count,
).to eq(2)
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:consolidated]).to be_nil
expect(consolidated_notification.data_hash[:display_username]).to eq(user_3.username)
end
it "keeps the reaction icon when consolidating multiple likes from the same user" do
like_reaction_p2 = Fabricate(:reaction, post: post_2, reaction_value: "heart")
described_class.new(like_reaction, user_2).create
described_class.new(like_reaction_p2, user_2).create
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:consolidated]).to eq(true)
expect(consolidated_notification.data_hash[:reaction_icon]).to eq(
like_reaction.reaction_value,
)
end
it "doesn't add the reaction icon when consolidating a non-like and a like notification" do
described_class.new(cry_p2, user_2).create
described_class.new(like_reaction, user_2).create
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:reaction_icon]).to be_nil
end
it "removes the reaction icon when updating a like consolidated notification with a different reactions" do
like_reaction_p2 = Fabricate(:reaction, post: post_2, reaction_value: "heart")
post_3 = Fabricate(:post, user: post_1.user)
cry_p3 = Fabricate(:reaction, post: post_3, reaction_value: "cry")
described_class.new(like_reaction, user_2).create
described_class.new(like_reaction_p2, user_2).create
described_class.new(cry_p3, user_2).create
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:reaction_icon]).to be_nil
end
end
describe "multiple users reacting to the same post" do
before do
post_1.user.user_option.update!(
like_notification_frequency: UserOption.like_notification_frequency_type[:always],
)
end
it "keeps one notification pointing to the two last users that reacted to a post" do
described_class.new(cry_p1, user_2).create
described_class.new(thumbsup, user_3).create
expect(
Notification.where(
notification_type: Notification.types[:reaction],
user: post_1.user,
).count,
).to eq(1)
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:display_username]).to eq(user_3.username)
expect(consolidated_notification.data_hash[:username2]).to eq(user_2.username)
expect(consolidated_notification.data_hash[:display_name]).to eq(user_3.name)
expect(consolidated_notification.data_hash[:name2]).to eq(user_2.name)
end
it "creates a new notification if the last one was created more than one day ago" do
first_notification = described_class.new(cry_p1, user_2).create
first_notification.update!(created_at: 2.days.ago)
described_class.new(thumbsup, user_3).create
expect(
Notification.where(
notification_type: Notification.types[:reaction],
user: post_1.user,
).count,
).to eq(2)
end
it "keeps the icon of the last notification" do
described_class.new(thumbsup, user_3).create
described_class.new(like_reaction, user_2).create
consolidated_notification =
Notification.where(notification_type: Notification.types[:reaction]).last
expect(consolidated_notification.data_hash[:reaction_icon]).to eq(
like_reaction.reaction_value,
)
end
end
end
describe "stores the icon in the notification payload" do
it "stores the heart icon for like reactions" do
described_class.new(like_reaction, user_2).create
notification =
Notification.where(user: post_1.user, notification_type: Notification.types[:reaction]).last
expect(notification.data_hash[:reaction_icon]).to eq(like_reaction.reaction_value)
end
end
end