From 6e77107cccf1a7da63b1e482d84b0beca1361e96 Mon Sep 17 00:00:00 2001
From: Mark VanLandingham <markvanlan@gmail.com>
Date: Fri, 19 Jul 2024 10:53:12 -0500
Subject: [PATCH] DEV: Publish DiscourseEvent in TopicUser.track_visit for
 first visit (#27975)

---
 app/models/topic_user.rb       |  6 ++++--
 spec/models/topic_user_spec.rb | 18 ++++++++++++++----
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb
index 823f6b28f51..780f30a4c57 100644
--- a/app/models/topic_user.rb
+++ b/app/models/topic_user.rb
@@ -299,8 +299,10 @@ class TopicUser < ActiveRecord::Base
     def track_visit!(topic_id, user_id)
       now = DateTime.now
       rows = TopicUser.where(topic_id: topic_id, user_id: user_id).update_all(last_visited_at: now)
-
-      change(user_id, topic_id, last_visited_at: now, first_visited_at: now) if rows == 0
+      if rows == 0
+        change(user_id, topic_id, last_visited_at: now, first_visited_at: now)
+        DiscourseEvent.trigger(:user_first_visit_to_topic, user_id: user_id, topic_id: topic_id)
+      end
     end
 
     # Update the last read and the last seen post count, but only if it doesn't exist.
diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb
index 6954c17964c..640ef48d52f 100644
--- a/spec/models/topic_user_spec.rb
+++ b/spec/models/topic_user_spec.rb
@@ -186,23 +186,33 @@ RSpec.describe TopicUser do
   end
 
   describe "visited at" do
-    it "set upon initial visit" do
+    it "set upon initial visit and fires DiscourseEvent" do
       freeze_time yesterday
 
-      TopicUser.track_visit!(topic.id, user.id)
+      event =
+        DiscourseEvent
+          .track_events(:user_first_visit_to_topic) { TopicUser.track_visit!(topic.id, user.id) }
+          .first
+      expect(event[:params].first[:user_id]).to eq(user.id)
+      expect(event[:params].first[:topic_id]).to eq(topic.id)
 
       expect(topic_user.first_visited_at.to_i).to eq(yesterday.to_i)
       expect(topic_user.last_visited_at.to_i).to eq(yesterday.to_i)
     end
 
-    it "updates upon repeat visit" do
+    it "updates upon repeat visit and doesn't fire DiscourseEvent" do
       freeze_time yesterday
 
       TopicUser.track_visit!(topic.id, user.id)
 
       freeze_time Time.zone.now
 
-      TopicUser.track_visit!(topic.id, user.id)
+      events =
+        DiscourseEvent.track_events(:user_first_visit_to_topic) do
+          TopicUser.track_visit!(topic.id, user.id)
+        end
+      expect(events).to be_blank
+
       # reload is a no go
       topic_user = TopicUser.get(topic, user)
       expect(topic_user.first_visited_at.to_i).to eq(yesterday.to_i)