From 4d0ac8636c73b06b605887e530cb8eaf773000a5 Mon Sep 17 00:00:00 2001
From: Martin Brennan <martin@discourse.org>
Date: Mon, 9 May 2022 16:19:18 +1000
Subject: [PATCH] FIX: Polymorphic bookmarks for new user narrative bot
 (#16683)

This commit allows the new user narrative bot to work
with polymorphic bookmarks, gated behind the
use_polymorphic_bookmarks site setting.
---
 .../new_user_narrative.rb                       |  2 --
 plugins/discourse-narrative-bot/plugin.rb       |  9 ++++++---
 .../new_user_narrative_spec.rb                  | 17 ++++++++++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb
index 3b2d5e48aab..98ef6e4c8eb 100644
--- a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb
+++ b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb
@@ -243,7 +243,6 @@ module DiscourseNarrativeBot
       post
     end
 
-    # TODO (martin) [POLYBOOK] Fix up narrative bot bookmark interactions in a separate PR.
     def missing_bookmark
       return unless valid_topic?(@post.topic_id)
       return if @post.user_id == self.discobot_user.id
@@ -254,7 +253,6 @@ module DiscourseNarrativeBot
       false
     end
 
-    # TODO (martin) [POLYBOOK] Fix up narrative bot bookmark interactions in a separate PR.
     def reply_to_bookmark
       return unless valid_topic?(@post.topic_id)
       return unless @post.user_id == self.discobot_user.id
diff --git a/plugins/discourse-narrative-bot/plugin.rb b/plugins/discourse-narrative-bot/plugin.rb
index 0d1c3a2b211..78c4d9188a8 100644
--- a/plugins/discourse-narrative-bot/plugin.rb
+++ b/plugins/discourse-narrative-bot/plugin.rb
@@ -281,10 +281,13 @@ after_initialize do
     end
   end
 
-  # TODO (martin) [POLYBOOK] Fix up narrative bot bookmark interactions in a separate PR.
   self.add_model_callback(Bookmark, :after_commit, on: :create) do
-    if self.post && self.user.enqueue_narrative_bot_job?
-      Jobs.enqueue(:bot_input, user_id: self.user_id, post_id: self.post_id, input: "bookmark")
+    if self.user.enqueue_narrative_bot_job?
+      if SiteSetting.use_polymorphic_bookmarks && self.bookmarkable_type == "Post"
+        Jobs.enqueue(:bot_input, user_id: self.user_id, post_id: self.bookmarkable_id, input: "bookmark")
+      elsif !SiteSetting.use_polymorphic_bookmarks && self.post.present?
+        Jobs.enqueue(:bot_input, user_id: self.user_id, post_id: self.post_id, input: "bookmark")
+      end
     end
   end
 
diff --git a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb
index a7a8abf06b2..ccebc8f6fbc 100644
--- a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb
+++ b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb
@@ -248,7 +248,22 @@ describe DiscourseNarrativeBot::NewUserNarrative do
         end
       end
 
-      it 'should create the right reply when bookmarks with reminders are enabled' do
+      it 'adds an after commit model callback to bookmark' do
+        Jobs.run_later!
+        bookmark = Fabricate(:bookmark, post: Fabricate(:post))
+        expect_job_enqueued(job: :bot_input, args: { user_id: bookmark.user_id, post_id: bookmark.post_id, input: "bookmark" })
+      end
+
+      it 'adds an after commit model callback to bookmark for polymorphic bookmarks (but only for post polymorphic bookmarks)' do
+        SiteSetting.use_polymorphic_bookmarks = true
+        Jobs.run_later!
+        bookmark = Fabricate(:bookmark, bookmarkable: Fabricate(:post))
+        expect_job_enqueued(job: :bot_input, args: { user_id: bookmark.user_id, post_id: bookmark.bookmarkable_id, input: "bookmark" })
+        bookmark2 = Fabricate(:bookmark, bookmarkable: Fabricate(:topic))
+        expect_not_enqueued_with(job: :bot_input, args: { user_id: bookmark.user_id, post_id: kind_of(Integer), input: "bookmark" })
+      end
+
+      it 'should create the right reply when the bookmark is created' do
         post.update!(user: discobot_user)
         narrative.expects(:enqueue_timeout_job).with(user)