diff --git a/app/models/card/mentions.rb b/app/models/card/mentions.rb new file mode 100644 index 000000000..cb3a34f17 --- /dev/null +++ b/app/models/card/mentions.rb @@ -0,0 +1,11 @@ +module Card::Mentions + extend ActiveSupport::Concern + + included do + include ::Mentions + + def mentionable? + published? + end + end +end diff --git a/app/models/comment/mentions.rb b/app/models/comment/mentions.rb new file mode 100644 index 000000000..a4a0fc927 --- /dev/null +++ b/app/models/comment/mentions.rb @@ -0,0 +1,11 @@ +module Comment::Mentions + extend ActiveSupport::Concern + + included do + include ::Mentions + + def mentionable? + card.published? + end + end +end diff --git a/app/models/concerns/mentions.rb b/app/models/concerns/mentions.rb index 86d017533..fa50de543 100644 --- a/app/models/concerns/mentions.rb +++ b/app/models/concerns/mentions.rb @@ -4,7 +4,7 @@ module Mentions included do has_many :mentions, as: :source, dependent: :destroy has_many :mentionees, through: :mentions - after_save_commit :create_mentions_later, if: :mentionable_content_changed? + after_save_commit :create_mentions_later, if: :should_create_mentions? end def create_mentions(mentioner: Current.user) @@ -48,6 +48,10 @@ module Mentions self.class.reflect_on_all_associations(:has_one).filter { it.klass == ActionText::RichText } end + def should_create_mentions? + mentionable? && mentionable_content_changed? + end + def mentionable_content_changed? rich_text_associations.any? { send(it.name)&.body_previously_changed? } end @@ -55,4 +59,9 @@ module Mentions def create_mentions_later Mention::CreateJob.perform_later(self, mentioner: Current.user) end + + # Template method + def mentionable? + true + end end diff --git a/test/models/concerns/mentions_test.rb b/test/models/concerns/mentions_test.rb index 006d77ec0..941aed171 100644 --- a/test/models/concerns/mentions_test.rb +++ b/test/models/concerns/mentions_test.rb @@ -5,20 +5,75 @@ class MentionsTest < ActiveSupport::TestCase Current.session = sessions(:david) end - test "create mentions from plain text mentions" do - assert_difference -> { Mention.count }, +1 do + test "don't create mentions when creating or updating drafts" do + assert_no_difference -> { Mention.count } do perform_enqueued_jobs only: Mention::CreateJob do - collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup, @david?" + card = collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup, @david?" + card.update description: "Any thoughts here @jz" end end end - test "create mentions from rich text mentions" do - assert_difference -> { Mention.count }, +1 do - perform_enqueued_jobs only: Mention::CreateJob do + test "create mentions from plain text mentions when publishing cards" do + perform_enqueued_jobs only: Mention::CreateJob do + card = assert_no_difference -> { Mention.count } do + collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup, @david?" + end + + assert_difference -> { Mention.count }, +1 do + card.published! + end + end + end + + test "create mentions from rich text mentions when publishing cards" do + perform_enqueued_jobs only: Mention::CreateJob do + card = assert_no_difference -> { Mention.count } do attachment = ActionText::Attachment.from_attachable(users(:david)) collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup, #{attachment.to_html}?" end + + assert_difference -> { Mention.count }, +1 do + card.published! + end + end + end + + test "don't create repeated mentions when updating cards" do + perform_enqueued_jobs only: Mention::CreateJob do + card = collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup, @david?" + + assert_difference -> { Mention.count }, +1 do + card.published! + end + + assert_no_difference -> { Mention.count } do + card.update description: "Any thoughts here @david" + end + + assert_difference -> { Mention.count }, +1 do + card.update description: "Any thoughts here @jz" + end + end + end + + test "create mentions from plain text mentions when posting comments" do + perform_enqueued_jobs only: Mention::CreateJob do + card = collections(:writebook).cards.create title: "Cleanup", description: "Some initial content", status: :published + + assert_difference -> { Mention.count }, +1 do + card.comments.create!(body: "Great work on this @david!") + end + end + end + + test "don't create mentions from comments when belonging to unpublished cards" do + perform_enqueued_jobs only: Mention::CreateJob do + card = collections(:writebook).cards.create title: "Cleanup", description: "Some initial content" + + assert_no_difference -> { Mention.count } do + card.comments.create!(body: "Great work on this @david!") + end end end @@ -37,6 +92,7 @@ class MentionsTest < ActiveSupport::TestCase test "mentionees are added as watchers of the card" do perform_enqueued_jobs only: Mention::CreateJob do card = collections(:writebook).cards.create title: "Cleanup", description: "Did you finish up with the cleanup @kevin?" + card.published! assert card.watchers.include?(users(:kevin)) end end