From df8b25d2f55262b6f3aa6643abd0699a6adcf710 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Tue, 8 Jul 2014 17:39:36 -0400 Subject: [PATCH] FEATURE: don't demote trust level 3 users who were promoted less than SiteSetting.leader_promotion_min_duration days ago --- .../user_leader_requirements.js.handlebars | 3 -- app/jobs/scheduled/leader_promotions.rb | 7 ++++ app/models/user_history.rb | 3 +- config/locales/client.en.yml | 1 - config/locales/server.en.yml | 1 + config/site_settings.yml | 3 ++ lib/promotion.rb | 5 +++ spec/components/promotion_spec.rb | 12 ++++++ spec/jobs/leader_promotions_spec.rb | 38 ++++++++++++++++--- 9 files changed, 63 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/admin/templates/user_leader_requirements.js.handlebars b/app/assets/javascripts/admin/templates/user_leader_requirements.js.handlebars index 168e9dc0c53..16b19d94cfb 100644 --- a/app/assets/javascripts/admin/templates/user_leader_requirements.js.handlebars +++ b/app/assets/javascripts/admin/templates/user_leader_requirements.js.handlebars @@ -86,9 +86,6 @@ {{/unless}} {{else}} {{i18n admin.user.tl3_requirements.does_not_qualify}} - {{#if isLeader}} - {{i18n admin.user.tl3_requirements.will_be_demoted}} - {{/if}} {{/if}}

diff --git a/app/jobs/scheduled/leader_promotions.rb b/app/jobs/scheduled/leader_promotions.rb index 8a1d6eff719..12697f28f6e 100644 --- a/app/jobs/scheduled/leader_promotions.rb +++ b/app/jobs/scheduled/leader_promotions.rb @@ -7,6 +7,13 @@ module Jobs # Demotions demoted_user_ids = [] User.real.where(trust_level: TrustLevel.levels[:leader]).find_each do |u| + # Don't demote too soon after being promoted + next if UserHistory.for(u, :auto_trust_level_change) + .where('created_at >= ?', SiteSetting.leader_promotion_min_duration.to_i.days.ago) + .where(previous_value: TrustLevel.levels[:regular].to_s) + .where(new_value: TrustLevel.levels[:leader].to_s) + .exists? + unless Promotion.leader_met?(u) demoted_user_ids << u.id Promotion.new(u).change_trust_level!(:regular) diff --git a/app/models/user_history.rb b/app/models/user_history.rb index ab0c5bbaff0..7b57eddc0be 100644 --- a/app/models/user_history.rb +++ b/app/models/user_history.rb @@ -25,7 +25,8 @@ class UserHistory < ActiveRecord::Base :unsuspend_user, :facebook_no_email, :grant_badge, - :revoke_badge) + :revoke_badge, + :auto_trust_level_change) end # Staff actions is a subset of all actions, used to audit actions taken by staff users. diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 4f4ec57b7f2..57e9d556bdc 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1829,7 +1829,6 @@ en: qualifies: "Qualifies for trust level 3." will_be_promoted: "Will be promoted within 24 hours." does_not_qualify: "Doesn't qualify for trust level 3." - will_be_demoted: "Will be demoted within 24 hours." site_content: none: "Choose a type of content to begin editing." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 51e29baafab..d6b261f4d0a 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -816,6 +816,7 @@ en: leader_requires_topics_viewed_all_time: "The minimum total number of topics a user must have viewed to qualify for leader (3) trust level." leader_requires_posts_read_all_time: "The minimum total number of posts a user must have read to qualify for leader (3) trust level." leader_requires_max_flagged: "User must not have had more than x posts flagged by x different users in the last 100 days to qualify for promotion to leader (3) trust level, where x is this setting's value. (0 or higher)" + leader_promotion_min_duration: "The minimum number of days that a promotion to leader lasts before a user can be demoted." min_trust_to_create_topic: "The minimum trust level required to create a new topic." diff --git a/config/site_settings.yml b/config/site_settings.yml index 4108a3d1b27..1f888fd7502 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -483,6 +483,9 @@ trust: leader_requires_max_flagged: default: 5 min: 0 + leader_promotion_min_duration: + default: 14 + min: 0 security: use_https: false diff --git a/lib/promotion.rb b/lib/promotion.rb index 5ec5f802bf3..95879d6df47 100644 --- a/lib/promotion.rb +++ b/lib/promotion.rb @@ -62,6 +62,11 @@ class Promotion @user.transaction do if admin StaffActionLogger.new(admin).log_trust_level_change(@user, old_level, new_level) + else + UserHistory.create!( action: UserHistory.actions[:auto_trust_level_change], + target_user_id: @user.id, + previous_value: old_level, + new_value: new_level) end @user.save! @user.user_profile.recook_bio diff --git a/spec/components/promotion_spec.rb b/spec/components/promotion_spec.rb index 001270fb759..0188dbb3bbc 100644 --- a/spec/components/promotion_spec.rb +++ b/spec/components/promotion_spec.rb @@ -118,6 +118,12 @@ describe Promotion do promotion.review_regular }.to_not change { user.reload.trust_level } end + + it "doesn't log a trust level change" do + expect { + promotion.review_regular + }.to_not change { UserHistory.count } + end end context "qualifies for promotion" do @@ -133,6 +139,12 @@ describe Promotion do promotion.review_regular.should == true user.reload.trust_level.should == TrustLevel.levels[:leader] end + + it "logs a trust level change" do + expect { + promotion.review_regular + }.to change { UserHistory.where(action: UserHistory.actions[:auto_trust_level_change]).count }.by(1) + end end end diff --git a/spec/jobs/leader_promotions_spec.rb b/spec/jobs/leader_promotions_spec.rb index f0dae384051..9fa1aabd90f 100644 --- a/spec/jobs/leader_promotions_spec.rb +++ b/spec/jobs/leader_promotions_spec.rb @@ -19,10 +19,38 @@ describe Jobs::LeaderPromotions do run_job end - it "demotes tl3 user who doesn't qualify for tl3 anymore" do - tl3_user = Fabricate(:user, trust_level: TrustLevel.levels[:leader]) - LeaderRequirements.any_instance.stubs(:requirements_met?).returns(false) - Promotion.any_instance.expects(:change_trust_level!).with(:regular, anything).once - run_job + context "tl3 user who doesn't qualify for tl3 anymore" do + def create_leader_user + user = Fabricate(:user, trust_level: TrustLevel.levels[:regular]) + LeaderRequirements.any_instance.stubs(:requirements_met?).returns(true) + Promotion.new(user).review_regular.should == true + user + end + + before do + SiteSetting.stubs(:leader_promotion_min_duration).returns(3) + end + + it "demotes if was promoted more than X days ago" do + user = nil + Timecop.freeze(4.days.ago) do + user = create_leader_user + end + + LeaderRequirements.any_instance.stubs(:requirements_met?).returns(false) + run_job + user.reload.trust_level.should == TrustLevel.levels[:regular] + end + + it "doesn't demote if user was promoted recently" do + user = nil + Timecop.freeze(1.day.ago) do + user = create_leader_user + end + + LeaderRequirements.any_instance.stubs(:requirements_met?).returns(false) + run_job + user.reload.trust_level.should == TrustLevel.levels[:leader] + end end end