From 9c24f2d6b17104cac229a126e35fdfda7a557d79 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Tue, 26 Mar 2024 15:46:38 +0100
Subject: [PATCH] Undo notification permissions on individual and domain blocks
 (#29570)

---
 .../after_block_domain_from_account_service.rb    |  5 +++++
 app/services/block_service.rb                     |  2 ++
 ...fter_block_domain_from_account_service_spec.rb | 15 ++++++---------
 spec/services/block_service_spec.rb               |  8 +++++---
 4 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb
index adb17845c..fc5dc6568 100644
--- a/app/services/after_block_domain_from_account_service.rb
+++ b/app/services/after_block_domain_from_account_service.rb
@@ -12,6 +12,7 @@ class AfterBlockDomainFromAccountService < BaseService
     @domain_block_event = nil
 
     clear_notifications!
+    clear_notification_permissions!
     remove_follows!
     reject_existing_followers!
     reject_pending_follow_requests!
@@ -31,6 +32,10 @@ class AfterBlockDomainFromAccountService < BaseService
     Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all
   end
 
+  def clear_notification_permissions!
+    NotificationPermission.where(account: @account, from_account: Account.where(domain: @domain)).in_batches.delete_all
+  end
+
   def reject_existing_followers!
     @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).in_batches do |follows|
       domain_block_event.import_from_passive_follows!(follows)
diff --git a/app/services/block_service.rb b/app/services/block_service.rb
index 266a0f4b9..98229d98c 100644
--- a/app/services/block_service.rb
+++ b/app/services/block_service.rb
@@ -10,6 +10,8 @@ class BlockService < BaseService
     UnfollowService.new.call(target_account, account) if target_account.following?(account)
     RejectFollowService.new.call(target_account, account) if target_account.requested?(account)
 
+    NotificationPermission.where(account: account, from_account: target_account).destroy_all
+
     block = account.block!(target_account)
 
     BlockWorker.perform_async(account.id, target_account.id)
diff --git a/spec/services/after_block_domain_from_account_service_spec.rb b/spec/services/after_block_domain_from_account_service_spec.rb
index 12e780357..248648a80 100644
--- a/spec/services/after_block_domain_from_account_service_spec.rb
+++ b/spec/services/after_block_domain_from_account_service_spec.rb
@@ -10,20 +10,17 @@ RSpec.describe AfterBlockDomainFromAccountService do
   let(:alice) { Fabricate(:account, username: 'alice') }
 
   before do
+    NotificationPermission.create!(account: alice, from_account: wolf)
+
     wolf.follow!(alice)
     alice.follow!(dog)
   end
 
-  around do |example|
-    Sidekiq::Testing.fake! do
-      example.run
-    end
-  end
+  it 'purge followers from blocked domain, remove notification permissions, sends `Reject->Follow`, and records severed relationships', :aggregate_failures do
+    expect { subject.call(alice, 'evil.org') }
+      .to change { wolf.following?(alice) }.from(true).to(false)
+      .and change { NotificationPermission.exists?(account: alice, from_account: wolf) }.from(true).to(false)
 
-  it 'purges followers from blocked domain, sends them Reject->Follow, and records severed relationships', :aggregate_failures do
-    subject.call(alice, 'evil.org')
-
-    expect(wolf.following?(alice)).to be false
     expect(ActivityPub::DeliveryWorker.jobs.pluck('args')).to contain_exactly(
       [a_string_including('"type":"Reject"'), alice.id, wolf.inbox_url],
       [a_string_including('"type":"Undo"'), alice.id, dog.inbox_url]
diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb
index e72e52825..d096aa1ea 100644
--- a/spec/services/block_service_spec.rb
+++ b/spec/services/block_service_spec.rb
@@ -11,11 +11,13 @@ RSpec.describe BlockService do
     let(:bob) { Fabricate(:account, username: 'bob') }
 
     before do
-      subject.call(sender, bob)
+      NotificationPermission.create!(account: sender, from_account: bob)
     end
 
-    it 'creates a blocking relation' do
-      expect(sender.blocking?(bob)).to be true
+    it 'creates a blocking relation and removes notification permissions' do
+      expect { subject.call(sender, bob) }
+        .to change { sender.blocking?(bob) }.from(false).to(true)
+        .and change { NotificationPermission.exists?(account: sender, from_account: bob) }.from(true).to(false)
     end
   end