From 3cec3882ee925460c3afebe1eaca0b39cd6719c9 Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Sat, 19 Oct 2024 01:49:19 +0100 Subject: [PATCH 1/8] AO3-6810 Add work.hidden_for_spam virtual attribute --- app/models/moderated_work.rb | 1 + app/models/work.rb | 7 ++++++- features/admins/admin_works.feature | 25 +++++++++++++++++++++++++ features/step_definitions/work_steps.rb | 5 +++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/models/moderated_work.rb b/app/models/moderated_work.rb index e6124be2471..67d1b4962b2 100644 --- a/app/models/moderated_work.rb +++ b/app/models/moderated_work.rb @@ -41,6 +41,7 @@ def self.bulk_review(ids) where(id: ids).update_all(reviewed: true, approved: false) # Ensure works are hidden and spam if they weren't already Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| + work.hidden_for_spam = true work.update(hidden_by_admin: true, spam: true) end end diff --git a/app/models/work.rb b/app/models/work.rb index 0881823f956..5f784d7462f 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -75,6 +75,9 @@ def create_stat_counter attr_accessor :new_gifts attr_accessor :preview_mode + # Virtual attribute for when a work is to be hidden, whether if it's for spam or other reasons, so different emails can be sent + attr_accessor :hidden_for_spam + # return title.html_safe to overcome escaping done by sanitiser def title read_attribute(:title).try(:html_safe) @@ -1121,6 +1124,7 @@ def hide_spam return unless spam? admin_settings = AdminSetting.current if admin_settings.hide_spam? + self.hidden_for_spam = true self.hidden_by_admin = true end end @@ -1132,6 +1136,7 @@ def moderate_spam def mark_as_spam! update_attribute(:spam, true) ModeratedWork.mark_reviewed(self) + self.hidden_for_spam = true # don't submit spam reports unless in production mode Rails.env.production? && Akismetor.submit_spam(akismet_attributes) end @@ -1146,7 +1151,7 @@ def mark_as_ham! def notify_of_hiding return unless hidden_by_admin? && saved_change_to_hidden_by_admin? users.each do |user| - if spam? + if spam? && hidden_for_spam UserMailer.admin_spam_work_notification(id, user.id).deliver_after_commit else UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit diff --git a/features/admins/admin_works.feature b/features/admins/admin_works.feature index 39807cbd650..ec3f6315486 100644 --- a/features/admins/admin_works.feature +++ b/features/admins/admin_works.feature @@ -32,6 +32,27 @@ Feature: Admin Actions for Works, Comments, Series, Bookmarks | superadmin | | legal | | policy_and_abuse | + + Scenario Outline: Can hide works already marked as spam + Given I am logged in as "regular_user" + And I post the work "ToS Violation + Spam" + And the work "ToS Violation + Spam" is marked as spam + When I am logged in as a "<role>" admin + And all emails have been delivered + And I view the work "ToS Violation + Spam" + And I follow "Hide Work" + Then I should see "Item has been hidden." + And logged out users should not see the hidden work "ToS Violation + Spam" by "regular_user" + And logged in users should not see the hidden work "ToS Violation + Spam" by "regular_user" + And "regular_user" should see their work "ToS Violation + Spam" is hidden + And 1 email should be delivered + And the email should contain "you will be required to take action to correct the violation" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | Scenario Outline: Can unhide works Given I am logged in as "regular_user" @@ -361,12 +382,16 @@ Feature: Admin Actions for Works, Comments, Series, Bookmarks Given the work "Spammity Spam" And I am logged in as a "policy_and_abuse" admin And I view the work "Spammity Spam" + And all emails have been delivered Then I should see "Mark As Spam" When I follow "Mark As Spam" Then I should see "marked as spam and hidden" And I should see "Mark Not Spam" And the work "Spammity Spam" should be marked as spam And the work "Spammity Spam" should be hidden + And 1 email should be delivered + And the email should contain "has been flagged by our automated system as spam" + Scenario: can mark a spam work as not-spam Given the spam work "Spammity Spam" diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb index 0086cbfe51f..40e227ff574 100644 --- a/features/step_definitions/work_steps.rb +++ b/features/step_definitions/work_steps.rb @@ -264,6 +264,11 @@ w.update_attribute(:hidden_by_admin, true) end +Given /^the work "([^\"]*)" is marked as spam$/ do |work| + w = Work.find_by_title(work) + w.update_attribute(:spam, true) +end + Given "the user-defined tag limit is {int}" do |count| allow(ArchiveConfig).to receive(:USER_DEFINED_TAGS_MAX).and_return(count) end From d9d90068dc51b79dd2b6fc0c63b70edc1609f868 Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Wed, 20 Nov 2024 22:51:38 +0000 Subject: [PATCH 2/8] AO3-6810 Remove virtual attribute and add tests for bulk hiding --- .../admin/user_creations_controller.rb | 5 ++- app/models/moderated_work.rb | 4 ++- app/models/work.rb | 20 +++++------ features/admins/admin_spam.feature | 35 +++++++++++++++++-- features/admins/admin_works.feature | 2 +- features/step_definitions/work_steps.rb | 4 ++- 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/app/controllers/admin/user_creations_controller.rb b/app/controllers/admin/user_creations_controller.rb index 6e5d0300a33..c088d6d509c 100644 --- a/app/controllers/admin/user_creations_controller.rb +++ b/app/controllers/admin/user_creations_controller.rb @@ -38,7 +38,10 @@ def set_spam AdminActivity.log_action(current_admin, @creation, action: action, summary: @creation.inspect) if params[:spam] == "true" @creation.mark_as_spam! - @creation.update_attribute(:hidden_by_admin, true) + if not @creation.hidden_by_admin + @creation.notify_of_hiding_for_spam() if @creation_class == Work + @creation.update_attribute(:hidden_by_admin, true) + end flash[:notice] = ts("Work was marked as spam and hidden.") else @creation.mark_as_ham! diff --git a/app/models/moderated_work.rb b/app/models/moderated_work.rb index 67d1b4962b2..2a8d15cb50b 100644 --- a/app/models/moderated_work.rb +++ b/app/models/moderated_work.rb @@ -41,7 +41,9 @@ def self.bulk_review(ids) where(id: ids).update_all(reviewed: true, approved: false) # Ensure works are hidden and spam if they weren't already Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| - work.hidden_for_spam = true + if not work.hidden_by_admin? + work.notify_of_hiding_for_spam() + end work.update(hidden_by_admin: true, spam: true) end end diff --git a/app/models/work.rb b/app/models/work.rb index 5f784d7462f..ea9ff6671c3 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -75,9 +75,6 @@ def create_stat_counter attr_accessor :new_gifts attr_accessor :preview_mode - # Virtual attribute for when a work is to be hidden, whether if it's for spam or other reasons, so different emails can be sent - attr_accessor :hidden_for_spam - # return title.html_safe to overcome escaping done by sanitiser def title read_attribute(:title).try(:html_safe) @@ -1124,8 +1121,9 @@ def hide_spam return unless spam? admin_settings = AdminSetting.current if admin_settings.hide_spam? - self.hidden_for_spam = true + return if self.hidden_by_admin self.hidden_by_admin = true + notify_of_hiding_for_spam() end end @@ -1136,7 +1134,6 @@ def moderate_spam def mark_as_spam! update_attribute(:spam, true) ModeratedWork.mark_reviewed(self) - self.hidden_for_spam = true # don't submit spam reports unless in production mode Rails.env.production? && Akismetor.submit_spam(akismet_attributes) end @@ -1150,12 +1147,15 @@ def mark_as_ham! def notify_of_hiding return unless hidden_by_admin? && saved_change_to_hidden_by_admin? + return if spam? users.each do |user| - if spam? && hidden_for_spam - UserMailer.admin_spam_work_notification(id, user.id).deliver_after_commit - else - UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit - end + UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit + end + end + + def notify_of_hiding_for_spam + users.each do |user| + UserMailer.admin_spam_work_notification(id, user.id).deliver_after_commit end end diff --git a/features/admins/admin_spam.feature b/features/admins/admin_spam.feature index ded7525a80c..cca10b26247 100644 --- a/features/admins/admin_spam.feature +++ b/features/admins/admin_spam.feature @@ -4,10 +4,39 @@ Feature: Admin spam management As an an admin I want to be able to view and update works marked as spam -Scenario: Review spam - Given the spam work "Spammity Spam" +Scenario: Review spam when spam works are already hidden + Given the following admin settings are configured: + | hide_spam | 1 | + And the spam work "Spammity Spam" And the spam work "Totally Legit" + And the work "Spammity Spam" should be hidden + And the work "Totally Legit" should be hidden + And I am logged in as a "superadmin" admin + And all emails have been delivered + Then I should see "Spam" + When I follow "Spam" + Then I should see "Works Marked as Spam" + And I should see "Spammity" + And I should see "Totally Legit" + When I check "spam_1" + And I check "ham_2" + And I press "Update Works" + Then I should not see "Spammity" + And I should not see "Totally Legit" + And the work "Spammity Spam" should be hidden + And the work "Totally Legit" should not be hidden + And 0 email should be delivered + + +Scenario: Review spam when spam works are not already hidden + Given the following admin settings are configured: + | hide_spam | 0 | + And the spam work "Spammity Spam" + And the spam work "Totally Legit" + And the work "Spammity Spam" should not be hidden + And the work "Totally Legit" should not be hidden And I am logged in as a "superadmin" admin + And all emails have been delivered Then I should see "Spam" When I follow "Spam" Then I should see "Works Marked as Spam" @@ -20,3 +49,5 @@ Scenario: Review spam And I should not see "Totally Legit" And the work "Spammity Spam" should be hidden And the work "Totally Legit" should not be hidden + And 1 email should be delivered + And the email should contain "has been flagged by our automated system as spam" diff --git a/features/admins/admin_works.feature b/features/admins/admin_works.feature index ec3f6315486..4478dc0d9fc 100644 --- a/features/admins/admin_works.feature +++ b/features/admins/admin_works.feature @@ -382,7 +382,7 @@ Feature: Admin Actions for Works, Comments, Series, Bookmarks Given the work "Spammity Spam" And I am logged in as a "policy_and_abuse" admin And I view the work "Spammity Spam" - And all emails have been delivered + And all emails have been delivered Then I should see "Mark As Spam" When I follow "Mark As Spam" Then I should see "marked as spam and hidden" diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb index 40e227ff574..8b0ade36078 100644 --- a/features/step_definitions/work_steps.rb +++ b/features/step_definitions/work_steps.rb @@ -261,7 +261,9 @@ step %{I log out} w = Work.find_by_title(work) w.update_attribute(:spam, true) - w.update_attribute(:hidden_by_admin, true) + + admin_settings = AdminSetting.current + w.update_attribute(:hidden_by_admin, true) if admin_settings.hide_spam? end Given /^the work "([^\"]*)" is marked as spam$/ do |work| From 94718747392603b25e52a27ba927ad4036da0a7f Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Wed, 20 Nov 2024 22:56:40 +0000 Subject: [PATCH 3/8] AO3-6810 Rubocop code style --- app/controllers/admin/user_creations_controller.rb | 4 ++-- app/models/moderated_work.rb | 4 ++-- app/models/work.rb | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/user_creations_controller.rb b/app/controllers/admin/user_creations_controller.rb index c088d6d509c..69272e2b800 100644 --- a/app/controllers/admin/user_creations_controller.rb +++ b/app/controllers/admin/user_creations_controller.rb @@ -38,8 +38,8 @@ def set_spam AdminActivity.log_action(current_admin, @creation, action: action, summary: @creation.inspect) if params[:spam] == "true" @creation.mark_as_spam! - if not @creation.hidden_by_admin - @creation.notify_of_hiding_for_spam() if @creation_class == Work + unless @creation.hidden_by_admin + @creation.notify_of_hiding_for_spam if @creation_class == Work @creation.update_attribute(:hidden_by_admin, true) end flash[:notice] = ts("Work was marked as spam and hidden.") diff --git a/app/models/moderated_work.rb b/app/models/moderated_work.rb index 2a8d15cb50b..56607530b0e 100644 --- a/app/models/moderated_work.rb +++ b/app/models/moderated_work.rb @@ -41,8 +41,8 @@ def self.bulk_review(ids) where(id: ids).update_all(reviewed: true, approved: false) # Ensure works are hidden and spam if they weren't already Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| - if not work.hidden_by_admin? - work.notify_of_hiding_for_spam() + unless work.hidden_by_admin? + work.notify_of_hiding_for_spam end work.update(hidden_by_admin: true, spam: true) end diff --git a/app/models/work.rb b/app/models/work.rb index ea9ff6671c3..ef528cb6f29 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -1122,8 +1122,9 @@ def hide_spam admin_settings = AdminSetting.current if admin_settings.hide_spam? return if self.hidden_by_admin + self.hidden_by_admin = true - notify_of_hiding_for_spam() + notify_of_hiding_for_spam end end @@ -1148,6 +1149,7 @@ def mark_as_ham! def notify_of_hiding return unless hidden_by_admin? && saved_change_to_hidden_by_admin? return if spam? + users.each do |user| UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit end From 481989b15bcf4ee6984acff345d41c4f2d801009 Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Thu, 21 Nov 2024 00:04:18 +0000 Subject: [PATCH 4/8] AO3-6810 Fix test --- app/controllers/admin/user_creations_controller.rb | 4 ++-- app/models/work.rb | 4 ++-- features/admins/admin_spam.feature | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/user_creations_controller.rb b/app/controllers/admin/user_creations_controller.rb index 69272e2b800..9bffc42a017 100644 --- a/app/controllers/admin/user_creations_controller.rb +++ b/app/controllers/admin/user_creations_controller.rb @@ -37,11 +37,11 @@ def set_spam action = "mark as " + (params[:spam] == "true" ? "spam" : "not spam") AdminActivity.log_action(current_admin, @creation, action: action, summary: @creation.inspect) if params[:spam] == "true" - @creation.mark_as_spam! unless @creation.hidden_by_admin @creation.notify_of_hiding_for_spam if @creation_class == Work - @creation.update_attribute(:hidden_by_admin, true) + @creation.hidden_by_admin = true end + @creation.mark_as_spam! flash[:notice] = ts("Work was marked as spam and hidden.") else @creation.mark_as_ham! diff --git a/app/models/work.rb b/app/models/work.rb index ef528cb6f29..cd1ec0a7a7c 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -1148,8 +1148,8 @@ def mark_as_ham! def notify_of_hiding return unless hidden_by_admin? && saved_change_to_hidden_by_admin? - return if spam? - + return if spam? && saved_change_to_spam? + users.each do |user| UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit end diff --git a/features/admins/admin_spam.feature b/features/admins/admin_spam.feature index cca10b26247..868f3c6e816 100644 --- a/features/admins/admin_spam.feature +++ b/features/admins/admin_spam.feature @@ -42,8 +42,8 @@ Scenario: Review spam when spam works are not already hidden Then I should see "Works Marked as Spam" And I should see "Spammity" And I should see "Totally Legit" - When I check "spam_1" - And I check "ham_2" + When I check "spam_3" + And I check "ham_4" And I press "Update Works" Then I should not see "Spammity" And I should not see "Totally Legit" From 716ae7ea7872b06b6619540e823c5e5b78ba1c9f Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Thu, 21 Nov 2024 00:41:21 +0000 Subject: [PATCH 5/8] AO3-6810 Replace the 'spam?' rising edge detector with an internal virtual attribute --- app/models/work.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/work.rb b/app/models/work.rb index cd1ec0a7a7c..e87fe4332b1 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -75,6 +75,9 @@ def create_stat_counter attr_accessor :new_gifts attr_accessor :preview_mode + # Internal virtual attribute for whether if the hidden-for-spam email has been sent, so the normal work-hidden email should not be sent + attr_accessor :notified_of_hiding_for_spam + # return title.html_safe to overcome escaping done by sanitiser def title read_attribute(:title).try(:html_safe) @@ -1148,7 +1151,7 @@ def mark_as_ham! def notify_of_hiding return unless hidden_by_admin? && saved_change_to_hidden_by_admin? - return if spam? && saved_change_to_spam? + return if notified_of_hiding_for_spam users.each do |user| UserMailer.admin_hidden_work_notification(id, user.id).deliver_after_commit @@ -1159,6 +1162,7 @@ def notify_of_hiding_for_spam users.each do |user| UserMailer.admin_spam_work_notification(id, user.id).deliver_after_commit end + self.notified_of_hiding_for_spam = true end ############################################################################# From b34897ac50fd34b7dfd8782b8128bab07c85169c Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Tue, 26 Nov 2024 01:51:32 +0000 Subject: [PATCH 6/8] AO3-6810 Fix test --- features/other_a/hit_counts.feature | 2 +- features/step_definitions/work_steps.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/features/other_a/hit_counts.feature b/features/other_a/hit_counts.feature index 187f94380d4..be99a5e2f7b 100644 --- a/features/other_a/hit_counts.feature +++ b/features/other_a/hit_counts.feature @@ -41,7 +41,7 @@ Feature: Hit Counts Then I should see "Hits: 0" Scenario: Viewing a work hidden by an admin doesn't increment the hit count - Given the spam work "Hit Count Test" + Given the hidden work "Hit Count Test" And I am logged in as an admin And all hit count information is reset When I go to the work "Hit Count Test" diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb index 8b0ade36078..f519769ace6 100644 --- a/features/step_definitions/work_steps.rb +++ b/features/step_definitions/work_steps.rb @@ -266,6 +266,13 @@ w.update_attribute(:hidden_by_admin, true) if admin_settings.hide_spam? end +Given /^the hidden work "([^\"]*)"$/ do |work| + step %{I have a work "#{work}"} + step %{I log out} + w = Work.find_by_title(work) + w.update_attribute(:hidden_by_admin, true) +end + Given /^the work "([^\"]*)" is marked as spam$/ do |work| w = Work.find_by_title(work) w.update_attribute(:spam, true) From e97973f3954e7072fe4a7751b9c3ad4f8d34d50a Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Sun, 8 Dec 2024 15:53:25 +0000 Subject: [PATCH 7/8] AO3-6810 Revert test step changes --- features/step_definitions/work_steps.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb index f519769ace6..ea54b8c3540 100644 --- a/features/step_definitions/work_steps.rb +++ b/features/step_definitions/work_steps.rb @@ -261,9 +261,6 @@ step %{I log out} w = Work.find_by_title(work) w.update_attribute(:spam, true) - - admin_settings = AdminSetting.current - w.update_attribute(:hidden_by_admin, true) if admin_settings.hide_spam? end Given /^the hidden work "([^\"]*)"$/ do |work| From 012e0dd3194a7302caccb10c143d4edc62593beb Mon Sep 17 00:00:00 2001 From: EchoEkhi <echoekhi@gmail.com> Date: Fri, 20 Dec 2024 12:19:13 +0000 Subject: [PATCH 8/8] AO3-6810 Formatting --- app/models/moderated_work.rb | 4 +--- app/models/work.rb | 2 +- features/admins/admin_spam.feature | 2 +- features/step_definitions/work_steps.rb | 12 ++++++------ 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/models/moderated_work.rb b/app/models/moderated_work.rb index 56607530b0e..75760fd6365 100644 --- a/app/models/moderated_work.rb +++ b/app/models/moderated_work.rb @@ -41,9 +41,7 @@ def self.bulk_review(ids) where(id: ids).update_all(reviewed: true, approved: false) # Ensure works are hidden and spam if they weren't already Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| - unless work.hidden_by_admin? - work.notify_of_hiding_for_spam - end + work.notify_of_hiding_for_spam unless work.hidden_by_admin? work.update(hidden_by_admin: true, spam: true) end end diff --git a/app/models/work.rb b/app/models/work.rb index e87fe4332b1..aaf904c38af 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -75,7 +75,7 @@ def create_stat_counter attr_accessor :new_gifts attr_accessor :preview_mode - # Internal virtual attribute for whether if the hidden-for-spam email has been sent, so the normal work-hidden email should not be sent + # Virtual attribute for whether the hidden-for-spam email has been sent, so the normal work-hidden email should not be sent attr_accessor :notified_of_hiding_for_spam # return title.html_safe to overcome escaping done by sanitiser diff --git a/features/admins/admin_spam.feature b/features/admins/admin_spam.feature index 868f3c6e816..fb7ef69484a 100644 --- a/features/admins/admin_spam.feature +++ b/features/admins/admin_spam.feature @@ -25,7 +25,7 @@ Scenario: Review spam when spam works are already hidden And I should not see "Totally Legit" And the work "Spammity Spam" should be hidden And the work "Totally Legit" should not be hidden - And 0 email should be delivered + And 0 emails should be delivered Scenario: Review spam when spam works are not already hidden diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb index ea54b8c3540..ca77e376fdf 100644 --- a/features/step_definitions/work_steps.rb +++ b/features/step_definitions/work_steps.rb @@ -256,22 +256,22 @@ step %{I am logged in as "#{work.users.first.login}"} end -Given /^the spam work "([^\"]*)"$/ do |work| +Given "the spam work {string}" do |work| step %{I have a work "#{work}"} step %{I log out} - w = Work.find_by_title(work) + w = Work.find_by(title: work) w.update_attribute(:spam, true) end -Given /^the hidden work "([^\"]*)"$/ do |work| +Given "the hidden work {string}" do |work| step %{I have a work "#{work}"} step %{I log out} - w = Work.find_by_title(work) + w = Work.find_by(title: work) w.update_attribute(:hidden_by_admin, true) end -Given /^the work "([^\"]*)" is marked as spam$/ do |work| - w = Work.find_by_title(work) +Given "the work {string} is marked as spam" do |work| + w = Work.find_by(title: work) w.update_attribute(:spam, true) end