diff --git a/app/services/moderator/manage_activity_and_roles.rb b/app/services/moderator/manage_activity_and_roles.rb index 800d4b721..4cb06be20 100644 --- a/app/services/moderator/manage_activity_and_roles.rb +++ b/app/services/moderator/manage_activity_and_roles.rb @@ -79,6 +79,7 @@ module Moderator remove_privileges remove_notifications resolve_spam_reports + confirm_flag_reactions when "Super Moderator" assign_elevated_role_to_user(user, :super_moderator) TagModerators::AddTrustedRole.call(user) @@ -165,5 +166,9 @@ module Moderator def resolve_spam_reports Users::ResolveSpamReportsWorker.perform_async(user.id) end + + def confirm_flag_reactions + Users::ConfirmFlagReactionsWorker.perform_async(user.id) + end end end diff --git a/app/services/users/confirm_flag_reactions.rb b/app/services/users/confirm_flag_reactions.rb new file mode 100644 index 000000000..f89f368d3 --- /dev/null +++ b/app/services/users/confirm_flag_reactions.rb @@ -0,0 +1,27 @@ +module Users + class ConfirmFlagReactions + def self.call(...) + new(...).call + end + + def initialize(user) + @user = user + end + + def call + relation = Reaction.where(category: "vomit", status: "valid").live_reactable + user_flags = relation.where(reactable: user) + user_flags.update_all(status: "confirmed") + + article_flags = relation.where(reactable: user.articles) + article_flags.update_all(status: "confirmed") + + comment_flags = relation.where(reactable: user.comments) + comment_flags.update_all(status: "confirmed") + end + + private + + attr_reader :user + end +end diff --git a/app/workers/users/confirm_flag_reactions_worker.rb b/app/workers/users/confirm_flag_reactions_worker.rb new file mode 100644 index 000000000..6e5cc2380 --- /dev/null +++ b/app/workers/users/confirm_flag_reactions_worker.rb @@ -0,0 +1,14 @@ +module Users + class ConfirmFlagReactionsWorker + 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::ConfirmFlagReactions.call(user) + end + end +end diff --git a/spec/services/moderator/manage_activity_and_roles_spec.rb b/spec/services/moderator/manage_activity_and_roles_spec.rb index fbb363b03..64075aca5 100644 --- a/spec/services/moderator/manage_activity_and_roles_spec.rb +++ b/spec/services/moderator/manage_activity_and_roles_spec.rb @@ -273,6 +273,38 @@ RSpec.describe Moderator::ManageActivityAndRoles, type: :service do end end + describe "confirms flag reactions when adding the spam role" do + let(:spam_user) { create(:user) } + let(:spam_article) { create(:article, user: spam_user) } + let!(:flag) do + create(:reaction, category: "vomit", status: "valid", reactable: spam_article, user: admin) + end + + it "schedules ConfirmFlagReactionsWorker" do + sidekiq_assert_enqueued_with( + job: Users::ConfirmFlagReactionsWorker, + args: [spam_user.id], + ) do + manage_roles_for(spam_user, user_status: "Spam") + end + end + + it "calls ConfirmFlagReactionsWorker" do + allow(Users::ConfirmFlagReactions).to receive(:call) + sidekiq_perform_enqueued_jobs do + manage_roles_for(spam_user, user_status: "Spam") + end + expect(Users::ConfirmFlagReactions).to have_received(:call).with(spam_user) + end + + it "actually confirms the flag" do + sidekiq_perform_enqueued_jobs do + manage_roles_for(spam_user, user_status: "Spam") + end + expect(flag.reload.status).to eq("confirmed") + end + end + describe "removes notifications when adding the spam role" do let(:nice_article) { create(:article, user: user) } let(:spam_user) { create(:user) } diff --git a/spec/services/users/confirm_flag_reactions_spec.rb b/spec/services/users/confirm_flag_reactions_spec.rb new file mode 100644 index 000000000..c277bdc3b --- /dev/null +++ b/spec/services/users/confirm_flag_reactions_spec.rb @@ -0,0 +1,56 @@ +require "rails_helper" + +RSpec.describe Users::ConfirmFlagReactions, type: :service do + let(:user) { create(:user, :trusted) } + let(:user2) { create(:user, :trusted) } + 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 reactions" do + described_class.call(user) + end + + def flag_reaction(reactable) + create(:reaction, category: "vomit", status: "valid", reactable: reactable, user: user2) + end + + context "with flag reactions" do + let!(:user_flag) { flag_reaction(user) } + let!(:article_flag) { flag_reaction(article) } + let!(:article2_flag) { flag_reaction(article2) } + let!(:comment_flag) { flag_reaction(comment) } + let!(:comment2_flag) { flag_reaction(comment2) } + + it "updates statuses of the flag reactions to user, articles and comments", :aggregate_failures do + described_class.call(user) + expect(user_flag.reload.status).to eq("confirmed") + expect(article_flag.reload.status).to eq("confirmed") + expect(article2_flag.reload.status).to eq("confirmed") + expect(comment_flag.reload.status).to eq("confirmed") + expect(comment2_flag.reload.status).to eq("confirmed") + end + + it "doesn't update non-flag (non-vomit) reactions", :aggregate_failures do + reaction = create(:reaction, category: "thumbsup", status: "valid", reactable: user, user: user2) + reaction2 = create(:reaction, category: "thumbsdown", status: "valid", reactable: article, user: user2) + + described_class.call(user) + + expect(reaction.reload.status).to eq("valid") + expect(reaction2.reload.status).to eq("valid") + end + + it "doesn't update other users reports", :aggregate_failures do + user2_flag = create(:reaction, category: "vomit", status: "valid", reactable: user2, user: user) + article3_flag = create(:reaction, category: "vomit", status: "valid", reactable: article3, user: user) + + described_class.call(user) + + expect(user2_flag.reload.status).to eq("valid") + expect(article3_flag.reload.status).to eq("valid") + end + end +end diff --git a/spec/workers/users/confirm_flag_reactions_worker_spec.rb b/spec/workers/users/confirm_flag_reactions_worker_spec.rb new file mode 100644 index 000000000..cb821f836 --- /dev/null +++ b/spec/workers/users/confirm_flag_reactions_worker_spec.rb @@ -0,0 +1,19 @@ +require "rails_helper" + +RSpec.describe Users::ConfirmFlagReactionsWorker, type: :worker do + describe "#perform" do + let(:user) { create(:user) } + let(:worker) { subject } + + it "calls spam reports resolver" do + allow(Users::ConfirmFlagReactions).to receive(:call).with(user) + + worker.perform(user.id) + expect(Users::ConfirmFlagReactions).to have_received(:call).with(user) + end + + it "doesn't fail with invalid url" do + worker.perform(-1) + end + end +end