Fix processing of compacted single-item JSON-LD collections (#28816)
This commit is contained in:
parent
de60322711
commit
460e4fbdd6
6 changed files with 49 additions and 7 deletions
|
@ -23,9 +23,9 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService
|
||||||
|
|
||||||
case collection['type']
|
case collection['type']
|
||||||
when 'Collection', 'CollectionPage'
|
when 'Collection', 'CollectionPage'
|
||||||
collection['items']
|
as_array(collection['items'])
|
||||||
when 'OrderedCollection', 'OrderedCollectionPage'
|
when 'OrderedCollection', 'OrderedCollectionPage'
|
||||||
collection['orderedItems']
|
as_array(collection['orderedItems'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ class ActivityPub::FetchRepliesService < BaseService
|
||||||
|
|
||||||
case collection['type']
|
case collection['type']
|
||||||
when 'Collection', 'CollectionPage'
|
when 'Collection', 'CollectionPage'
|
||||||
collection['items']
|
as_array(collection['items'])
|
||||||
when 'OrderedCollection', 'OrderedCollectionPage'
|
when 'OrderedCollection', 'OrderedCollectionPage'
|
||||||
collection['orderedItems']
|
as_array(collection['orderedItems'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,9 @@ class ActivityPub::SynchronizeFollowersService < BaseService
|
||||||
|
|
||||||
case collection['type']
|
case collection['type']
|
||||||
when 'Collection', 'CollectionPage'
|
when 'Collection', 'CollectionPage'
|
||||||
collection['items']
|
as_array(collection['items'])
|
||||||
when 'OrderedCollection', 'OrderedCollectionPage'
|
when 'OrderedCollection', 'OrderedCollectionPage'
|
||||||
collection['orderedItems']
|
as_array(collection['orderedItems'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Keys::QueryService < BaseService
|
||||||
|
|
||||||
return if json['items'].blank?
|
return if json['items'].blank?
|
||||||
|
|
||||||
@devices = json['items'].map do |device|
|
@devices = as_array(json['items']).map do |device|
|
||||||
Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim'])
|
Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim'])
|
||||||
end
|
end
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
|
rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
|
||||||
|
|
|
@ -97,6 +97,21 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'sets pinned posts'
|
it_behaves_like 'sets pinned posts'
|
||||||
|
|
||||||
|
context 'when there is a single item, with the array compacted away' do
|
||||||
|
let(:items) { 'https://example.com/account/pinned/4' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:get, 'https://example.com/account/pinned/4').to_return(status: 200, body: Oj.dump(status_json_4))
|
||||||
|
subject.call(actor, note: true, hashtag: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets expected posts as pinned posts' do
|
||||||
|
expect(actor.pinned_statuses.pluck(:uri)).to contain_exactly(
|
||||||
|
'https://example.com/account/pinned/4'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the endpoint is a paginated Collection' do
|
context 'when the endpoint is a paginated Collection' do
|
||||||
|
@ -118,6 +133,21 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'sets pinned posts'
|
it_behaves_like 'sets pinned posts'
|
||||||
|
|
||||||
|
context 'when there is a single item, with the array compacted away' do
|
||||||
|
let(:items) { 'https://example.com/account/pinned/4' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:get, 'https://example.com/account/pinned/4').to_return(status: 200, body: Oj.dump(status_json_4))
|
||||||
|
subject.call(actor, note: true, hashtag: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets expected posts as pinned posts' do
|
||||||
|
expect(actor.pinned_statuses.pluck(:uri)).to contain_exactly(
|
||||||
|
'https://example.com/account/pinned/4'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,18 @@ RSpec.describe ActivityPub::FetchRepliesService, type: :service do
|
||||||
|
|
||||||
describe '#call' do
|
describe '#call' do
|
||||||
context 'when the payload is a Collection with inlined replies' do
|
context 'when the payload is a Collection with inlined replies' do
|
||||||
|
context 'when there is a single reply, with the array compacted away' do
|
||||||
|
let(:items) { 'http://example.com/self-reply-1' }
|
||||||
|
|
||||||
|
it 'queues the expected worker' do
|
||||||
|
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||||
|
|
||||||
|
subject.call(status, payload)
|
||||||
|
|
||||||
|
expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when passing the collection itself' do
|
context 'when passing the collection itself' do
|
||||||
it 'spawns workers for up to 5 replies on the same server' do
|
it 'spawns workers for up to 5 replies on the same server' do
|
||||||
expect(FetchReplyWorker).to receive(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
|
expect(FetchReplyWorker).to receive(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
|
||||||
|
|
Loading…
Reference in a new issue