Fix follower synchronization mechanism erroneously removing followers from multi-page collections (#34272)
This commit is contained in:
parent
81b88095b4
commit
3edac14f02
2 changed files with 36 additions and 8 deletions
app/services/activitypub
spec/services/activitypub
|
@ -57,6 +57,9 @@ class ActivityPub::SynchronizeFollowersService < BaseService
|
|||
collection = fetch_collection(collection['first']) if collection['first'].present?
|
||||
return unless collection.is_a?(Hash)
|
||||
|
||||
# Abort if we'd have to paginate through more than one page of followers
|
||||
return if collection['next'].present?
|
||||
|
||||
case collection['type']
|
||||
when 'Collection', 'CollectionPage'
|
||||
as_array(collection['items'])
|
||||
|
|
|
@ -27,14 +27,14 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
before do
|
||||
alice.follow!(actor)
|
||||
bob.follow!(actor)
|
||||
mallory.request_follow!(actor)
|
||||
end
|
||||
|
||||
shared_examples 'synchronizes followers' do
|
||||
before do
|
||||
alice.follow!(actor)
|
||||
bob.follow!(actor)
|
||||
mallory.request_follow!(actor)
|
||||
|
||||
allow(ActivityPub::DeliveryWorker).to receive(:perform_async)
|
||||
|
||||
subject.call(actor, collection_uri)
|
||||
end
|
||||
|
||||
|
@ -46,7 +46,7 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
expect(mallory)
|
||||
.to be_following(actor) # Convert follow request to follow when accepted
|
||||
expect(ActivityPub::DeliveryWorker)
|
||||
.to have_received(:perform_async).with(anything, eve.id, actor.inbox_url) # Send Undo Follow to actor
|
||||
.to have_enqueued_sidekiq_job(anything, eve.id, actor.inbox_url) # Send Undo Follow to actor
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -76,7 +76,7 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
it_behaves_like 'synchronizes followers'
|
||||
end
|
||||
|
||||
context 'when the endpoint is a paginated Collection of actor URIs' do
|
||||
context 'when the endpoint is a single-page paginated Collection of actor URIs' do
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
|
@ -96,5 +96,30 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
|
||||
it_behaves_like 'synchronizes followers'
|
||||
end
|
||||
|
||||
context 'when the endpoint is a paginated Collection of actor URIs with a next page' do
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
type: 'Collection',
|
||||
id: collection_uri,
|
||||
first: {
|
||||
type: 'CollectionPage',
|
||||
partOf: collection_uri,
|
||||
items: items,
|
||||
next: "#{collection_uri}/page2",
|
||||
},
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload), headers: { 'Content-Type': 'application/activity+json' })
|
||||
end
|
||||
|
||||
it 'does not change followers' do
|
||||
expect { subject.call(actor, collection_uri) }
|
||||
.to_not(change { actor.followers.reload.reorder(id: :asc).pluck(:id) })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue