diff --git a/app/services/revoke_quote_service.rb b/app/services/revoke_quote_service.rb index 1dd37d055..346fba897 100644 --- a/app/services/revoke_quote_service.rb +++ b/app/services/revoke_quote_service.rb @@ -21,6 +21,11 @@ class RevokeQuoteService < BaseService end def distribute_stamp_deletion! + # It is possible the quoted status has been soft-deleted. + # In this case, `signed_activity_json` would fail, but we can just ignore + # that, as we have already federated deletion. + return if @quote.quoted_status.nil? + ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url| [signed_activity_json, @account.id, inbox_url] end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index f2b46f05b..3cb2eceec 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -129,4 +129,20 @@ RSpec.describe RemoveStatusService, :inline_jobs do ) ) end + + context 'when removed status is a quote of a local user', inline_jobs: false do + let(:original_status) { Fabricate(:status, account: alice) } + let(:status) { Fabricate(:status, account: jeff) } + + before do + bill.follow!(jeff) + Fabricate(:quote, status: status, quoted_status: original_status, state: :accepted) + original_status.discard + end + + it 'sends deletion without crashing' do + expect { subject.call(status.reload) } + .to enqueue_sidekiq_job(ActivityPub::DeliveryWorker).with(/Delete/, jeff.id, bill.inbox_url) + end + end end