From 670e4655d13975e0597bd1c74ebeeeeffc4edc37 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 7 Aug 2024 17:14:37 +0200 Subject: [PATCH] Change dismissing a notification to clear existing filtered notifications for that account (#31329) --- .../v1/notifications/requests_controller.rb | 2 +- .../dismiss_notification_request_service.rb | 8 +++++++ .../filtered_notification_cleanup_worker.rb | 9 +++++++ ...smiss_notification_request_service_spec.rb | 19 +++++++++++++++ ...ltered_notification_cleanup_worker_spec.rb | 24 +++++++++++++++++++ 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 app/services/dismiss_notification_request_service.rb create mode 100644 app/workers/filtered_notification_cleanup_worker.rb create mode 100644 spec/services/dismiss_notification_request_service_spec.rb create mode 100644 spec/workers/filtered_notification_cleanup_worker_spec.rb diff --git a/app/controllers/api/v1/notifications/requests_controller.rb b/app/controllers/api/v1/notifications/requests_controller.rb index b4207147c..0710166d0 100644 --- a/app/controllers/api/v1/notifications/requests_controller.rb +++ b/app/controllers/api/v1/notifications/requests_controller.rb @@ -29,7 +29,7 @@ class Api::V1::Notifications::RequestsController < Api::BaseController end def dismiss - @request.destroy! + DismissNotificationRequestService.new.call(@request) render_empty end diff --git a/app/services/dismiss_notification_request_service.rb b/app/services/dismiss_notification_request_service.rb new file mode 100644 index 000000000..90b26d0bb --- /dev/null +++ b/app/services/dismiss_notification_request_service.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class DismissNotificationRequestService < BaseService + def call(request) + FilteredNotificationCleanupWorker.perform_async(request.account_id, request.from_account_id) + request.destroy! + end +end diff --git a/app/workers/filtered_notification_cleanup_worker.rb b/app/workers/filtered_notification_cleanup_worker.rb new file mode 100644 index 000000000..2b955da3c --- /dev/null +++ b/app/workers/filtered_notification_cleanup_worker.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class FilteredNotificationCleanupWorker + include Sidekiq::Worker + + def perform(account_id, from_account_id) + Notification.where(account_id: account_id, from_account_id: from_account_id, filtered: true).reorder(nil).in_batches(order: :desc).delete_all + end +end diff --git a/spec/services/dismiss_notification_request_service_spec.rb b/spec/services/dismiss_notification_request_service_spec.rb new file mode 100644 index 000000000..590725c87 --- /dev/null +++ b/spec/services/dismiss_notification_request_service_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe DismissNotificationRequestService do + describe '#call' do + let(:sender) { Fabricate(:account) } + let(:receiver) { Fabricate(:account) } + let(:request) { Fabricate(:notification_request, account: receiver, from_account: sender) } + + it 'destroys the request and queues a worker', :aggregate_failures do + expect { described_class.new.call(request) } + .to change(request, :destroyed?).to(true) + + expect(FilteredNotificationCleanupWorker) + .to have_enqueued_sidekiq_job(receiver.id, sender.id) + end + end +end diff --git a/spec/workers/filtered_notification_cleanup_worker_spec.rb b/spec/workers/filtered_notification_cleanup_worker_spec.rb new file mode 100644 index 000000000..2636b70ad --- /dev/null +++ b/spec/workers/filtered_notification_cleanup_worker_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe FilteredNotificationCleanupWorker do + describe '#perform' do + let(:sender) { Fabricate(:account) } + let(:recipient) { Fabricate(:account) } + let(:bystander) { Fabricate(:account) } + + before do + Fabricate(:notification, account: recipient, activity: Fabricate(:favourite, account: sender), filtered: true) + Fabricate(:notification, account: recipient, activity: Fabricate(:favourite, account: bystander), filtered: true) + Fabricate(:notification, account: recipient, activity: Fabricate(:follow, account: sender), filtered: true) + Fabricate(:notification, account: recipient, activity: Fabricate(:favourite, account: bystander), filtered: true) + end + + it 'deletes all filtered notifications to the account' do + expect { described_class.new.perform(recipient.id, sender.id) } + .to change { recipient.notifications.where(from_account: sender).count }.from(2).to(0) + .and(not_change { recipient.notifications.where(from_account: bystander).count }) + end + end +end