diff --git a/app/controllers/reviewables_controller.rb b/app/controllers/reviewables_controller.rb index d0385343aa1..7099796ce0e 100644 --- a/app/controllers/reviewables_controller.rb +++ b/app/controllers/reviewables_controller.rb @@ -268,7 +268,7 @@ protected end def allowed_statuses - @allowed_statuses ||= (%i[reviewed all] + Reviewable.statuses.keys) + @allowed_statuses ||= (%i[reviewed all] + Reviewable.statuses.symbolize_keys.keys) end def version_required diff --git a/app/jobs/regular/export_user_archive.rb b/app/jobs/regular/export_user_archive.rb index 3e76285f9d7..256b8a3d4d7 100644 --- a/app/jobs/regular/export_user_archive.rb +++ b/app/jobs/regular/export_user_archive.rb @@ -361,7 +361,7 @@ module Jobs yield [ rev.id, - Reviewable.statuses[rev.status], + rev.status, rev.category_id, rev.topic_id, rev.payload['raw'], diff --git a/app/jobs/scheduled/auto_queue_handler.rb b/app/jobs/scheduled/auto_queue_handler.rb index dfc87b77f12..6bf75924c96 100644 --- a/app/jobs/scheduled/auto_queue_handler.rb +++ b/app/jobs/scheduled/auto_queue_handler.rb @@ -11,7 +11,7 @@ module Jobs return unless SiteSetting.auto_handle_queued_age.to_i > 0 Reviewable - .where(status: Reviewable.statuses[:pending]) + .pending .where('created_at < ?', SiteSetting.auto_handle_queued_age.to_i.days.ago) .each do |reviewable| diff --git a/app/jobs/scheduled/pending_queued_posts_reminder.rb b/app/jobs/scheduled/pending_queued_posts_reminder.rb index 0bc78cb69e9..22b84fc701b 100644 --- a/app/jobs/scheduled/pending_queued_posts_reminder.rb +++ b/app/jobs/scheduled/pending_queued_posts_reminder.rb @@ -27,7 +27,7 @@ module Jobs end 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 ).pluck(:id) end diff --git a/app/jobs/scheduled/reviewable_priorities.rb b/app/jobs/scheduled/reviewable_priorities.rb index da4d9c8148c..b9c5e4c8b55 100644 --- a/app/jobs/scheduled/reviewable_priorities.rb +++ b/app/jobs/scheduled/reviewable_priorities.rb @@ -15,11 +15,7 @@ class Jobs::ReviewablePriorities < ::Jobs::Scheduled def execute(args) min_priority_threshold = SiteSetting.reviewable_low_priority_threshold - reviewable_count = Reviewable.where( - "score > ? AND status = ?", - min_priority_threshold, - Reviewable.statuses[:approved] - ).count + reviewable_count = Reviewable.approved.where("score > ?", min_priority_threshold).count return if reviewable_count < self.class.min_reviewables res = DB.query_single(<<~SQL, target_count: self.class.target_count, min_priority: min_priority_threshold) diff --git a/app/models/concerns/roleable.rb b/app/models/concerns/roleable.rb index 4a9a6be3ddb..6dc571f2298 100644 --- a/app/models/concerns/roleable.rb +++ b/app/models/concerns/roleable.rb @@ -80,7 +80,7 @@ module Roleable private 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) else ReviewableUser.set_approved_fields!(self, Discourse.system_user) diff --git a/app/models/reviewable.rb b/app/models/reviewable.rb index b1b5f518f4d..0f544519ea8 100644 --- a/app/models/reviewable.rb +++ b/app/models/reviewable.rb @@ -31,6 +31,25 @@ class Reviewable < ActiveRecord::Base has_many :reviewable_histories 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 log_history(:created, created_by) end @@ -48,47 +67,12 @@ class Reviewable < ActiveRecord::Base {} 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. # 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 - statuses.each do |name, id| - define_method("#{name}?") { status == id } - singleton_class.define_method(name) { where(status: id) } - end - def self.default_visible where("score >= ?", min_score_for_priority) end @@ -211,7 +195,7 @@ class Reviewable < ActiveRecord::Base rs = reviewable_scores.new( user: user, - status: ReviewableScore.statuses[:pending], + status: :pending, reviewable_score_type: reviewable_score_type, score: sub_total, user_accuracy_bonus: user_accuracy_bonus, @@ -232,7 +216,7 @@ class Reviewable < ActiveRecord::Base def self.set_priorities(values) values.each do |k, v| - id = Reviewable.priorities[k] + id = priorities[k] PluginStore.set('reviewables', "priority_#{id}", v) unless id.nil? end end @@ -240,9 +224,9 @@ class Reviewable < ActiveRecord::Base def self.sensitivity_score_value(sensitivity, scale) return Float::MAX if sensitivity == 0 - ratio = sensitivity / Reviewable.sensitivity[:low].to_f + ratio = sensitivity / sensitivities[:low].to_f high = ( - PluginStore.get('reviewables', "priority_#{Reviewable.priorities[:high]}") || + PluginStore.get('reviewables', "priority_#{priorities[:high]}") || typical_sensitivity ).to_f @@ -271,7 +255,7 @@ class Reviewable < ActiveRecord::Base def self.min_score_for_priority(priority = nil) priority ||= SiteSetting.reviewable_default_visibility - id = Reviewable.priorities[priority.to_sym] + id = priorities[priority] return 0.0 if id.nil? PluginStore.get('reviewables', "priority_#{id}").to_f end @@ -282,7 +266,7 @@ class Reviewable < ActiveRecord::Base def log_history(reviewable_history_type, performed_by, edited: nil) reviewable_histories.create!( - reviewable_history_type: ReviewableHistory.types[reviewable_history_type], + reviewable_history_type: reviewable_history_type, status: status, created_by: performed_by, edited: edited @@ -386,9 +370,7 @@ class Reviewable < ActiveRecord::Base end def transition_to(status_symbol, performed_by) - was_pending = pending? - - self.status = Reviewable.statuses[status_symbol] + self.status = status_symbol save! log_history(:transitioned, performed_by) @@ -402,7 +384,7 @@ class Reviewable < ActiveRecord::Base ) end - was_pending + status_previously_changed?(from: "pending") end def post_options @@ -503,13 +485,13 @@ class Reviewable < ActiveRecord::Base SELECT reviewable_id FROM reviewable_histories 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 SQL ) end - min_score = Reviewable.min_score_for_priority(priority) + min_score = min_score_for_priority(priority) if min_score > 0 && status == :pending result = result.where("reviewables.score >= ? OR reviewables.force_review", min_score) @@ -678,8 +660,8 @@ class Reviewable < ActiveRecord::Base DB.query( sql, topic_id: topic_id, - pending: Reviewable.statuses[:pending], - approved: Reviewable.statuses[:approved] + pending: self.class.statuses[:pending], + approved: self.class.statuses[:approved] ) self.score = result[0].score @@ -776,7 +758,7 @@ end # # id :bigint not null, primary key # type :string not null -# status :integer default(0), not null +# status :integer default("pending"), not null # created_by_id :integer not null # reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_group_id :integer diff --git a/app/models/reviewable_flagged_post.rb b/app/models/reviewable_flagged_post.rb index debfa19c340..d79f1daf1ce 100644 --- a/app/models/reviewable_flagged_post.rb +++ b/app/models/reviewable_flagged_post.rb @@ -13,7 +13,7 @@ class ReviewableFlaggedPost < Reviewable def self.counts_for(posts) result = {} - counts = DB.query(<<~SQL, pending: Reviewable.statuses[:pending]) + counts = DB.query(<<~SQL, pending: statuses[:pending]) SELECT r.target_id AS post_id, rs.reviewable_score_type, count(*) as total @@ -336,7 +336,7 @@ end # # id :bigint not null, primary key # type :string not null -# status :integer default(0), not null +# status :integer default("pending"), not null # created_by_id :integer not null # reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_group_id :integer diff --git a/app/models/reviewable_history.rb b/app/models/reviewable_history.rb index 98b6636500d..c01d41a9357 100644 --- a/app/models/reviewable_history.rb +++ b/app/models/reviewable_history.rb @@ -4,16 +4,22 @@ class ReviewableHistory < ActiveRecord::Base belongs_to :reviewable belongs_to :created_by, class_name: 'User' - def self.types - @types ||= Enum.new( - created: 0, - transitioned: 1, - edited: 2, - claimed: 3, - unclaimed: 4 - ) - end + enum status: { + pending: 0, + approved: 1, + rejected: 2, + ignored: 3, + deleted: 4 + } + alias_attribute :type, :reviewable_history_type + enum type: { + created: 0, + transitioned: 1, + edited: 2, + claimed: 3, + unclaimed: 4 + } end # == Schema Information diff --git a/app/models/reviewable_post.rb b/app/models/reviewable_post.rb index a8c24b1878a..983a96c0549 100644 --- a/app/models/reviewable_post.rb +++ b/app/models/reviewable_post.rb @@ -8,7 +8,7 @@ class ReviewablePost < Reviewable def self.queue_for_review_if_possible(post, created_or_edited_by) return unless SiteSetting.review_every_post 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]) system_user = Discourse.system_user @@ -116,7 +116,7 @@ end # # id :bigint not null, primary key # type :string not null -# status :integer default(0), not null +# status :integer default("pending"), not null # created_by_id :integer not null # reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_group_id :integer diff --git a/app/models/reviewable_queued_post.rb b/app/models/reviewable_queued_post.rb index ccfcea66712..50a453c734c 100644 --- a/app/models/reviewable_queued_post.rb +++ b/app/models/reviewable_queued_post.rb @@ -174,7 +174,7 @@ class ReviewableQueuedPost < Reviewable def status_changed_from_or_to_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 @@ -184,7 +184,7 @@ end # # id :bigint not null, primary key # type :string not null -# status :integer default(0), not null +# status :integer default("pending"), not null # created_by_id :integer not null # reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_group_id :integer diff --git a/app/models/reviewable_score.rb b/app/models/reviewable_score.rb index 34080a944d9..2d650b41317 100644 --- a/app/models/reviewable_score.rb +++ b/app/models/reviewable_score.rb @@ -6,6 +6,13 @@ class ReviewableScore < ActiveRecord::Base belongs_to :reviewed_by, class_name: 'User' 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 # compatibility, but we can add extra reasons for scores. def self.types @@ -29,15 +36,6 @@ class ReviewableScore < ActiveRecord::Base end end - def self.statuses - @statuses ||= Enum.new( - pending: 0, - agreed: 1, - disagreed: 2, - ignored: 3 - ) - end - def self.score_transitions { approved: statuses[:agreed], @@ -46,12 +44,6 @@ class ReviewableScore < ActiveRecord::Base } 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 Reviewable::Collection::Item.new(reviewable_score_type) end diff --git a/app/models/reviewable_sensitivity_setting.rb b/app/models/reviewable_sensitivity_setting.rb index 4207d142605..c6fa405c3d6 100644 --- a/app/models/reviewable_sensitivity_setting.rb +++ b/app/models/reviewable_sensitivity_setting.rb @@ -7,7 +7,7 @@ class ReviewableSensitivitySetting < EnumSiteSetting end def self.values - Reviewable.sensitivity.map do |p| + Reviewable.sensitivities.map do |p| { name: I18n.t("reviewables.sensitivity.#{p[0]}"), value: p[1] } end end diff --git a/app/models/reviewable_user.rb b/app/models/reviewable_user.rb index 6fa1fc56ce1..c885c8718c6 100644 --- a/app/models/reviewable_user.rb +++ b/app/models/reviewable_user.rb @@ -105,7 +105,7 @@ end # # id :bigint not null, primary key # type :string not null -# status :integer default(0), not null +# status :integer default("pending"), not null # created_by_id :integer not null # reviewable_by_moderator :boolean default(FALSE), not null # reviewable_by_group_id :integer diff --git a/app/models/user.rb b/app/models/user.rb index ff8cb516266..24afd78f3ca 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1396,7 +1396,7 @@ class User < ActiveRecord::Base def number_of_rejected_posts ReviewableQueuedPost - .where(status: Reviewable.statuses[:rejected]) + .rejected .where(created_by_id: self.id) .count end diff --git a/app/serializers/queued_post_serializer.rb b/app/serializers/queued_post_serializer.rb index a0e51ab133e..f9dc0dcdefd 100644 --- a/app/serializers/queued_post_serializer.rb +++ b/app/serializers/queued_post_serializer.rb @@ -2,7 +2,6 @@ # Deprecated, should be removed once users have sufficient opportunity to do so class QueuedPostSerializer < ApplicationSerializer - attributes( :id, :queue, @@ -33,11 +32,11 @@ class QueuedPostSerializer < ApplicationSerializer end def approved_by_id - who_did(:approved) + post_history.approved.last&.created_by_id end def rejected_by_id - who_did(:rejected) + post_history.rejected.last&.created_by_id end def raw @@ -56,17 +55,12 @@ class QueuedPostSerializer < ApplicationSerializer created_by && created_by.trust_level == TrustLevel[0] end -protected + private - def who_did(status) + def post_history object. reviewable_histories. - where( - reviewable_history_type: ReviewableHistory.types[:transitioned], - status: Reviewable.statuses[status] - ). + transitioned. order(:created_at) - .last&.created_by_id end - end diff --git a/app/serializers/reviewable_history_serializer.rb b/app/serializers/reviewable_history_serializer.rb index 16733219ce7..d4ae2e78383 100644 --- a/app/serializers/reviewable_history_serializer.rb +++ b/app/serializers/reviewable_history_serializer.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true 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' - end diff --git a/app/serializers/reviewable_score_serializer.rb b/app/serializers/reviewable_score_serializer.rb index 549bd4536a5..6a0eac38d0a 100644 --- a/app/serializers/reviewable_score_serializer.rb +++ b/app/serializers/reviewable_score_serializer.rb @@ -15,7 +15,10 @@ class ReviewableScoreSerializer < ApplicationSerializer 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 :score_type, serializer: ReviewableScoreTypeSerializer has_one :reviewable_conversation, serializer: ReviewableConversationSerializer diff --git a/app/serializers/reviewable_serializer.rb b/app/serializers/reviewable_serializer.rb index 5dafa06a0b9..2260a4f9db1 100644 --- a/app/serializers/reviewable_serializer.rb +++ b/app/serializers/reviewable_serializer.rb @@ -6,7 +6,6 @@ class ReviewableSerializer < ApplicationSerializer attributes( :id, - :status, :type, :topic_id, :topic_url, @@ -20,6 +19,8 @@ class ReviewableSerializer < ApplicationSerializer :target_created_by_trust_level ) + attribute :status_for_database, key: :status + has_one :created_by, serializer: UserWithCustomFieldsSerializer, root: 'users' has_one :target_created_by, serializer: UserWithCustomFieldsSerializer, root: 'users' has_one :topic, serializer: ListableTopicSerializer diff --git a/app/services/spam_rule/flag_sockpuppets.rb b/app/services/spam_rule/flag_sockpuppets.rb index 00f74e881be..c51d67f4022 100644 --- a/app/services/spam_rule/flag_sockpuppets.rb +++ b/app/services/spam_rule/flag_sockpuppets.rb @@ -47,8 +47,7 @@ class SpamRule::FlagSockpuppets private def flag_post(post, message) - can_trust_user = ReviewableFlaggedPost.where(status: Reviewable.statuses[:rejected], target_created_by: post.user).exists? - return if can_trust_user + return if ReviewableFlaggedPost.rejected.exists?(target_created_by: post.user) PostActionCreator.create(Discourse.system_user, post, :spam, message: message) end diff --git a/lib/post_action_creator.rb b/lib/post_action_creator.rb index 93cc6f7a912..ccfc08b3207 100644 --- a/lib/post_action_creator.rb +++ b/lib/post_action_creator.rb @@ -152,7 +152,7 @@ private def cannot_flag_again?(reviewable) 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 handled_recently = reviewable.updated_at > SiteSetting.cooldown_hours_until_reflag.to_i.hours.ago diff --git a/spec/integration/spam_rules_spec.rb b/spec/integration/spam_rules_spec.rb index bf89f478680..edefab13de0 100644 --- a/spec/integration/spam_rules_spec.rb +++ b/spec/integration/spam_rules_spec.rb @@ -9,9 +9,9 @@ RSpec.describe "spam rules for users" do fab!(:user2) { Fabricate(:user) } before do - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] + SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled] 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 end @@ -74,7 +74,7 @@ RSpec.describe "spam rules for users" do context 'with hide_post_sensitivity' do it 'should silence the spammer' do 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) expect(spammer.reload).to be_silenced expect(Guardian.new(spammer).can_create_topic?(nil)).to be false diff --git a/spec/lib/post_destroyer_spec.rb b/spec/lib/post_destroyer_spec.rb index 019db8de92b..71935cbc9db 100644 --- a/spec/lib/post_destroyer_spec.rb +++ b/spec/lib/post_destroyer_spec.rb @@ -1012,28 +1012,36 @@ RSpec.describe PostDestroyer do end end - describe '#delete_with_replies' do - let(:reporter) { Discourse.system_user } + describe '.delete_with_replies' do + subject(:delete_with_replies) { PostDestroyer.delete_with_replies(reporter, post, defer_reply_flags: defer_reply_flags) } + 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 - reply = Fabricate(:post, topic: post.topic) post.update(replies: [reply]) PostActionCreator.off_topic(reporter, post) - - @reviewable_reply = PostActionCreator.off_topic(reporter, reply).reviewable + reviewable_reply end - it 'ignores flagged replies' do - PostDestroyer.delete_with_replies(reporter, post) + context 'when deferring reply flags' do + 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 - it 'approves flagged replies' do - PostDestroyer.delete_with_replies(reporter, post, defer_reply_flags: false) + context 'when not deferring reply flags' do + 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 diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index ade7b9c92c0..746f4fc55f0 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -518,7 +518,7 @@ RSpec.describe PostAction do post = Fabricate(:post, user: mod) 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) PostActionCreator.spam(eviltrout, post) @@ -533,7 +533,7 @@ RSpec.describe PostAction do post = Fabricate(:post, user: mod) 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) PostActionCreator.spam(eviltrout, post) @@ -563,7 +563,7 @@ RSpec.describe PostAction do walterwhite = Fabricate(:walter_white) 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) PostActionCreator.spam(eviltrout, post) @@ -687,9 +687,9 @@ RSpec.describe PostAction do fab!(:flagger2) { Fabricate(:user) } before do - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] + SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled] 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_hours_to_close_topic = 1 end @@ -753,7 +753,7 @@ RSpec.describe PostAction do SiteSetting.num_flaggers_to_close_topic = 1 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) PostActionCreator.spam(flagger1, post) @@ -772,7 +772,7 @@ RSpec.describe PostAction do freeze_time timer.execute_at SiteSetting.num_flaggers_to_close_topic = 10 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) diff --git a/spec/models/reviewable_flagged_post_spec.rb b/spec/models/reviewable_flagged_post_spec.rb index 2faa5d2cddb..691276e5687 100644 --- a/spec/models/reviewable_flagged_post_spec.rb +++ b/spec/models/reviewable_flagged_post_spec.rb @@ -292,7 +292,7 @@ RSpec.describe ReviewableFlaggedPost, type: :model do flagged_reply = Fabricate(:reviewable_flagged_post, target: reply) 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 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_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 diff --git a/spec/models/reviewable_history_spec.rb b/spec/models/reviewable_history_spec.rb index 17d2db7e167..0b01814321b 100644 --- a/spec/models/reviewable_history_spec.rb +++ b/spec/models/reviewable_history_spec.rb @@ -14,8 +14,8 @@ RSpec.describe ReviewableHistory, type: :model do history = reviewable.history expect(history.size).to eq(3) - expect(history[0].reviewable_history_type).to eq(ReviewableHistory.types[:created]) - expect(history[0].status).to eq(Reviewable.statuses[:pending]) + expect(history[0]).to be_created + expect(history[0]).to be_pending expect(history[0].created_by).to eq(admin) end @@ -26,12 +26,12 @@ RSpec.describe ReviewableHistory, type: :model do history = reviewable.history expect(history.size).to eq(3) - expect(history[1].reviewable_history_type).to eq(ReviewableHistory.types[:transitioned]) - expect(history[1].status).to eq(Reviewable.statuses[:approved]) + expect(history[1]).to be_transitioned + expect(history[1]).to be_approved expect(history[1].created_by).to eq(moderator) - expect(history[2].reviewable_history_type).to eq(ReviewableHistory.types[:transitioned]) - expect(history[2].status).to eq(Reviewable.statuses[:pending]) + expect(history[2]).to be_transitioned + expect(history[2]).to be_pending expect(history[2].created_by).to eq(admin) end @@ -52,7 +52,7 @@ RSpec.describe ReviewableHistory, type: :model do history = reviewable.history 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].edited).to eq("category_id" => [old_category.id, nil]) end diff --git a/spec/models/reviewable_post_spec.rb b/spec/models/reviewable_post_spec.rb index 0ff65c50452..cba3af49da9 100644 --- a/spec/models/reviewable_post_spec.rb +++ b/spec/models/reviewable_post_spec.rb @@ -9,8 +9,8 @@ RSpec.describe ReviewablePost do let(:guardian) { Guardian.new } it 'Does not return available actions when the reviewable is no longer pending' do - available_actions = (Reviewable.statuses.keys - [:pending]).reduce([]) do |actions, status| - reviewable.status = Reviewable.statuses[status] + available_actions = (Reviewable.statuses.keys - ["pending"]).reduce([]) do |actions, status| + reviewable.status = status actions.concat reviewable_actions(guardian).to_a end diff --git a/spec/models/reviewable_queued_post_spec.rb b/spec/models/reviewable_queued_post_spec.rb index b745ebf4bb7..1d79a301f43 100644 --- a/spec/models/reviewable_queued_post_spec.rb +++ b/spec/models/reviewable_queued_post_spec.rb @@ -85,7 +85,7 @@ RSpec.describe ReviewableQueuedPost, type: :model do post = Fabricate(:post, user: newuser) PostActionCreator.spam(moderator, post) 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 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 it "updates user stats" do user_stats.expects(:update_pending_posts) - reviewable.update!(status: described_class.statuses[:approved]) + reviewable.update!(status: :approved) end end diff --git a/spec/models/reviewable_spec.rb b/spec/models/reviewable_spec.rb index 342380bb869..9c1d63d0129 100644 --- a/spec/models/reviewable_spec.rb +++ b/spec/models/reviewable_spec.rb @@ -427,8 +427,8 @@ RSpec.describe Reviewable, type: :model do expect { PostActionCreator.spam(Fabricate(:user), post) } .to change { reviewable.reload.status } - .from(Reviewable.statuses[:rejected]) - .to(Reviewable.statuses[:pending]) + .from("rejected") + .to("pending") .and change { Jobs::NotifyReviewable.jobs.size } .by(1) end @@ -521,77 +521,77 @@ RSpec.describe Reviewable, type: :model do describe ".score_required_to_hide_post" do it "will return the default visibility if it's higher" do - Reviewable.set_priorities(low: 40.0, high: 100.0) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.score_required_to_hide_post).to eq(40.0) + described_class.set_priorities(low: 40.0, high: 100.0) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high] + expect(described_class.score_required_to_hide_post).to eq(40.0) end it "returns a default if we can't calculated any percentiles" do - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.score_required_to_hide_post).to eq(12.5) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium] - 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) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:low] + expect(described_class.score_required_to_hide_post).to eq(12.5) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:medium] + expect(described_class.score_required_to_hide_post).to eq(8.33) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high] + expect(described_class.score_required_to_hide_post).to eq(4.16) end it "returns a fraction of the high percentile" do - Reviewable.set_priorities(high: 100.0) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] - expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(Float::MAX) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(100.0) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium] - expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(66.66) - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(33.33) + described_class.set_priorities(high: 100.0) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:disabled] + expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(Float::MAX) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:low] + expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(100.0) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:medium] + expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(66.66) + SiteSetting.hide_post_sensitivity = described_class.sensitivities[:high] + expect(described_class.score_required_to_hide_post.to_f.truncate(2)).to eq(33.33) end end describe ".spam_score_to_silence_new_user" do it "returns a default value if we can't calculated any percentiles" do - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.spam_score_to_silence_new_user).to eq(7.5) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium] - expect(Reviewable.spam_score_to_silence_new_user).to eq(4.99) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.spam_score_to_silence_new_user).to eq(2.49) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:low] + expect(described_class.spam_score_to_silence_new_user).to eq(7.5) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:medium] + expect(described_class.spam_score_to_silence_new_user).to eq(4.99) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:high] + expect(described_class.spam_score_to_silence_new_user).to eq(2.49) end it "returns a fraction of the high percentile" do - Reviewable.set_priorities(high: 100.0) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled] - expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(Float::MAX) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(60.0) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium] - expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(39.99) - SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.spam_score_to_silence_new_user.to_f).to eq(19.99) + described_class.set_priorities(high: 100.0) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:disabled] + expect(described_class.spam_score_to_silence_new_user.to_f).to eq(Float::MAX) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:low] + expect(described_class.spam_score_to_silence_new_user.to_f).to eq(60.0) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:medium] + expect(described_class.spam_score_to_silence_new_user.to_f).to eq(39.99) + SiteSetting.silence_new_user_sensitivity = described_class.sensitivities[:high] + expect(described_class.spam_score_to_silence_new_user.to_f).to eq(19.99) end end describe ".score_to_auto_close_topic" do it "returns the default if we can't calculated any percentiles" do - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.score_to_auto_close_topic).to eq(31.25) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium] - expect(Reviewable.score_to_auto_close_topic).to eq(20.83) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.score_to_auto_close_topic).to eq(10.41) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:low] + expect(described_class.score_to_auto_close_topic).to eq(31.25) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:medium] + expect(described_class.score_to_auto_close_topic).to eq(20.83) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:high] + expect(described_class.score_to_auto_close_topic).to eq(10.41) end it "returns a fraction of the high percentile" do - Reviewable.set_priorities(high: 100.0) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:disabled] - expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(Float::MAX) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low] - expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(250.0) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium] - expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(166.66) - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] - expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(83.33) + described_class.set_priorities(high: 100.0) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:disabled] + expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(Float::MAX) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:low] + expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(250.0) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:medium] + expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(166.66) + SiteSetting.auto_close_topic_sensitivity = described_class.sensitivities[:high] + expect(described_class.score_to_auto_close_topic.to_f.truncate(2)).to eq(83.33) end end diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index 9d65c6d9936..7a8ddeafb52 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -2909,7 +2909,7 @@ RSpec.describe Topic do Reviewable.set_priorities(low: 2.0, medium: 6.0, high: 9.0) SiteSetting.num_flaggers_to_close_topic = 2 SiteSetting.reviewable_default_visibility = 'medium' - SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high] + SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivities[:high] post = Fabricate(:post) @topic = post.topic @reviewable = Fabricate(:reviewable_flagged_post, target: post, topic: @topic) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d2e01363cfb..70dc777cfcf 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2602,35 +2602,44 @@ RSpec.describe User do end 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 - reviewable_user.target.grant_admin! + context 'when the user isn’t approved yet' do + 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 - it 'does nothing when the user is already approved' do - reviewable_user = Fabricate(:reviewable_user) - reviewable_user.perform(Discourse.system_user, :approve_user) + context 'when granting moderator status' do + context 'when there is a reviewable' do + let(:user) { Fabricate(:reviewable_user) } - reviewable_user.target.grant_admin! - - expect(reviewable_user.reload.status).to eq Reviewable.statuses[:approved] - 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) + it 'approves the associated reviewable' do + expect { user.target.grant_moderation! }.to change { user.reload.dup }.to be_approved + end + end end end diff --git a/spec/serializers/reviewable_serializer_spec.rb b/spec/serializers/reviewable_serializer_spec.rb index 8d7053194d7..b3a90c90464 100644 --- a/spec/serializers/reviewable_serializer_spec.rb +++ b/spec/serializers/reviewable_serializer_spec.rb @@ -9,7 +9,7 @@ RSpec.describe ReviewableSerializer do json = described_class.new(reviewable, scope: Guardian.new(admin), root: nil).as_json 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[:created_at]).to eq(reviewable.created_at) expect(json[:category_id]).to eq(reviewable.category_id) diff --git a/spec/services/auto_silence_spec.rb b/spec/services/auto_silence_spec.rb index 2f0c787a950..0c138266162 100644 --- a/spec/services/auto_silence_spec.rb +++ b/spec/services/auto_silence_spec.rb @@ -2,9 +2,9 @@ RSpec.describe SpamRule::AutoSilence do before do - SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled] + SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:disabled] 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 end @@ -20,7 +20,7 @@ RSpec.describe SpamRule::AutoSilence do it 'delivers punishment when user should be silenced' do 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 PostActionCreator.spam(Discourse.system_user, post) subject.perform @@ -194,7 +194,7 @@ RSpec.describe SpamRule::AutoSilence do end 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(flagger2, post) expect(subject.should_autosilence?).to eq(false) diff --git a/spec/services/flag_sockpuppets_spec.rb b/spec/services/flag_sockpuppets_spec.rb index f67bd67f1aa..edfb9de9933 100644 --- a/spec/services/flag_sockpuppets_spec.rb +++ b/spec/services/flag_sockpuppets_spec.rb @@ -156,7 +156,7 @@ RSpec.describe SpamRule::FlagSockpuppets do described_class.new(post2).perform - expect(flagged_post.reload.status).to eq(Reviewable.statuses[:rejected]) + expect(flagged_post.reload).to be_rejected end it "doesn't flag the post if another post of the same user was rejected by staff before" do diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index b1e5478bc00..67d1508ce22 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -308,7 +308,7 @@ RSpec.describe PostAlerter do PostActionNotifier.enable 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(walterwhite, post) diff --git a/spec/services/user_destroyer_spec.rb b/spec/services/user_destroyer_spec.rb index 2865440acd2..4a053d66b02 100644 --- a/spec/services/user_destroyer_spec.rb +++ b/spec/services/user_destroyer_spec.rb @@ -106,7 +106,7 @@ RSpec.describe UserDestroyer do it 'sets the reviewable user as rejected' do UserDestroyer.new(admin).destroy(reviewable.target) - expect(reviewable.reload.status).to eq(Reviewable.statuses[:rejected]) + expect(reviewable.reload).to be_rejected end end