FIX: Skip whisper posts when updating topic like count (#10157)

FIX: Skip whisper posts when updating topic like count (#10157)

diff --git a/app/models/topic.rb b/app/models/topic.rb
index 643c48b..4088ab4 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -1071,7 +1071,13 @@ class Topic < ActiveRecord::Base
   end
 
   def update_action_counts
-    update_column(:like_count, Post.where(topic_id: id).sum(:like_count))
+    update_column(
+      :like_count,
+      Post
+        .where.not(post_type: Post.types[:whisper])
+        .where(topic_id: id)
+        .sum(:like_count)
+    )
   end
 
   def posters_summary(options = {}) # avatar lookup in options
diff --git a/db/migrate/20200707154522_fix_topic_like_count.rb b/db/migrate/20200707154522_fix_topic_like_count.rb
new file mode 100644
index 0000000..95dd170
--- /dev/null
+++ b/db/migrate/20200707154522_fix_topic_like_count.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class FixTopicLikeCount < ActiveRecord::Migration[6.0]
+  def up
+    return if DB.query_single("SELECT * FROM site_settings WHERE name = 'enable_whispers' AND value = 't'").empty?
+
+    DB.exec(<<~SQL, whisper: Post.types[:whisper])
+      UPDATE topics SET like_count = tbl.like_count
+      FROM (
+        SELECT topic_id, SUM(like_count) like_count
+        FROM posts
+        WHERE deleted_at IS NULL AND post_type <> :whisper
+        GROUP BY topic_id
+      ) AS tbl
+      WHERE topics.id = tbl.topic_id
+        AND topics.like_count <> tbl.like_count
+    SQL
+  end
+
+  def down
+    raise ActiveRecord::IrreversibleMigration
+  end
+end
diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb
index ead9621..dbe0c74 100644
--- a/spec/models/topic_spec.rb
+++ b/spec/models/topic_spec.rb
@@ -2634,4 +2634,26 @@ describe Topic do
       expect(@topic.auto_close_threshold_reached?).to eq(true)
     end
   end
+
+  describe '#update_action_counts' do
+    let(:topic) { Fabricate(:topic) }
+
+    it 'updates like count without including whisper posts' do
+      post = Fabricate(:post, topic: topic)
+      whisper_post = Fabricate(:post, topic: topic, post_type: Post.types[:whisper])
+
+      topic.update_action_counts
+      expect(topic.like_count).to eq(0)
+
+      PostAction.create!(post: post, user: user, post_action_type_id: PostActionType.types[:like])
+
+      topic.update_action_counts
+      expect(topic.like_count).to eq(1)
+
+      PostAction.create!(post: whisper_post, user: user, post_action_type_id: PostActionType.types[:like])
+
+      topic.update_action_counts
+      expect(topic.like_count).to eq(1)
+    end
+  end
 end

GitHub sha: 44927188

This commit appears in #10157 which was approved by eviltrout, ZogStriP, and ZogStriP. It was merged by SamSaffron.