# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do
subject { described_class.new }
let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account', inbox_url: 'http://example.com/inbox') }
let(:alice) { Fabricate(:account, username: 'alice') }
let(:bob) { Fabricate(:account, username: 'bob') }
let(:eve) { Fabricate(:account, username: 'eve') }
let(:mallory) { Fabricate(:account, username: 'mallory') }
let(:collection_uri) { 'http://example.com/partial-followers' }
let(:items) do
[
ActivityPub::TagManager.instance.uri_for(alice),
ActivityPub::TagManager.instance.uri_for(eve),
ActivityPub::TagManager.instance.uri_for(mallory),
]
end
let(:payload) do
{
'@context': 'https://www.w3.org/ns/activitystreams',
type: 'Collection',
id: collection_uri,
items: items,
}.with_indifferent_access
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)
it 'keeps expected followers' do
expect(alice.following?(actor)).to be true
it 'removes local followers not in the remote list' do
expect(bob.following?(actor)).to be false
it 'converts follow requests to follow relationships when they have been accepted' do
expect(mallory.following?(actor)).to be true
it 'sends an Undo Follow to the actor' do
expect(ActivityPub::DeliveryWorker).to have_received(:perform_async).with(anything, eve.id, actor.inbox_url)
describe '#call' do
context 'when the endpoint is a Collection of actor URIs' do
stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload))
it_behaves_like 'synchronizes followers'
context 'when the endpoint is an OrderedCollection of actor URIs' do
type: 'OrderedCollection',
orderedItems: items,
context 'when the endpoint is a paginated Collection of actor URIs' do
first: {
type: 'CollectionPage',
partOf: collection_uri,
},