Adjusts the `minimum_flag_threshold` for TL3/TL4 actions

Adjusts the minimum_flag_threshold for TL3/TL4 actions

Before this patch, a high trust level user could flag something and have an action be taken, as well as skipping the flag queue.

Now, if a TL3/TL4 cause an action, the flag will skip the minimum visibility check and allow staff to review it.

diff --git a/app/models/post_action.rb b/app/models/post_action.rb
index 8efa750..1e533b0 100644
--- a/app/models/post_action.rb
+++ b/app/models/post_action.rb
@@ -52,6 +52,26 @@ class PostAction < ActiveRecord::Base
       .count
   end
 
+  # Forums can choose to apply a minimum number of flags required before it shows up in
+  # the admin interface. One exception is posts hidden by tl3/tl4 - we want those to
+  # show up even if the minimum visibility is not met.
+  def self.apply_minimum_visibility(relation)
+    return relation unless SiteSetting.min_flags_staff_visibility > 1
+
+    params = {
+      min_flags: SiteSetting.min_flags_staff_visibility,
+      hidden_reasons: Post.hidden_reasons.only(:flagged_by_tl3_user, :flagged_by_tl4_user).values
+    }
+
+    relation.having(<<~SQL, params)
+      (COUNT(*) >= :min_flags) OR
+      (SUM(CASE
+        WHEN posts.hidden_reason_id IN (:hidden_reasons) THEN 1
+        ELSE 0
+       END) > 0)
+    SQL
+  end
+
   def self.update_flagged_posts_count
     flagged_relation = PostAction.active
       .flags
@@ -61,10 +81,7 @@ class PostAction < ActiveRecord::Base
       .where('posts.user_id > 0')
       .group("posts.id")
 
-    if SiteSetting.min_flags_staff_visibility > 1
-      flagged_relation = flagged_relation
-        .having("count(*) >= ?", SiteSetting.min_flags_staff_visibility)
-    end
+    flagged_relation = apply_minimum_visibility(flagged_relation)
 
     posts_flagged_count = flagged_relation
       .pluck("posts.id")
@@ -638,6 +655,7 @@ class PostAction < ActiveRecord::Base
                       message_type: hiding_again ? :post_hidden_again : :post_hidden,
                       message_options: options)
     end
+    update_flagged_posts_count
   end
 
   def self.guess_hide_reason(post)
diff --git a/lib/flag_query.rb b/lib/flag_query.rb
index f3ef77e..cd0ed15 100644
--- a/lib/flag_query.rb
+++ b/lib/flag_query.rb
@@ -35,8 +35,8 @@ module FlagQuery
       .group(:post_id)
       .order('MIN(post_actions.created_at) DESC')
 
-    if opts[:filter] != "old" && SiteSetting.min_flags_staff_visibility > 1
-      post_ids_relation = post_ids_relation.having("count(*) >= ?", SiteSetting.min_flags_staff_visibility)
+    if opts[:filter] != "old"
+      post_ids_relation = PostAction.apply_minimum_visibility(post_ids_relation)
     end
 
     post_ids = post_ids_relation.pluck(:post_id).uniq
diff --git a/spec/components/flag_query_spec.rb b/spec/components/flag_query_spec.rb
index 428a5aa..aee1607 100644
--- a/spec/components/flag_query_spec.rb
+++ b/spec/components/flag_query_spec.rb
@@ -114,11 +114,11 @@ describe FlagQuery do
 
     it "respects `min_flags_staff_visibility`" do
       admin = Fabricate(:admin)
-      moderator = Fabricate(:moderator)
+      flagger = Fabricate(:user)
 
       post = create_post
 
-      PostAction.act(moderator, post, PostActionType.types[:spam])
+      PostAction.act(flagger, post, PostActionType.types[:spam])
 
       SiteSetting.min_flags_staff_visibility = 2
       posts, topics, users = FlagQuery.flagged_posts_report(admin)
@@ -133,5 +133,33 @@ describe FlagQuery do
       expect(users).to be_present
     end
 
+    it "respects `min_flags_staff_visibility` for tl3 hidden spam" do
+      admin = Fabricate(:admin)
+      tl3 = Fabricate(:user, trust_level: 3)
+      post = create_post
+
+      post.user.update_column(:trust_level, 0)
+      PostAction.act(tl3, post, PostActionType.types[:spam])
+
+      SiteSetting.min_flags_staff_visibility = 2
+      posts, topics, users = FlagQuery.flagged_posts_report(admin)
+      expect(posts).to be_present
+      expect(topics).to be_present
+      expect(users).to be_present
+    end
+
+    it "respects `min_flags_staff_visibility` for tl4 hidden posts" do
+      admin = Fabricate(:admin)
+      tl4 = Fabricate(:user, trust_level: 4)
+      post = create_post
+      PostAction.act(tl4, post, PostActionType.types[:spam])
+
+      SiteSetting.min_flags_staff_visibility = 2
+      posts, topics, users = FlagQuery.flagged_posts_report(admin)
+      expect(posts).to be_present
+      expect(topics).to be_present
+      expect(users).to be_present
+    end
+
   end
 end
diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb
index a99ecc7..823128d 100644
--- a/spec/models/post_action_spec.rb
+++ b/spec/models/post_action_spec.rb
@@ -160,6 +160,26 @@ describe PostAction do
       expect(PostAction.flagged_posts_count).to eq(1)
     end
 
+    it "tl3 hidden posts will supersede min_flags_staff_visibility" do
+      SiteSetting.min_flags_staff_visibility = 2
+      expect(PostAction.flagged_posts_count).to eq(0)
+
+      codinghorror.update_column(:trust_level, 3)
+      post.user.update_column(:trust_level, 0)
+      PostAction.act(codinghorror, post, PostActionType.types[:spam])
+      expect(PostAction.flagged_posts_count).to eq(1)
+    end
+
+    it "tl4 hidden posts will supersede min_flags_staff_visibility" do
+      SiteSetting.min_flags_staff_visibility = 2
+      expect(PostAction.flagged_posts_count).to eq(0)
+
+      codinghorror.update_column(:trust_level, 4)
+      PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
+
+      expect(PostAction.flagged_posts_count).to eq(1)
+    end
+
     it "should reset counts when a topic is deleted" do
       PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
       post.topic.trash!

GitHub sha: 5eaf3cb1

1 Like