2
0

Fix crash when serializing quotes of deleted posts for ActivityPub (#36381)

This commit is contained in:
Claire
2025-10-09 15:52:38 +02:00
committed by GitHub
parent b7c5e60426
commit d4a4a7177a
8 changed files with 97 additions and 8 deletions

View File

@@ -938,6 +938,30 @@ RSpec.describe ActivityPub::Activity::Create do
end
end
context 'with an unverifiable quote of a dead post' do
let(:quoted_status) { Fabricate(:status) }
let(:object_json) do
build_object(
type: 'Note',
content: 'woah what she said is amazing',
quote: { type: 'Tombstone' }
)
end
it 'creates a status with an unverified quote' do
expect { subject.perform }.to change(sender.statuses, :count).by(1)
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.quote).to_not be_nil
expect(status.quote).to have_attributes(
state: 'deleted',
approval_uri: nil
)
end
end
context 'with an unverifiable unknown post' do
let(:unknown_post_uri) { 'https://unavailable.example.com/unavailable-post' }

View File

@@ -58,6 +58,21 @@ RSpec.describe ActivityPub::NoteSerializer do
end
end
context 'with a deleted quote' do
let(:quoted_status) { Fabricate(:status) }
before do
Fabricate(:quote, status: parent, quoted_status: nil, state: :accepted)
end
it 'has the expected shape' do
expect(subject).to include({
'type' => 'Note',
'quote' => { 'type' => 'Tombstone' },
})
end
end
context 'with a quote policy' do
let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }

View File

@@ -1053,6 +1053,44 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
end
end
context 'when the status swaps a verified quote with an ID-less Tombstone through an explicit update' do
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
let(:quoted_status) { Fabricate(:status, account: quoted_account) }
let(:second_quoted_status) { Fabricate(:status, account: quoted_account) }
let!(:quote) { Fabricate(:quote, status: status, quoted_status: quoted_status, approval_uri: approval_uri, state: :accepted) }
let(:approval_uri) { 'https://quoted.example.com/approvals/1' }
let(:payload) do
{
'@context': [
'https://www.w3.org/ns/activitystreams',
{
'@id': 'https://w3id.org/fep/044f#quote',
'@type': '@id',
},
{
'@id': 'https://w3id.org/fep/044f#quoteAuthorization',
'@type': '@id',
},
],
id: 'foo',
type: 'Note',
summary: 'Show more',
content: 'Hello universe',
updated: '2021-09-08T22:39:25Z',
quote: { type: 'Tombstone' },
}
end
it 'updates the URI and unverifies the quote' do
expect { subject.call(status, json, json) }
.to change { status.quote.quoted_status }.from(quoted_status).to(nil)
.and change { status.quote.state }.from('accepted').to('deleted')
expect { quote.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
context 'when the status swaps a verified quote with another verifiable quote through an explicit update' do
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
let(:second_quoted_account) { Fabricate(:account, domain: 'second-quoted.example.com') }