DEV: Use AR enums in reviewables related code

This is the first patch of many to replace our custom enums in Ruby by
the ones provided by `ActiveRecord`.
This commit is contained in:
Loïc Guitaut 2021-12-08 18:12:24 +01:00 committed by Loïc Guitaut
parent 0c743a591f
commit 26fe047724
36 changed files with 220 additions and 228 deletions

View File

@ -268,7 +268,7 @@ protected
end end
def allowed_statuses def allowed_statuses
@allowed_statuses ||= (%i[reviewed all] + Reviewable.statuses.keys) @allowed_statuses ||= (%i[reviewed all] + Reviewable.statuses.symbolize_keys.keys)
end end
def version_required def version_required

View File

@ -361,7 +361,7 @@ module Jobs
yield [ yield [
rev.id, rev.id,
Reviewable.statuses[rev.status], rev.status,
rev.category_id, rev.category_id,
rev.topic_id, rev.topic_id,
rev.payload['raw'], rev.payload['raw'],

View File

@ -11,7 +11,7 @@ module Jobs
return unless SiteSetting.auto_handle_queued_age.to_i > 0 return unless SiteSetting.auto_handle_queued_age.to_i > 0
Reviewable Reviewable
.where(status: Reviewable.statuses[:pending]) .pending
.where('created_at < ?', SiteSetting.auto_handle_queued_age.to_i.days.ago) .where('created_at < ?', SiteSetting.auto_handle_queued_age.to_i.days.ago)
.each do |reviewable| .each do |reviewable|

View File

@ -27,7 +27,7 @@ module Jobs
end end
def should_notify_ids def should_notify_ids
ReviewableQueuedPost.where(status: Reviewable.statuses[:pending]).where( ReviewableQueuedPost.pending.where(
'created_at < ?', SiteSetting.notify_about_queued_posts_after.to_f.hours.ago 'created_at < ?', SiteSetting.notify_about_queued_posts_after.to_f.hours.ago
).pluck(:id) ).pluck(:id)
end end

View File

@ -15,11 +15,7 @@ class Jobs::ReviewablePriorities < ::Jobs::Scheduled
def execute(args) def execute(args)
min_priority_threshold = SiteSetting.reviewable_low_priority_threshold min_priority_threshold = SiteSetting.reviewable_low_priority_threshold
reviewable_count = Reviewable.where( reviewable_count = Reviewable.approved.where("score > ?", min_priority_threshold).count
"score > ? AND status = ?",
min_priority_threshold,
Reviewable.statuses[:approved]
).count
return if reviewable_count < self.class.min_reviewables return if reviewable_count < self.class.min_reviewables
res = DB.query_single(<<~SQL, target_count: self.class.target_count, min_priority: min_priority_threshold) res = DB.query_single(<<~SQL, target_count: self.class.target_count, min_priority: min_priority_threshold)

View File

@ -80,7 +80,7 @@ module Roleable
private private
def auto_approve_user def auto_approve_user
if reviewable = ReviewableUser.find_by(target: self, status: Reviewable.statuses[:pending]) if reviewable = ReviewableUser.pending.find_by(target: self)
reviewable.perform(Discourse.system_user, :approve_user, send_email: false) reviewable.perform(Discourse.system_user, :approve_user, send_email: false)
else else
ReviewableUser.set_approved_fields!(self, Discourse.system_user) ReviewableUser.set_approved_fields!(self, Discourse.system_user)

View File

@ -31,6 +31,25 @@ class Reviewable < ActiveRecord::Base
has_many :reviewable_histories has_many :reviewable_histories
has_many :reviewable_scores, -> { order(created_at: :desc) } has_many :reviewable_scores, -> { order(created_at: :desc) }
enum :status, {
pending: 0,
approved: 1,
rejected: 2,
ignored: 3,
deleted: 4
}
enum :priority, {
low: 0,
medium: 5,
high: 10
}, scopes: false, suffix: true
enum :sensitivity, {
disabled: 0,
low: 9,
medium: 6,
high: 3
}, scopes: false, suffix: true
after_create do after_create do
log_history(:created, created_by) log_history(:created, created_by)
end end
@ -48,47 +67,12 @@ class Reviewable < ActiveRecord::Base
{} {}
end end
# The gaps are in case we want more precision in the future
def self.priorities
@priorities ||= Enum.new(
low: 0,
medium: 5,
high: 10
)
end
# The gaps are in case we want more precision in the future
def self.sensitivity
@sensitivity ||= Enum.new(
disabled: 0,
low: 9,
medium: 6,
high: 3
)
end
def self.statuses
@statuses ||= Enum.new(
pending: 0,
approved: 1,
rejected: 2,
ignored: 3,
deleted: 4
)
end
# This number comes from looking at forums in the wild and what numbers work. # 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. # As the site accumulates real data it'll be based on the site activity instead.
def self.typical_sensitivity def self.typical_sensitivity
12.5 12.5
end end
# Generate `pending?`, `rejected?`, etc helper methods
statuses.each do |name, id|
define_method("#{name}?") { status == id }
singleton_class.define_method(name) { where(status: id) }
end
def self.default_visible def self.default_visible
where("score >= ?", min_score_for_priority) where("score >= ?", min_score_for_priority)
end end
@ -211,7 +195,7 @@ class Reviewable < ActiveRecord::Base
rs = reviewable_scores.new( rs = reviewable_scores.new(
user: user, user: user,
status: ReviewableScore.statuses[:pending], status: :pending,
reviewable_score_type: reviewable_score_type, reviewable_score_type: reviewable_score_type,
score: sub_total, score: sub_total,
user_accuracy_bonus: user_accuracy_bonus, user_accuracy_bonus: user_accuracy_bonus,
@ -232,7 +216,7 @@ class Reviewable < ActiveRecord::Base
def self.set_priorities(values) def self.set_priorities(values)
values.each do |k, v| values.each do |k, v|
id = Reviewable.priorities[k] id = priorities[k]
PluginStore.set('reviewables', "priority_#{id}", v) unless id.nil? PluginStore.set('reviewables', "priority_#{id}", v) unless id.nil?
end end
end end
@ -240,9 +224,9 @@ class Reviewable < ActiveRecord::Base
def self.sensitivity_score_value(sensitivity, scale) def self.sensitivity_score_value(sensitivity, scale)
return Float::MAX if sensitivity == 0 return Float::MAX if sensitivity == 0
ratio = sensitivity / Reviewable.sensitivity[:low].to_f ratio = sensitivity / sensitivities[:low].to_f
high = ( high = (
PluginStore.get('reviewables', "priority_#{Reviewable.priorities[:high]}") || PluginStore.get('reviewables', "priority_#{priorities[:high]}") ||
typical_sensitivity typical_sensitivity
).to_f ).to_f
@ -271,7 +255,7 @@ class Reviewable < ActiveRecord::Base
def self.min_score_for_priority(priority = nil) def self.min_score_for_priority(priority = nil)
priority ||= SiteSetting.reviewable_default_visibility priority ||= SiteSetting.reviewable_default_visibility
id = Reviewable.priorities[priority.to_sym] id = priorities[priority]
return 0.0 if id.nil? return 0.0 if id.nil?
PluginStore.get('reviewables', "priority_#{id}").to_f PluginStore.get('reviewables', "priority_#{id}").to_f
end end
@ -282,7 +266,7 @@ class Reviewable < ActiveRecord::Base
def log_history(reviewable_history_type, performed_by, edited: nil) def log_history(reviewable_history_type, performed_by, edited: nil)
reviewable_histories.create!( reviewable_histories.create!(
reviewable_history_type: ReviewableHistory.types[reviewable_history_type], reviewable_history_type: reviewable_history_type,
status: status, status: status,
created_by: performed_by, created_by: performed_by,
edited: edited edited: edited
@ -386,9 +370,7 @@ class Reviewable < ActiveRecord::Base
end end
def transition_to(status_symbol, performed_by) def transition_to(status_symbol, performed_by)
was_pending = pending? self.status = status_symbol
self.status = Reviewable.statuses[status_symbol]
save! save!
log_history(:transitioned, performed_by) log_history(:transitioned, performed_by)
@ -402,7 +384,7 @@ class Reviewable < ActiveRecord::Base
) )
end end
was_pending status_previously_changed?(from: "pending")
end end
def post_options def post_options
@ -503,13 +485,13 @@ class Reviewable < ActiveRecord::Base
SELECT reviewable_id SELECT reviewable_id
FROM reviewable_histories FROM reviewable_histories
WHERE reviewable_history_type = #{ReviewableHistory.types[:transitioned]} AND WHERE reviewable_history_type = #{ReviewableHistory.types[:transitioned]} AND
status <> #{Reviewable.statuses[:pending]} AND created_by_id = #{reviewed_by_id} status <> #{statuses[:pending]} AND created_by_id = #{reviewed_by_id}
) AS rh ON rh.reviewable_id = reviewables.id ) AS rh ON rh.reviewable_id = reviewables.id
SQL SQL
) )
end end
min_score = Reviewable.min_score_for_priority(priority) min_score = min_score_for_priority(priority)
if min_score > 0 && status == :pending if min_score > 0 && status == :pending
result = result.where("reviewables.score >= ? OR reviewables.force_review", min_score) result = result.where("reviewables.score >= ? OR reviewables.force_review", min_score)
@ -678,8 +660,8 @@ class Reviewable < ActiveRecord::Base
DB.query( DB.query(
sql, sql,
topic_id: topic_id, topic_id: topic_id,
pending: Reviewable.statuses[:pending], pending: self.class.statuses[:pending],
approved: Reviewable.statuses[:approved] approved: self.class.statuses[:approved]
) )
self.score = result[0].score self.score = result[0].score
@ -776,7 +758,7 @@ end
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# type :string not null # type :string not null
# status :integer default(0), not null # status :integer default("pending"), not null
# created_by_id :integer not null # created_by_id :integer not null
# reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_moderator :boolean default(FALSE), not null
# reviewable_by_group_id :integer # reviewable_by_group_id :integer

View File

@ -13,7 +13,7 @@ class ReviewableFlaggedPost < Reviewable
def self.counts_for(posts) def self.counts_for(posts)
result = {} result = {}
counts = DB.query(<<~SQL, pending: Reviewable.statuses[:pending]) counts = DB.query(<<~SQL, pending: statuses[:pending])
SELECT r.target_id AS post_id, SELECT r.target_id AS post_id,
rs.reviewable_score_type, rs.reviewable_score_type,
count(*) as total count(*) as total
@ -336,7 +336,7 @@ end
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# type :string not null # type :string not null
# status :integer default(0), not null # status :integer default("pending"), not null
# created_by_id :integer not null # created_by_id :integer not null
# reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_moderator :boolean default(FALSE), not null
# reviewable_by_group_id :integer # reviewable_by_group_id :integer

View File

@ -4,16 +4,22 @@ class ReviewableHistory < ActiveRecord::Base
belongs_to :reviewable belongs_to :reviewable
belongs_to :created_by, class_name: 'User' belongs_to :created_by, class_name: 'User'
def self.types enum status: {
@types ||= Enum.new( pending: 0,
created: 0, approved: 1,
transitioned: 1, rejected: 2,
edited: 2, ignored: 3,
claimed: 3, deleted: 4
unclaimed: 4 }
)
end
alias_attribute :type, :reviewable_history_type
enum type: {
created: 0,
transitioned: 1,
edited: 2,
claimed: 3,
unclaimed: 4
}
end end
# == Schema Information # == Schema Information

View File

@ -8,7 +8,7 @@ class ReviewablePost < Reviewable
def self.queue_for_review_if_possible(post, created_or_edited_by) def self.queue_for_review_if_possible(post, created_or_edited_by)
return unless SiteSetting.review_every_post return unless SiteSetting.review_every_post
return if post.post_type != Post.types[:regular] || post.topic.private_message? return if post.post_type != Post.types[:regular] || post.topic.private_message?
return if Reviewable.where(target: post, status: Reviewable.statuses[:pending]).exists? return if Reviewable.pending.where(target: post).exists?
return if created_or_edited_by.bot? || created_or_edited_by.staff? || created_or_edited_by.has_trust_level?(TrustLevel[4]) return if created_or_edited_by.bot? || created_or_edited_by.staff? || created_or_edited_by.has_trust_level?(TrustLevel[4])
system_user = Discourse.system_user system_user = Discourse.system_user
@ -116,7 +116,7 @@ end
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# type :string not null # type :string not null
# status :integer default(0), not null # status :integer default("pending"), not null
# created_by_id :integer not null # created_by_id :integer not null
# reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_moderator :boolean default(FALSE), not null
# reviewable_by_group_id :integer # reviewable_by_group_id :integer

View File

@ -174,7 +174,7 @@ class ReviewableQueuedPost < Reviewable
def status_changed_from_or_to_pending? def status_changed_from_or_to_pending?
saved_change_to_id?(from: nil) && pending? || saved_change_to_id?(from: nil) && pending? ||
saved_change_to_status?(from: self.class.statuses[:pending]) saved_change_to_status?(from: "pending")
end end
end end
@ -184,7 +184,7 @@ end
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# type :string not null # type :string not null
# status :integer default(0), not null # status :integer default("pending"), not null
# created_by_id :integer not null # created_by_id :integer not null
# reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_moderator :boolean default(FALSE), not null
# reviewable_by_group_id :integer # reviewable_by_group_id :integer

View File

@ -6,6 +6,13 @@ class ReviewableScore < ActiveRecord::Base
belongs_to :reviewed_by, class_name: 'User' belongs_to :reviewed_by, class_name: 'User'
belongs_to :meta_topic, class_name: 'Topic' belongs_to :meta_topic, class_name: 'Topic'
enum status: {
pending: 0,
agreed: 1,
disagreed: 2,
ignored: 3
}
# To keep things simple the types correspond to `PostActionType` for backwards # To keep things simple the types correspond to `PostActionType` for backwards
# compatibility, but we can add extra reasons for scores. # compatibility, but we can add extra reasons for scores.
def self.types def self.types
@ -29,15 +36,6 @@ class ReviewableScore < ActiveRecord::Base
end end
end end
def self.statuses
@statuses ||= Enum.new(
pending: 0,
agreed: 1,
disagreed: 2,
ignored: 3
)
end
def self.score_transitions def self.score_transitions
{ {
approved: statuses[:agreed], approved: statuses[:agreed],
@ -46,12 +44,6 @@ class ReviewableScore < ActiveRecord::Base
} }
end end
# Generate `pending?`, `rejected?`, etc helper methods
statuses.each do |name, id|
define_method("#{name}?") { status == id }
singleton_class.define_method(name) { where(status: id) }
end
def score_type def score_type
Reviewable::Collection::Item.new(reviewable_score_type) Reviewable::Collection::Item.new(reviewable_score_type)
end end

View File

@ -7,7 +7,7 @@ class ReviewableSensitivitySetting < EnumSiteSetting
end end
def self.values def self.values
Reviewable.sensitivity.map do |p| Reviewable.sensitivities.map do |p|
{ name: I18n.t("reviewables.sensitivity.#{p[0]}"), value: p[1] } { name: I18n.t("reviewables.sensitivity.#{p[0]}"), value: p[1] }
end end
end end

View File

@ -105,7 +105,7 @@ end
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# type :string not null # type :string not null
# status :integer default(0), not null # status :integer default("pending"), not null
# created_by_id :integer not null # created_by_id :integer not null
# reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_moderator :boolean default(FALSE), not null
# reviewable_by_group_id :integer # reviewable_by_group_id :integer

View File

@ -1396,7 +1396,7 @@ class User < ActiveRecord::Base
def number_of_rejected_posts def number_of_rejected_posts
ReviewableQueuedPost ReviewableQueuedPost
.where(status: Reviewable.statuses[:rejected]) .rejected
.where(created_by_id: self.id) .where(created_by_id: self.id)
.count .count
end end

View File

@ -2,7 +2,6 @@
# Deprecated, should be removed once users have sufficient opportunity to do so # Deprecated, should be removed once users have sufficient opportunity to do so
class QueuedPostSerializer < ApplicationSerializer class QueuedPostSerializer < ApplicationSerializer
attributes( attributes(
:id, :id,
:queue, :queue,
@ -33,11 +32,11 @@ class QueuedPostSerializer < ApplicationSerializer
end end
def approved_by_id def approved_by_id
who_did(:approved) post_history.approved.last&.created_by_id
end end
def rejected_by_id def rejected_by_id
who_did(:rejected) post_history.rejected.last&.created_by_id
end end
def raw def raw
@ -56,17 +55,12 @@ class QueuedPostSerializer < ApplicationSerializer
created_by && created_by.trust_level == TrustLevel[0] created_by && created_by.trust_level == TrustLevel[0]
end end
protected private
def who_did(status) def post_history
object. object.
reviewable_histories. reviewable_histories.
where( transitioned.
reviewable_history_type: ReviewableHistory.types[:transitioned],
status: Reviewable.statuses[status]
).
order(:created_at) order(:created_at)
.last&.created_by_id
end end
end end

View File

@ -1,8 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class ReviewableHistorySerializer < ApplicationSerializer class ReviewableHistorySerializer < ApplicationSerializer
attributes :id, :created_at
attribute :reviewable_history_type_for_database, key: :reviewable_history_type
attribute :status_for_database, key: :status
attributes :id, :reviewable_history_type, :status, :created_at
has_one :created_by, serializer: BasicUserSerializer, root: 'users' has_one :created_by, serializer: BasicUserSerializer, root: 'users'
end end

View File

@ -15,7 +15,10 @@ class ReviewableScoreSerializer < ApplicationSerializer
contains_media: 'review_media_unless_trust_level', contains_media: 'review_media_unless_trust_level',
} }
attributes :id, :score, :agree_stats, :status, :reason, :created_at, :reviewed_at attributes :id, :score, :agree_stats, :reason, :created_at, :reviewed_at
attribute :status_for_database, key: :status
has_one :user, serializer: BasicUserSerializer, root: 'users' has_one :user, serializer: BasicUserSerializer, root: 'users'
has_one :score_type, serializer: ReviewableScoreTypeSerializer has_one :score_type, serializer: ReviewableScoreTypeSerializer
has_one :reviewable_conversation, serializer: ReviewableConversationSerializer has_one :reviewable_conversation, serializer: ReviewableConversationSerializer

View File

@ -6,7 +6,6 @@ class ReviewableSerializer < ApplicationSerializer
attributes( attributes(
:id, :id,
:status,
:type, :type,
:topic_id, :topic_id,
:topic_url, :topic_url,
@ -20,6 +19,8 @@ class ReviewableSerializer < ApplicationSerializer
:target_created_by_trust_level :target_created_by_trust_level
) )
attribute :status_for_database, key: :status
has_one :created_by, serializer: UserWithCustomFieldsSerializer, root: 'users' has_one :created_by, serializer: UserWithCustomFieldsSerializer, root: 'users'
has_one :target_created_by, serializer: UserWithCustomFieldsSerializer, root: 'users' has_one :target_created_by, serializer: UserWithCustomFieldsSerializer, root: 'users'
has_one :topic, serializer: ListableTopicSerializer has_one :topic, serializer: ListableTopicSerializer

View File

@ -47,8 +47,7 @@ class SpamRule::FlagSockpuppets
private private
def flag_post(post, message) def flag_post(post, message)
can_trust_user = ReviewableFlaggedPost.where(status: Reviewable.statuses[:rejected], target_created_by: post.user).exists? return if ReviewableFlaggedPost.rejected.exists?(target_created_by: post.user)
return if can_trust_user
PostActionCreator.create(Discourse.system_user, post, :spam, message: message) PostActionCreator.create(Discourse.system_user, post, :spam, message: message)
end end

View File

@ -152,7 +152,7 @@ private
def cannot_flag_again?(reviewable) def cannot_flag_again?(reviewable)
return false if @post_action_type_id == PostActionType.types[:notify_moderators] return false if @post_action_type_id == PostActionType.types[:notify_moderators]
flag_type_already_used = reviewable.reviewable_scores.any? { |rs| rs.reviewable_score_type == @post_action_type_id && rs.status != ReviewableScore.statuses[:pending] } flag_type_already_used = reviewable.reviewable_scores.any? { |rs| rs.reviewable_score_type == @post_action_type_id && !rs.pending? }
not_edited_since_last_review = @post.last_version_at.blank? || reviewable.updated_at > @post.last_version_at not_edited_since_last_review = @post.last_version_at.blank? || reviewable.updated_at > @post.last_version_at
handled_recently = reviewable.updated_at > SiteSetting.cooldown_hours_until_reflag.to_i.hours.ago handled_recently = reviewable.updated_at > SiteSetting.cooldown_hours_until_reflag.to_i.hours.ago

View File

@ -9,9 +9,9 @@ RSpec.describe "spam rules for users" do
fab!(:user2) { Fabricate(:user) } fab!(:user2) { Fabricate(:user) }
before do before do
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled]
Reviewable.set_priorities(high: 4.0) Reviewable.set_priorities(high: 4.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:low]
SiteSetting.num_users_to_silence_new_user = 2 SiteSetting.num_users_to_silence_new_user = 2
end end
@ -74,7 +74,7 @@ RSpec.describe "spam rules for users" do
context 'with hide_post_sensitivity' do context 'with hide_post_sensitivity' do
it 'should silence the spammer' do it 'should silence the spammer' do
Reviewable.set_priorities(high: 2.0) Reviewable.set_priorities(high: 2.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low]
PostActionCreator.create(user2, spam_post, :spam) PostActionCreator.create(user2, spam_post, :spam)
expect(spammer.reload).to be_silenced expect(spammer.reload).to be_silenced
expect(Guardian.new(spammer).can_create_topic?(nil)).to be false expect(Guardian.new(spammer).can_create_topic?(nil)).to be false

View File

@ -1012,28 +1012,36 @@ RSpec.describe PostDestroyer do
end end
end end
describe '#delete_with_replies' do describe '.delete_with_replies' do
let(:reporter) { Discourse.system_user } subject(:delete_with_replies) { PostDestroyer.delete_with_replies(reporter, post, defer_reply_flags: defer_reply_flags) }
fab!(:post) { Fabricate(:post) } fab!(:post) { Fabricate(:post) }
let(:reporter) { Discourse.system_user }
let(:reply) { Fabricate(:post, topic: post.topic) }
let(:reviewable_reply) { PostActionCreator.off_topic(reporter, reply).reviewable }
before do before do
reply = Fabricate(:post, topic: post.topic)
post.update(replies: [reply]) post.update(replies: [reply])
PostActionCreator.off_topic(reporter, post) PostActionCreator.off_topic(reporter, post)
reviewable_reply
@reviewable_reply = PostActionCreator.off_topic(reporter, reply).reviewable
end end
it 'ignores flagged replies' do context 'when deferring reply flags' do
PostDestroyer.delete_with_replies(reporter, post) let(:defer_reply_flags) { true }
expect(@reviewable_reply.reload.status).to eq Reviewable.statuses[:ignored] it 'ignores flagged replies' do
delete_with_replies
expect(reviewable_reply.reload).to be_ignored
end
end end
it 'approves flagged replies' do context 'when not deferring reply flags' do
PostDestroyer.delete_with_replies(reporter, post, defer_reply_flags: false) let(:defer_reply_flags) { false }
expect(@reviewable_reply.reload.status).to eq Reviewable.statuses[:approved] it 'approves flagged replies' do
delete_with_replies
expect(reviewable_reply.reload).to be_approved
end
end end
end end

View File

@ -518,7 +518,7 @@ RSpec.describe PostAction do
post = Fabricate(:post, user: mod) post = Fabricate(:post, user: mod)
Reviewable.set_priorities(high: 2.0) Reviewable.set_priorities(high: 2.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low]
Discourse.stubs(:site_contact_user).returns(admin) Discourse.stubs(:site_contact_user).returns(admin)
PostActionCreator.spam(eviltrout, post) PostActionCreator.spam(eviltrout, post)
@ -533,7 +533,7 @@ RSpec.describe PostAction do
post = Fabricate(:post, user: mod) post = Fabricate(:post, user: mod)
Reviewable.set_priorities(high: 8.0) Reviewable.set_priorities(high: 8.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low]
Discourse.stubs(:site_contact_user).returns(admin) Discourse.stubs(:site_contact_user).returns(admin)
PostActionCreator.spam(eviltrout, post) PostActionCreator.spam(eviltrout, post)
@ -563,7 +563,7 @@ RSpec.describe PostAction do
walterwhite = Fabricate(:walter_white) walterwhite = Fabricate(:walter_white)
Reviewable.set_priorities(high: 3.0) Reviewable.set_priorities(high: 3.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low]
Discourse.stubs(:site_contact_user).returns(admin) Discourse.stubs(:site_contact_user).returns(admin)
PostActionCreator.spam(eviltrout, post) PostActionCreator.spam(eviltrout, post)
@ -687,9 +687,9 @@ RSpec.describe PostAction do
fab!(:flagger2) { Fabricate(:user) } fab!(:flagger2) { Fabricate(:user) }
before do before do
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled]
Reviewable.set_priorities(high: 4.5) Reviewable.set_priorities(high: 4.5)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivities[:low]
SiteSetting.num_flaggers_to_close_topic = 2 SiteSetting.num_flaggers_to_close_topic = 2
SiteSetting.num_hours_to_close_topic = 1 SiteSetting.num_hours_to_close_topic = 1
end end
@ -753,7 +753,7 @@ RSpec.describe PostAction do
SiteSetting.num_flaggers_to_close_topic = 1 SiteSetting.num_flaggers_to_close_topic = 1
Reviewable.set_priorities(high: 0.5) Reviewable.set_priorities(high: 0.5)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivities[:low]
post = Fabricate(:post, topic: topic) post = Fabricate(:post, topic: topic)
PostActionCreator.spam(flagger1, post) PostActionCreator.spam(flagger1, post)
@ -772,7 +772,7 @@ RSpec.describe PostAction do
freeze_time timer.execute_at freeze_time timer.execute_at
SiteSetting.num_flaggers_to_close_topic = 10 SiteSetting.num_flaggers_to_close_topic = 10
Reviewable.set_priorities(high: 10.0) Reviewable.set_priorities(high: 10.0)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivities[:low]
Jobs::ToggleTopicClosed.new.execute(topic_timer_id: timer.id, state: false) Jobs::ToggleTopicClosed.new.execute(topic_timer_id: timer.id, state: false)

View File

@ -292,7 +292,7 @@ RSpec.describe ReviewableFlaggedPost, type: :model do
flagged_reply = Fabricate(:reviewable_flagged_post, target: reply) flagged_reply = Fabricate(:reviewable_flagged_post, target: reply)
flagged_post.perform(moderator, :delete_and_agree_replies) flagged_post.perform(moderator, :delete_and_agree_replies)
expect(flagged_reply.reload.status).to eq(Reviewable.statuses[:ignored]) expect(flagged_reply.reload).to be_ignored
end end
it "notifies users that responded to flagged post" do it "notifies users that responded to flagged post" do
@ -308,7 +308,7 @@ RSpec.describe ReviewableFlaggedPost, type: :model do
flagged_reply = Fabricate(:reviewable_flagged_post, target: reply) flagged_reply = Fabricate(:reviewable_flagged_post, target: reply)
flagged_post.perform(moderator, :delete_and_agree_replies) flagged_post.perform(moderator, :delete_and_agree_replies)
expect(flagged_reply.reload.status).to eq(Reviewable.statuses[:ignored]) expect(flagged_reply.reload).to be_ignored
end end
end end

View File

@ -14,8 +14,8 @@ RSpec.describe ReviewableHistory, type: :model do
history = reviewable.history history = reviewable.history
expect(history.size).to eq(3) expect(history.size).to eq(3)
expect(history[0].reviewable_history_type).to eq(ReviewableHistory.types[:created]) expect(history[0]).to be_created
expect(history[0].status).to eq(Reviewable.statuses[:pending]) expect(history[0]).to be_pending
expect(history[0].created_by).to eq(admin) expect(history[0].created_by).to eq(admin)
end end
@ -26,12 +26,12 @@ RSpec.describe ReviewableHistory, type: :model do
history = reviewable.history history = reviewable.history
expect(history.size).to eq(3) expect(history.size).to eq(3)
expect(history[1].reviewable_history_type).to eq(ReviewableHistory.types[:transitioned]) expect(history[1]).to be_transitioned
expect(history[1].status).to eq(Reviewable.statuses[:approved]) expect(history[1]).to be_approved
expect(history[1].created_by).to eq(moderator) expect(history[1].created_by).to eq(moderator)
expect(history[2].reviewable_history_type).to eq(ReviewableHistory.types[:transitioned]) expect(history[2]).to be_transitioned
expect(history[2].status).to eq(Reviewable.statuses[:pending]) expect(history[2]).to be_pending
expect(history[2].created_by).to eq(admin) expect(history[2].created_by).to eq(admin)
end end
@ -52,7 +52,7 @@ RSpec.describe ReviewableHistory, type: :model do
history = reviewable.history history = reviewable.history
expect(history.size).to eq(2) expect(history.size).to eq(2)
expect(history[1].reviewable_history_type).to eq(ReviewableHistory.types[:edited]) expect(history[1]).to be_edited
expect(history[1].created_by).to eq(moderator) expect(history[1].created_by).to eq(moderator)
expect(history[1].edited).to eq("category_id" => [old_category.id, nil]) expect(history[1].edited).to eq("category_id" => [old_category.id, nil])
end end

View File

@ -9,8 +9,8 @@ RSpec.describe ReviewablePost do
let(:guardian) { Guardian.new } let(:guardian) { Guardian.new }
it 'Does not return available actions when the reviewable is no longer pending' do it 'Does not return available actions when the reviewable is no longer pending' do
available_actions = (Reviewable.statuses.keys - [:pending]).reduce([]) do |actions, status| available_actions = (Reviewable.statuses.keys - ["pending"]).reduce([]) do |actions, status|
reviewable.status = Reviewable.statuses[status] reviewable.status = status
actions.concat reviewable_actions(guardian).to_a actions.concat reviewable_actions(guardian).to_a
end end

View File

@ -85,7 +85,7 @@ RSpec.describe ReviewableQueuedPost, type: :model do
post = Fabricate(:post, user: newuser) post = Fabricate(:post, user: newuser)
PostActionCreator.spam(moderator, post) PostActionCreator.spam(moderator, post)
Reviewable.set_priorities(high: 1.0) Reviewable.set_priorities(high: 1.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:low]
SiteSetting.num_users_to_silence_new_user = 1 SiteSetting.num_users_to_silence_new_user = 1
expect(Guardian.new(newuser).can_create_post?(topic)).to eq(false) expect(Guardian.new(newuser).can_create_post?(topic)).to eq(false)
@ -212,7 +212,7 @@ RSpec.describe ReviewableQueuedPost, type: :model do
context "when status changes from 'pending' to something else" do context "when status changes from 'pending' to something else" do
it "updates user stats" do it "updates user stats" do
user_stats.expects(:update_pending_posts) user_stats.expects(:update_pending_posts)
reviewable.update!(status: described_class.statuses[:approved]) reviewable.update!(status: :approved)
end end
end end

View File

@ -427,8 +427,8 @@ RSpec.describe Reviewable, type: :model do
expect { PostActionCreator.spam(Fabricate(:user), post) } expect { PostActionCreator.spam(Fabricate(:user), post) }
.to change { reviewable.reload.status } .to change { reviewable.reload.status }
.from(Reviewable.statuses[:rejected]) .from("rejected")
.to(Reviewable.statuses[:pending]) .to("pending")
.and change { Jobs::NotifyReviewable.jobs.size } .and change { Jobs::NotifyReviewable.jobs.size }
.by(1) .by(1)
end end
@ -521,77 +521,77 @@ RSpec.describe Reviewable, type: :model do
describe ".score_required_to_hide_post" do describe ".score_required_to_hide_post" do
it "will return the default visibility if it's higher" do it "will return the default visibility if it's higher" do
Reviewable.set_priorities(low: 40.0, high: 100.0) described_class.set_priorities(low: 40.0, high: 100.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.score_required_to_hide_post).to eq(40.0) expect(described_class.score_required_to_hide_post).to eq(40.0)
end end
it "returns a default 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 = described_class.sensitivities[:low]
expect(Reviewable.score_required_to_hide_post).to eq(12.5) expect(described_class.score_required_to_hide_post).to eq(12.5)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:medium]
expect(Reviewable.score_required_to_hide_post).to eq(8.33) expect(described_class.score_required_to_hide_post).to eq(8.33)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.score_required_to_hide_post).to eq(4.16) expect(described_class.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
Reviewable.set_priorities(high: 100.0) described_class.set_priorities(high: 100.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:disabled]
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(Float::MAX) expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(Float::MAX)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:low]
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(100.0) expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(100.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:medium]
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(66.66) expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(66.66)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high] SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(33.33) expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(33.33)
end end
end end
describe ".spam_score_to_silence_new_user" do describe ".spam_score_to_silence_new_user" do
it "returns a default value 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 = described_class.sensitivities[:low]
expect(Reviewable.spam_score_to_silence_new_user).to eq(7.5) expect(described_class.spam_score_to_silence_new_user).to eq(7.5)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:medium]
expect(Reviewable.spam_score_to_silence_new_user).to eq(4.99) expect(described_class.spam_score_to_silence_new_user).to eq(4.99)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high] SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.spam_score_to_silence_new_user).to eq(2.49) expect(described_class.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) described_class.set_priorities(high: 100.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:disabled]
expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(Float::MAX) expect(described_class.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 = described_class.sensitivities[:low]
expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(60.0) expect(described_class.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 = described_class.sensitivities[:medium]
expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(39.99) expect(described_class.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 = described_class.sensitivities[:high]
expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(19.99) expect(described_class.spam_score_to_silence_new_user.to_f).to eq(19.99)
end end
end end
describe ".score_to_auto_close_topic" do describe ".score_to_auto_close_topic" do
it "returns the default 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 = described_class.sensitivities[:low]
expect(Reviewable.score_to_auto_close_topic).to eq(31.25) expect(described_class.score_to_auto_close_topic).to eq(31.25)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:medium]
expect(Reviewable.score_to_auto_close_topic).to eq(20.83) expect(described_class.score_to_auto_close_topic).to eq(20.83)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.score_to_auto_close_topic).to eq(10.41) expect(described_class.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
Reviewable.set_priorities(high: 100.0) described_class.set_priorities(high: 100.0)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:disabled]
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(Float::MAX) expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(Float::MAX)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:low]
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(250.0) expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(250.0)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:medium]
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(166.66) expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(166.66)
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:high]
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(83.33) expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(83.33)
end end
end end

View File

@ -2909,7 +2909,7 @@ RSpec.describe Topic do
Reviewable.set_priorities(low: 2.0, medium: 6.0, high: 9.0) Reviewable.set_priorities(low: 2.0, medium: 6.0, high: 9.0)
SiteSetting.num_flaggers_to_close_topic = 2 SiteSetting.num_flaggers_to_close_topic = 2
SiteSetting.reviewable_default_visibility = 'medium' SiteSetting.reviewable_default_visibility = 'medium'
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivities[:high]
post = Fabricate(:post) post = Fabricate(:post)
@topic = post.topic @topic = post.topic
@reviewable = Fabricate(:reviewable_flagged_post, target: post, topic: @topic) @reviewable = Fabricate(:reviewable_flagged_post, target: post, topic: @topic)

View File

@ -2602,35 +2602,44 @@ RSpec.describe User do
end end
describe 'Granting admin or moderator status' do describe 'Granting admin or moderator status' do
fab!(:reviewable_user) { Fabricate(:reviewable_user) } context 'when granting admin status' do
context 'when there is a reviewable' do
fab!(:user) { Fabricate(:reviewable_user) }
it 'approves the associated reviewable when granting admin status' do context 'when the user isnt approved yet' do
reviewable_user.target.grant_admin! it 'approves the associated reviewable' do
expect { user.target.grant_admin! }.to change { user.reload.dup }.to be_approved
end
end
expect(reviewable_user.reload.status).to eq Reviewable.statuses[:approved] context "when the user is already approved" do
before do
user.perform(Discourse.system_user, :approve_user)
end
it 'does nothing' do
expect { user.target.grant_admin! }.not_to change { user.reload.approved? }
end
end
end
context 'when there is no reviewable' do
let(:user) { Fabricate(:user, approved: false) }
it 'approves the user' do
expect { user.grant_admin! }.to change { user.reload.approved }.to true
end
end
end end
it 'does nothing when the user is already approved' do context 'when granting moderator status' do
reviewable_user = Fabricate(:reviewable_user) context 'when there is a reviewable' do
reviewable_user.perform(Discourse.system_user, :approve_user) let(:user) { Fabricate(:reviewable_user) }
reviewable_user.target.grant_admin! it 'approves the associated reviewable' do
expect { user.target.grant_moderation! }.to change { user.reload.dup }.to be_approved
expect(reviewable_user.reload.status).to eq Reviewable.statuses[:approved] end
end end
it 'approves the associated reviewable when granting moderator status' do
reviewable_user.target.grant_moderation!
expect(reviewable_user.reload.status).to eq Reviewable.statuses[:approved]
end
it 'approves the user if there is no reviewable' do
user = Fabricate(:user, approved: false)
user.grant_admin!
expect(user.approved).to eq(true)
end end
end end

View File

@ -9,7 +9,7 @@ RSpec.describe ReviewableSerializer do
json = described_class.new(reviewable, scope: Guardian.new(admin), root: nil).as_json json = described_class.new(reviewable, scope: Guardian.new(admin), root: nil).as_json
expect(json[:id]).to eq(reviewable.id) expect(json[:id]).to eq(reviewable.id)
expect(json[:status]).to eq(reviewable.status) expect(json[:status]).to eq(reviewable.status_for_database)
expect(json[:type]).to eq(reviewable.type) expect(json[:type]).to eq(reviewable.type)
expect(json[:created_at]).to eq(reviewable.created_at) expect(json[:created_at]).to eq(reviewable.created_at)
expect(json[:category_id]).to eq(reviewable.category_id) expect(json[:category_id]).to eq(reviewable.category_id)

View File

@ -2,9 +2,9 @@
RSpec.describe SpamRule::AutoSilence do RSpec.describe SpamRule::AutoSilence do
before do before do
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled]
Reviewable.set_priorities(high: 4.0) Reviewable.set_priorities(high: 4.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:low]
SiteSetting.num_users_to_silence_new_user = 2 SiteSetting.num_users_to_silence_new_user = 2
end end
@ -20,7 +20,7 @@ RSpec.describe SpamRule::AutoSilence do
it 'delivers punishment when user should be silenced' do it 'delivers punishment when user should be silenced' do
Reviewable.set_priorities(high: 2.0) Reviewable.set_priorities(high: 2.0)
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:low]
SiteSetting.num_users_to_silence_new_user = 1 SiteSetting.num_users_to_silence_new_user = 1
PostActionCreator.spam(Discourse.system_user, post) PostActionCreator.spam(Discourse.system_user, post)
subject.perform subject.perform
@ -194,7 +194,7 @@ RSpec.describe SpamRule::AutoSilence do
end end
it 'returns false if silence_new_user_sensitivity is disabled' do it 'returns false if silence_new_user_sensitivity is disabled' do
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled] SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivities[:disabled]
PostActionCreator.spam(flagger, post) PostActionCreator.spam(flagger, post)
PostActionCreator.spam(flagger2, post) PostActionCreator.spam(flagger2, post)
expect(subject.should_autosilence?).to eq(false) expect(subject.should_autosilence?).to eq(false)

View File

@ -156,7 +156,7 @@ RSpec.describe SpamRule::FlagSockpuppets do
described_class.new(post2).perform described_class.new(post2).perform
expect(flagged_post.reload.status).to eq(Reviewable.statuses[:rejected]) expect(flagged_post.reload).to be_rejected
end end
it "doesn't flag the post if another post of the same user was rejected by staff before" do it "doesn't flag the post if another post of the same user was rejected by staff before" do

View File

@ -308,7 +308,7 @@ RSpec.describe PostAlerter do
PostActionNotifier.enable PostActionNotifier.enable
Reviewable.set_priorities(high: 4.0) Reviewable.set_priorities(high: 4.0)
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low]
PostActionCreator.spam(evil_trout, post) PostActionCreator.spam(evil_trout, post)
PostActionCreator.spam(walterwhite, post) PostActionCreator.spam(walterwhite, post)

View File

@ -106,7 +106,7 @@ RSpec.describe UserDestroyer do
it 'sets the reviewable user as rejected' do it 'sets the reviewable user as rejected' do
UserDestroyer.new(admin).destroy(reviewable.target) UserDestroyer.new(admin).destroy(reviewable.target)
expect(reviewable.reload.status).to eq(Reviewable.statuses[:rejected]) expect(reviewable.reload).to be_rejected
end end
end end