FIX: Sensitivity did not work by default

Forums without previously calculated scores would return the same values
for low/medium/high sensitivity. Now those are scaled based on the
default value.

The default value has also been changed from 10.0 to 12.5 based on
observing data from live discourse forums.
This commit is contained in:
Robin Ward
2019-09-19 13:17:00 -04:00
parent 7ad338e3e6
commit 3c6a5836c2
3 changed files with 34 additions and 23 deletions

View File

@ -78,6 +78,12 @@ class Reviewable < ActiveRecord::Base
) )
end end
# This number comes from looking at forums in the wild and what numbers work.
# As the site accumulates real data it'll be based on the site activity instead.
def self.typical_sensitivity
12.5
end
# Generate `pending?`, `rejected?`, etc helper methods # Generate `pending?`, `rejected?`, etc helper methods
statuses.each do |name, id| statuses.each do |name, id|
define_method("#{name}?") { status == id } define_method("#{name}?") { status == id }
@ -195,11 +201,13 @@ class Reviewable < ActiveRecord::Base
return Float::MAX if sensitivity == 0 return Float::MAX if sensitivity == 0
ratio = sensitivity / Reviewable.sensitivity[:low].to_f ratio = sensitivity / Reviewable.sensitivity[:low].to_f
high = PluginStore.get('reviewables', "priority_#{Reviewable.priorities[:high]}") high = (
return (10.0 * scale) if high.nil? PluginStore.get('reviewables', "priority_#{Reviewable.priorities[:high]}") ||
typical_sensitivity
).to_f
# We want this to be hard to reach # We want this to be hard to reach
(high.to_f * ratio) * scale ((high.to_f * ratio) * scale).truncate(2)
end end
def self.sensitivity_score(sensitivity, scale: 1.0) def self.sensitivity_score(sensitivity, scale: 1.0)

View File

@ -155,6 +155,7 @@ private
def auto_hide_if_needed def auto_hide_if_needed
return if @post.hidden? return if @post.hidden?
return if !@created_by.staff? && @post.user&.staff? return if !@created_by.staff? && @post.user&.staff?
return unless PostActionType.auto_action_flag_types.include?(@post_action_name)
# Special case: If you have TL3 and the user is TL0, and the flag is spam, # Special case: If you have TL3 and the user is TL0, and the flag is spam,
# hide it immediately. # hide it immediately.
@ -163,11 +164,11 @@ private
@post.user&.trust_level == TrustLevel[0] @post.user&.trust_level == TrustLevel[0]
@post.hide!(@post_action_type_id, Post.hidden_reasons[:flagged_by_tl3_user]) @post.hide!(@post_action_type_id, Post.hidden_reasons[:flagged_by_tl3_user])
return return
elsif PostActionType.auto_action_flag_types.include?(@post_action_name) end
score = ReviewableFlaggedPost.find_by(target: @post)&.score || 0
if score >= Reviewable.score_required_to_hide_post score = ReviewableFlaggedPost.find_by(target: @post)&.score || 0
@post.hide!(@post_action_type_id) if score >= Reviewable.score_required_to_hide_post
end @post.hide!(@post_action_type_id)
end end
end end

View File

@ -339,11 +339,13 @@ RSpec.describe Reviewable, type: :model do
expect(Reviewable.score_required_to_hide_post).to eq(40.0) expect(Reviewable.score_required_to_hide_post).to eq(40.0)
end end
it "returns 10 if we can't calculated any percentiles" do it "returns a default if we can't calculated any percentiles" do
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
expect(Reviewable.score_required_to_hide_post).to eq(10.0) expect(Reviewable.score_required_to_hide_post).to eq(12.5)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium]
expect(Reviewable.score_required_to_hide_post).to eq(10.0) expect(Reviewable.score_required_to_hide_post).to eq(8.33)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high]
expect(Reviewable.score_required_to_hide_post).to eq(4.16)
end end
it "returns a fraction of the high percentile" do it "returns a fraction of the high percentile" do
@ -360,37 +362,37 @@ RSpec.describe Reviewable, type: :model do
end end
context ".spam_score_to_silence_new_user" do context ".spam_score_to_silence_new_user" do
it "returns 6 if we can't calculated any percentiles" do it "returns a default value if we can't calculated any percentiles" do
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0) expect(Reviewable.spam_score_to_silence_new_user).to eq(7.5)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium]
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0) expect(Reviewable.spam_score_to_silence_new_user).to eq(4.99)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high]
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0) expect(Reviewable.spam_score_to_silence_new_user).to eq(2.49)
end end
it "returns a fraction of the high percentile" do it "returns a fraction of the high percentile" do
Reviewable.set_priorities(high: 100.0) Reviewable.set_priorities(high: 100.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled]
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(Float::MAX) expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(Float::MAX)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(60.0) expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(60.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium]
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(39.99) expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(39.99)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high]
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(19.99) expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(19.99)
end end
end end
context ".score_to_auto_close_topic" do context ".score_to_auto_close_topic" do
it "returns 25 if we can't calculated any percentiles" do it "returns the default if we can't calculated any percentiles" do
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
expect(Reviewable.score_to_auto_close_topic).to eq(25.0) expect(Reviewable.score_to_auto_close_topic).to eq(31.25)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium]
expect(Reviewable.score_to_auto_close_topic).to eq(25.0) expect(Reviewable.score_to_auto_close_topic).to eq(20.83)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high]
expect(Reviewable.score_to_auto_close_topic).to eq(25.0) expect(Reviewable.score_to_auto_close_topic).to eq(10.41)
end end
it "returns a fraction of the high percentile" do it "returns a fraction of the high percentile" do