From 6c5bd4f9a8926bcf93afc31f128c8d3378205762 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Tue, 28 Apr 2026 16:49:19 +0200 Subject: [PATCH] Handle collections when blocking a user (#38827) --- app/services/block_service.rb | 26 +++++++++++++++++++++++--- spec/services/block_service_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/app/services/block_service.rb b/app/services/block_service.rb index cbd0e8e75b..2efeceed0c 100644 --- a/app/services/block_service.rb +++ b/app/services/block_service.rb @@ -6,9 +6,11 @@ class BlockService < BaseService def call(account, target_account) return if account.id == target_account.id - UnfollowService.new.call(account, target_account) if account.following?(target_account) - UnfollowService.new.call(target_account, account) if target_account.following?(account) - RejectFollowService.new.call(target_account, account) if target_account.requested?(account) + @account = account + @target_account = target_account + + handle_following_relationships + handle_collections NotificationPermission.where(account: account, from_account: target_account).destroy_all @@ -21,6 +23,24 @@ class BlockService < BaseService private + def handle_following_relationships + UnfollowService.new.call(@account, @target_account) if @account.following?(@target_account) + UnfollowService.new.call(@target_account, @account) if @target_account.following?(@account) + RejectFollowService.new.call(@target_account, @account) if @target_account.requested?(@account) + end + + def handle_collections + # Remove account from target_account's collections + @target_account.curated_collection_items.where(account: @account).find_each do |collection_item| + RevokeCollectionItemService.new.call(collection_item) + end + + # Remove target_account from account's collections + @account.curated_collection_items.where(account: @target_account).find_each do |collection_item| + DeleteCollectionItemService.new.call(collection_item) + end + end + def create_notification(block) ActivityPub::DeliveryWorker.perform_async(build_json(block), block.account_id, block.target_account.inbox_url) end diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index d9687a5404..f708c3bd39 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -19,6 +19,28 @@ RSpec.describe BlockService do .to change { sender.blocking?(bob) }.from(false).to(true) .and change { NotificationPermission.exists?(account: sender, from_account: bob) }.from(true).to(false) end + + context 'when the block affects collections' do + context 'when the sender features the target in a collection' do + let(:collection) { Fabricate(:collection, account: sender) } + let!(:collection_item) { Fabricate(:collection_item, collection:, account: bob) } + + it 'removes the affected item from the collection' do + expect { subject.call(sender, bob) }.to change(CollectionItem, :count).by(-1) + expect { collection_item.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + context 'when the sender is featured by the target in a collection' do + let(:collection) { Fabricate(:collection, account: bob) } + let!(:collection_item) { Fabricate(:collection_item, collection:, account: sender) } + + it 'revokes the inclusion in the collection' do + subject.call(sender, bob) + expect(collection_item.reload).to be_revoked + end + end + end end describe 'remote ActivityPub' do