From 579d213150e3b29dd96dba70f07594fb4eeefa26 Mon Sep 17 00:00:00 2001 From: Pablo Brasero Date: Mon, 20 Apr 2026 15:26:48 +0100 Subject: [PATCH] Implement web notifications for note comments --- app/models/user_notifications.rb | 23 +++++ .../notifications/_note_comment.html.erb | 44 +++++++++ config/locales/en.yml | 9 ++ .../notifications/note_comment_view_test.rb | 91 +++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 app/views/notifications/_note_comment.html.erb create mode 100644 test/controllers/notifications/note_comment_view_test.rb diff --git a/app/models/user_notifications.rb b/app/models/user_notifications.rb index 6ecc98b4b..723e5c72e 100644 --- a/app/models/user_notifications.rb +++ b/app/models/user_notifications.rb @@ -50,10 +50,33 @@ class UserNotifications end end + class NoteCommentNotification < Notification + delegate :note, :to => :record + delegate :event, :to => :record + delegate :id, :to => :note, :prefix => true + + def comment_body + record.body + end + + def comment_id + record.id + end + + def commenter + record.author + end + + def note_text + note.description + end + end + include Enumerable LISTABLE_NOTIFICATIONS = %w[ ChangesetCommentNotifier::Notification + NoteCommentNotifier::Notification ].freeze def initialize(user) diff --git a/app/views/notifications/_note_comment.html.erb b/app/views/notifications/_note_comment.html.erb new file mode 100644 index 000000000..636f1e03a --- /dev/null +++ b/app/views/notifications/_note_comment.html.erb @@ -0,0 +1,44 @@ +<%# locals: (notification:) %> + +
+
+

+ <%= link_to( + t(".headline.#{notification.event}"), + note_path( + notification.note, + :anchor => "c#{notification.comment_id}" + ) + ) %> +

+

<%= friendly_date_ago(notification.timestamp) %>

+
+ +
+
+ <%= link_to( + user_thumbnail(notification.commenter, :class => "img-fluid"), + user_url(notification.commenter), + :target => "_blank", :rel => "noopener" + ) %> +
+
+

+ <%= t( + ".description.#{notification.event}_html", + :commenter_name_with_link => link_to( + notification.commenter.display_name, + notification.commenter + ), + :note_id_with_link => link_to("##{notification.note_id}", notification.note), + :note_text => notification.note_text + ) %> +

+ <% if notification.comment_body.present? %> +
+ <%= notification.comment_body.to_html %> +
+ <% end %> +
+
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 81cc721ae..3b2cba40e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -615,6 +615,15 @@ en: headline: Changeset comment description_with_summary_html: "User %{commenter_name_with_link} left a comment on changeset %{changeset_id_with_link} (\"%{changeset_summary}\")" description_without_summary_html: "User %{commenter_name_with_link} left a comment on changeset %{changeset_id_with_link}" + note_comment: + headline: + commented: Note comment + closed: Note resolved + reopened: Note reopened + description: + commented_html: "User %{commenter_name_with_link} left a comment on note %{note_id_with_link} (\"%{note_text}\")" + closed_html: "User %{commenter_name_with_link} resolved note %{note_id_with_link} (\"%{note_text}\")" + reopened_html: "User %{commenter_name_with_link} reopened note %{note_id_with_link} (\"%{note_text}\")" diary_entries: new: title: New Diary Entry diff --git a/test/controllers/notifications/note_comment_view_test.rb b/test/controllers/notifications/note_comment_view_test.rb new file mode 100644 index 000000000..7cb8865ce --- /dev/null +++ b/test/controllers/notifications/note_comment_view_test.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require "test_helper" + +module Notifications + class NoteCommentViewTest < ActionView::TestCase + def test_render_commented + note_comment = build_stubbed( + :note_comment, + :author => build_stubbed(:user), + :event => "commented" + ) + notification = build_stubbed(:notification, :record => note_comment) + notification_wrapper = UserNotifications::NoteCommentNotification.new(notification) + + render "notifications/note_comment", :notification => notification_wrapper + + assert_dom ".user-notification h2", "Note comment" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_dom ".user-notification blockquote", note_comment.body + end + + def test_render_closed_with_comment + comment_author = build_stubbed( + :user, + :display_name => "Helpful Commenter" + ) + note = build_stubbed(:note) + note_comment = build_stubbed( + :note_comment, + :author => comment_author, + :note => note, + :event => "closed" + ) + notification = build_stubbed(:notification, :record => note_comment) + notification_wrapper = UserNotifications::NoteCommentNotification.new(notification) + + render "notifications/note_comment", :notification => notification_wrapper + + assert_dom ".user-notification h2", "Note resolved" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_dom ".user-notification blockquote", note_comment.body + end + + def test_render_closed_without_comment + comment_author = build_stubbed( + :user, + :display_name => "Helpful Commenter" + ) + note = build_stubbed(:note) + note_comment = build_stubbed( + :note_comment, + :author => comment_author, + :note => note, + :event => "closed", + :body => "" + ) + notification = Struct.new(:record).new(note_comment) + notification_wrapper = UserNotifications::NoteCommentNotification.new(notification) + + render "notifications/note_comment", :notification => notification_wrapper + + assert_dom ".user-notification h2", "Note resolved" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_not_dom ".user-notification blockquote" + end + + def test_render_reopened + comment_author = build_stubbed( + :user, + :display_name => "Helpful Commenter" + ) + note = build_stubbed(:note) + note_comment = build_stubbed( + :note_comment, + :author => comment_author, + :note => note, + :event => "reopened", + :body => "" + ) + notification = Struct.new(:record).new(note_comment) + notification_wrapper = UserNotifications::NoteCommentNotification.new(notification) + + render "notifications/note_comment", :notification => notification_wrapper + + assert_dom ".user-notification h2", "Note reopened" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_not_dom ".user-notification blockquote" + end + end +end -- 2.47.3