From ca3792221a33cc5142d450cea4b692d41f75bab2 Mon Sep 17 00:00:00 2001
From: Jan Cernik <66427541+jancernik@users.noreply.github.com>
Date: Thu, 14 Dec 2023 15:39:28 -0300
Subject: [PATCH] FIX: Do not notify users for quoted mentions in chat (#24902)

---
 plugins/chat/lib/chat/parsed_mentions.rb      | 12 ++-
 .../spec/lib/chat/parsed_mentions_spec.rb     | 94 +++++++++++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/plugins/chat/lib/chat/parsed_mentions.rb b/plugins/chat/lib/chat/parsed_mentions.rb
index cb66917071c..b3f80ce6eb9 100644
--- a/plugins/chat/lib/chat/parsed_mentions.rb
+++ b/plugins/chat/lib/chat/parsed_mentions.rb
@@ -107,11 +107,19 @@ module Chat
     end
 
     def parse_mentions(message)
-      Nokogiri::HTML5.fragment(message.cooked).css(".mention").map(&:text)
+      cooked_stripped(message).css(".mention").map(&:text)
     end
 
     def parse_group_mentions(message)
-      Nokogiri::HTML5.fragment(message.cooked).css(".mention-group").map(&:text)
+      cooked_stripped(message).css(".mention-group").map(&:text)
+    end
+
+    def cooked_stripped(message)
+      cooked = Nokogiri::HTML5.fragment(message.cooked)
+      cooked.css(
+        ".chat-transcript .mention, .chat-transcript .mention-group, aside.quote .mention, aside.quote .mention-group",
+      ).remove
+      cooked
     end
 
     def normalize(mentions)
diff --git a/plugins/chat/spec/lib/chat/parsed_mentions_spec.rb b/plugins/chat/spec/lib/chat/parsed_mentions_spec.rb
index 8c5c4493310..be894fb8eb6 100644
--- a/plugins/chat/spec/lib/chat/parsed_mentions_spec.rb
+++ b/plugins/chat/spec/lib/chat/parsed_mentions_spec.rb
@@ -9,6 +9,22 @@ RSpec.describe Chat::ParsedMentions do
   fab!(:not_a_channel_member) { Fabricate(:user) }
   fab!(:chat_channel)
 
+  def message_quote_with_mentions(mentions)
+    <<~MARKDOWN
+    [chat quote="jan;100;2023-10-10T13:00:00Z"]
+    message mentioning #{mentions.map { |m| "@#{m}" }.join(" ")}
+    [/chat]
+    MARKDOWN
+  end
+
+  def post_quote_with_mentions(mentions)
+    <<~MARKDOWN
+    [quote="jan, post:1, topic:10"]
+    message mentioning #{mentions.map { |m| "@#{m}" }.join(" ")}
+    [/quote]
+    MARKDOWN
+  end
+
   before do
     chat_channel.add(channel_member_1)
     chat_channel.add(channel_member_2)
@@ -46,6 +62,24 @@ RSpec.describe Chat::ParsedMentions do
 
       expect(result).to be_empty
     end
+
+    it "returns an empty list when quoting a message with global mentions" do
+      message = create_message(message_quote_with_mentions(["all"]))
+
+      mentions = described_class.new(message)
+      result = mentions.global_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
+
+    it "returns an empty list when quoting a post with global mentions" do
+      message = create_message(post_quote_with_mentions(["all"]))
+
+      mentions = described_class.new(message)
+      result = mentions.global_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
   end
 
   describe "#here_mentions" do
@@ -82,6 +116,24 @@ RSpec.describe Chat::ParsedMentions do
 
       expect(result).to be_empty
     end
+
+    it "returns an empty list when quoting a message with here mentions" do
+      message = create_message(message_quote_with_mentions(["here"]))
+
+      mentions = described_class.new(message)
+      result = mentions.here_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
+
+    it "returns an empty list when quoting a post with here mentions" do
+      message = create_message(post_quote_with_mentions(["here"]))
+
+      mentions = described_class.new(message)
+      result = mentions.here_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
   end
 
   describe "#direct_mentions" do
@@ -121,6 +173,30 @@ RSpec.describe Chat::ParsedMentions do
 
       expect(result).to be_empty
     end
+
+    it "returns an empty list when quoting a message with mentioned users" do
+      message =
+        create_message(
+          message_quote_with_mentions([channel_member_1.username, channel_member_2.username]),
+        )
+
+      mentions = described_class.new(message)
+      result = mentions.direct_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
+
+    it "returns an empty list when quoting a post with mentioned users" do
+      message =
+        create_message(
+          post_quote_with_mentions([channel_member_1.username, channel_member_2.username]),
+        )
+
+      mentions = described_class.new(message)
+      result = mentions.direct_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
   end
 
   describe "#group_mentions" do
@@ -166,6 +242,24 @@ RSpec.describe Chat::ParsedMentions do
 
       expect(result).to be_empty
     end
+
+    it "returns an empty list when quoting a message with a mentioned group" do
+      message = create_message(message_quote_with_mentions([group1.name]))
+
+      mentions = described_class.new(message)
+      result = mentions.group_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
+
+    it "returns an empty list when quoting a post with a mentioned group" do
+      message = create_message(post_quote_with_mentions([group1.name]))
+
+      mentions = described_class.new(message)
+      result = mentions.group_mentions.pluck(:username)
+
+      expect(result).to be_empty
+    end
   end
 
   def create_message(text, **extra_args)