Automatically resolve spam reports when the offending user is marked as spam (#20781)
* Start resolving spam reports automatically after assigning spam role * Specs for resolving spam reports + async resolving
This commit is contained in:
parent
c3c8b5f9c4
commit
1008f0af7d
6 changed files with 153 additions and 0 deletions
|
|
@ -78,6 +78,7 @@ module Moderator
|
|||
user.add_role(:spam)
|
||||
remove_privileges
|
||||
remove_notifications
|
||||
resolve_spam_reports
|
||||
when "Super Moderator"
|
||||
assign_elevated_role_to_user(user, :super_moderator)
|
||||
TagModerators::AddTrustedRole.call(user)
|
||||
|
|
@ -158,5 +159,11 @@ module Moderator
|
|||
def update_roles
|
||||
handle_user_status(user_params[:user_status], user_params[:note_for_current_role])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resolve_spam_reports
|
||||
Users::ResolveSpamReportsWorker.perform_async(user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
35
app/services/users/resolve_spam_reports.rb
Normal file
35
app/services/users/resolve_spam_reports.rb
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
module Users
|
||||
class ResolveSpamReports
|
||||
def self.call(...)
|
||||
new(...).call
|
||||
end
|
||||
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def call
|
||||
relation = FeedbackMessage.where(status: "Open", category: "spam")
|
||||
|
||||
# profile reports by url and by path
|
||||
profile_reports = relation.where(reported_url: [URL.url(user.path), user.path])
|
||||
profile_reports.update_all(status: "Resolved")
|
||||
|
||||
# articles can be reported by url or by path
|
||||
article_paths = user.articles.map(&:path)
|
||||
article_paths += article_paths.map { |p| URL.url(p) }
|
||||
article_reports = relation.where(reported_url: article_paths)
|
||||
article_reports.update_all(status: "Resolved")
|
||||
|
||||
# comments can be reported by url or by path
|
||||
comment_paths = user.comments.map(&:path)
|
||||
comment_paths += comment_paths.map { |p| URL.url(p) }
|
||||
comment_reports = relation.where(reported_url: comment_paths)
|
||||
comment_reports.update_all(status: "Resolved")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :user
|
||||
end
|
||||
end
|
||||
14
app/workers/users/resolve_spam_reports_worker.rb
Normal file
14
app/workers/users/resolve_spam_reports_worker.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
module Users
|
||||
class ResolveSpamReportsWorker
|
||||
include Sidekiq::Job
|
||||
|
||||
sidekiq_options queue: :medium_priority, retry: 10, lock: :until_executing
|
||||
|
||||
def perform(user_id)
|
||||
user = User.find_by(id: user_id)
|
||||
return unless user
|
||||
|
||||
Users::ResolveSpamReports.call(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -250,6 +250,29 @@ RSpec.describe Moderator::ManageActivityAndRoles, type: :service do
|
|||
end
|
||||
end
|
||||
|
||||
describe "removes reports when adding the spam role" do
|
||||
let(:spam_user) { create(:user) }
|
||||
let(:spam_article) { create(:article, user: spam_user) }
|
||||
let!(:report) do
|
||||
create(:feedback_message, category: "spam", status: "Open", reported_url: URL.url(spam_article.path))
|
||||
end
|
||||
|
||||
it "calls ResolveSpamReports" do
|
||||
allow(Users::ResolveSpamReports).to receive(:call)
|
||||
sidekiq_perform_enqueued_jobs do
|
||||
manage_roles_for(spam_user, user_status: "Spam")
|
||||
end
|
||||
expect(Users::ResolveSpamReports).to have_received(:call).with(spam_user)
|
||||
end
|
||||
|
||||
it "actually removes the report" do
|
||||
sidekiq_perform_enqueued_jobs do
|
||||
manage_roles_for(spam_user, user_status: "Spam")
|
||||
end
|
||||
expect(report.reload.status).to eq("Resolved")
|
||||
end
|
||||
end
|
||||
|
||||
describe "removes notifications when adding the spam role" do
|
||||
let(:nice_article) { create(:article, user: user) }
|
||||
let(:spam_user) { create(:user) }
|
||||
|
|
|
|||
55
spec/services/users/resolve_spam_reports_spec.rb
Normal file
55
spec/services/users/resolve_spam_reports_spec.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Users::ResolveSpamReports, type: :service do
|
||||
let(:user) { create(:user) }
|
||||
let(:user2) { create(:user) }
|
||||
let(:article) { create(:article, user: user) }
|
||||
let(:article2) { create(:article, user: user) }
|
||||
let(:article3) { create(:article, user: user2) }
|
||||
let(:comment) { create(:comment, user: user, commentable: article2) }
|
||||
let(:comment2) { create(:comment, user: user, commentable: article) }
|
||||
|
||||
it "doesn't fail when user has no reports" do
|
||||
described_class.call(user)
|
||||
end
|
||||
|
||||
def spam_report(url)
|
||||
create(:feedback_message, category: "spam", status: "Open", reported_url: url)
|
||||
end
|
||||
|
||||
context "with reports" do
|
||||
let!(:rep) { spam_report(user.path) }
|
||||
let!(:rep2) { spam_report(URL.url(user.path)) }
|
||||
let!(:a_rep) { spam_report(article.path) }
|
||||
let!(:a_rep2) { spam_report(URL.url(article2.path)) }
|
||||
let!(:c_rep) { spam_report(comment.path) }
|
||||
let!(:c_rep2) { spam_report(URL.url(comment2.path)) }
|
||||
|
||||
it "updates statused of the user's profile, article and comment reports", :aggregate_failures do
|
||||
described_class.call(user)
|
||||
expect(rep.reload.status).to eq("Resolved")
|
||||
expect(rep2.reload.status).to eq("Resolved")
|
||||
expect(a_rep.reload.status).to eq("Resolved")
|
||||
expect(a_rep2.reload.status).to eq("Resolved")
|
||||
expect(c_rep.reload.status).to eq("Resolved")
|
||||
expect(c_rep2.reload.status).to eq("Resolved")
|
||||
end
|
||||
|
||||
it "doesn't update non-spam reports" do
|
||||
other_rep = create(:feedback_message, category: "other", status: "Open", reported_url: user.path)
|
||||
harassment_rep = create(:feedback_message, category: "harassment", status: "Open",
|
||||
reported_url: URL.url(article.path))
|
||||
described_class.call(user)
|
||||
expect(other_rep.reload.status).to eq("Open")
|
||||
expect(harassment_rep.reload.status).to eq("Open")
|
||||
end
|
||||
|
||||
it "doesn't update other users reports" do
|
||||
u2_rep = spam_report(URL.url(user2.path))
|
||||
a3_rep = spam_report(article3.path)
|
||||
described_class.call(user)
|
||||
expect(u2_rep.reload.status).to eq("Open")
|
||||
expect(a3_rep.reload.status).to eq("Open")
|
||||
end
|
||||
end
|
||||
end
|
||||
19
spec/workers/users/resolve_spam_reports_worker_spec.rb
Normal file
19
spec/workers/users/resolve_spam_reports_worker_spec.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Users::ResolveSpamReportsWorker, type: :worker do
|
||||
describe "#perform" do
|
||||
let(:user) { create(:user) }
|
||||
let(:worker) { subject }
|
||||
|
||||
it "calls spam reports resolver" do
|
||||
allow(Users::ResolveSpamReports).to receive(:call).with(user)
|
||||
|
||||
worker.perform(user.id)
|
||||
expect(Users::ResolveSpamReports).to have_received(:call).with(user)
|
||||
end
|
||||
|
||||
it "doesn't fail with invalid url" do
|
||||
worker.perform(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue