FEATURE: Permit users who had no penalties in last 6 months to be TL3. (#7892)

FEATURE: Permit users who had no penalties in last 6 months to be TL3. (#7892)

Previously, users who had any penalties (were silenced or suspended) were not allowed to promote to Trust Level 3.

There is also a more subtle change here: if users were silenced or suspended and then the operation was reverted (user was un-silenced or un-suspended), then it would have been like the user was never penalized in the first place. This is no longer the case. To forgive a user earlier, administrators can use “Clear Penalty History” feature.

Lastly, Jobs::UnsilenceUsers will automatically unsilence any users who should no longer be silenced (silenced_till < now()). This made it so silence_count - unsilence_count == 0 for any user who is not silenced, which defeated the purpose of this TL3 requirement.

diff --git a/app/models/trust_level3_requirements.rb b/app/models/trust_level3_requirements.rb
index 0690a58..bfd70fe 100644
--- a/app/models/trust_level3_requirements.rb
+++ b/app/models/trust_level3_requirements.rb
@@ -20,6 +20,7 @@ class TrustLevel3Requirements
   include ActiveModel::Serialization
 
   LOW_WATER_MARK = 0.9
+  FORGIVENESS_PERIOD = 6.months
 
   attr_accessor :days_visited, :min_days_visited,
                 :num_topics_replied_to, :min_topics_replied_to,
@@ -99,29 +100,18 @@ class TrustLevel3Requirements
     args = {
       user_id: @user.id,
       silence_user: UserHistory.actions[:silence_user],
-      unsilence_user: UserHistory.actions[:unsilence_user],
       suspend_user: UserHistory.actions[:suspend_user],
-      unsuspend_user: UserHistory.actions[:unsuspend_user]
+      since: FORGIVENESS_PERIOD.ago
     }
 
     sql = <<~SQL
-      SELECT SUM(
-          CASE
-            WHEN action = :silence_user THEN 1
-            WHEN action = :unsilence_user THEN -1
-            ELSE 0
-          END
-        ) AS silence_count,
-        SUM(
-          CASE
-            WHEN action = :suspend_user THEN 1
-            WHEN action = :unsuspend_user THEN -1
-            ELSE 0
-          END
-        ) AS suspend_count
+      SELECT
+        SUM(CASE WHEN action = :silence_user THEN 1 ELSE 0 END) AS silence_count,
+        SUM(CASE WHEN action = :suspend_user THEN 1 ELSE 0 END) AS suspend_count
       FROM user_histories AS uh
       WHERE uh.target_user_id = :user_id
-        AND uh.action IN (:silence_user, :unsilence_user, :suspend_user, :unsuspend_user)
+        AND uh.action IN (:silence_user, :suspend_user)
+        AND uh.created_at > :since
     SQL
 
     PenaltyCounts.new(DB.query_hash(sql, args).first)
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index a728f18..1ebecc9 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -4094,8 +4094,8 @@ en:
           likes_received: "Likes Received"
           likes_received_days: "Likes Received: unique days"
           likes_received_users: "Likes Received: unique users"
-          suspended: "Suspended (all time)"
-          silenced: "Silenced (all time)"
+          suspended: "Suspended (last 6 months)"
+          silenced: "Silenced (last 6 months)"
           qualifies: "Qualifies for trust level 3."
           does_not_qualify: "Doesn't qualify for trust level 3."
           will_be_promoted: "Will be promoted soon."
diff --git a/spec/models/trust_level3_requirements_spec.rb b/spec/models/trust_level3_requirements_spec.rb
index eea2e07..3f12401 100644
--- a/spec/models/trust_level3_requirements_spec.rb
+++ b/spec/models/trust_level3_requirements_spec.rb
@@ -24,18 +24,18 @@ describe TrustLevel3Requirements do
 
     describe "penalty_counts" do
 
-      it "returns if the user has ever been silenced" do
+      it "returns if the user has been silenced in last 6 months" do
         expect(tl3_requirements.penalty_counts.silenced).to eq(0)
         expect(tl3_requirements.penalty_counts.total).to eq(0)
         UserSilencer.new(user, moderator).silence
         expect(tl3_requirements.penalty_counts.silenced).to eq(1)
         expect(tl3_requirements.penalty_counts.total).to eq(1)
         UserSilencer.new(user, moderator).unsilence
-        expect(tl3_requirements.penalty_counts.silenced).to eq(0)
-        expect(tl3_requirements.penalty_counts.total).to eq(0)
+        expect(tl3_requirements.penalty_counts.silenced).to eq(1)
+        expect(tl3_requirements.penalty_counts.total).to eq(1)
       end
 
-      it "returns if the user has ever been suspended" do
+      it "returns if the user has been suspended in last 6 months" do
         user.save!
 
         expect(tl3_requirements.penalty_counts.suspended).to eq(0)
@@ -54,8 +54,29 @@ describe TrustLevel3Requirements do
           action: UserHistory.actions[:unsuspend_user]
         )
 
+        expect(tl3_requirements.penalty_counts.suspended).to eq(1)
+        expect(tl3_requirements.penalty_counts.total).to eq(1)
+      end
+
+      it "does not return if the user been silenced or suspended over 6 months ago" do
+        freeze_time 1.year.ago do
+          UserSilencer.new(user, moderator, silenced_till: 1.months.from_now).silence
+          UserHistory.create!(target_user_id: user.id, action: UserHistory.actions[:suspend_user])
+        end
+
+        expect(tl3_requirements.penalty_counts.silenced).to eq(0)
         expect(tl3_requirements.penalty_counts.suspended).to eq(0)
         expect(tl3_requirements.penalty_counts.total).to eq(0)
+
+        freeze_time 3.months.ago do
+          UserSilencer.new(user).unsilence
+          UserSilencer.new(user, moderator, silenced_till: 1.months.from_now).silence
+          UserHistory.create!(target_user_id: user.id, action: UserHistory.actions[:suspend_user])
+        end
+
+        expect(tl3_requirements.penalty_counts.silenced).to eq(1)
+        expect(tl3_requirements.penalty_counts.suspended).to eq(1)
+        expect(tl3_requirements.penalty_counts.total).to eq(2)
       end
     end

GitHub sha: 30c49150

1 Like