synchronize_followers_service_spec.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. require 'rails_helper'
  2. RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do
  3. let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account', inbox_url: 'http://example.com/inbox') }
  4. let(:alice) { Fabricate(:account, username: 'alice') }
  5. let(:bob) { Fabricate(:account, username: 'bob') }
  6. let(:eve) { Fabricate(:account, username: 'eve') }
  7. let(:mallory) { Fabricate(:account, username: 'mallory') }
  8. let(:collection_uri) { 'http://example.com/partial-followers' }
  9. let(:items) do
  10. [
  11. ActivityPub::TagManager.instance.uri_for(alice),
  12. ActivityPub::TagManager.instance.uri_for(eve),
  13. ActivityPub::TagManager.instance.uri_for(mallory),
  14. ]
  15. end
  16. let(:payload) do
  17. {
  18. '@context': 'https://www.w3.org/ns/activitystreams',
  19. type: 'Collection',
  20. id: collection_uri,
  21. items: items,
  22. }.with_indifferent_access
  23. end
  24. subject { described_class.new }
  25. shared_examples 'synchronizes followers' do
  26. before do
  27. alice.follow!(actor)
  28. bob.follow!(actor)
  29. mallory.request_follow!(actor)
  30. allow(ActivityPub::DeliveryWorker).to receive(:perform_async)
  31. subject.call(actor, collection_uri)
  32. end
  33. it 'keeps expected followers' do
  34. expect(alice.following?(actor)).to be true
  35. end
  36. it 'removes local followers not in the remote list' do
  37. expect(bob.following?(actor)).to be false
  38. end
  39. it 'converts follow requests to follow relationships when they have been accepted' do
  40. expect(mallory.following?(actor)).to be true
  41. end
  42. it 'sends an Undo Follow to the actor' do
  43. expect(ActivityPub::DeliveryWorker).to have_received(:perform_async).with(anything, eve.id, actor.inbox_url)
  44. end
  45. end
  46. describe '#call' do
  47. context 'when the endpoint is a Collection of actor URIs' do
  48. before do
  49. stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload), headers: { 'Content-Type': 'application/activity+json' })
  50. end
  51. it_behaves_like 'synchronizes followers'
  52. end
  53. context 'when the endpoint is an OrderedCollection of actor URIs' do
  54. let(:payload) do
  55. {
  56. '@context': 'https://www.w3.org/ns/activitystreams',
  57. type: 'OrderedCollection',
  58. id: collection_uri,
  59. orderedItems: items,
  60. }.with_indifferent_access
  61. end
  62. before do
  63. stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload), headers: { 'Content-Type': 'application/activity+json' })
  64. end
  65. it_behaves_like 'synchronizes followers'
  66. end
  67. context 'when the endpoint is a paginated Collection of actor URIs' do
  68. let(:payload) do
  69. {
  70. '@context': 'https://www.w3.org/ns/activitystreams',
  71. type: 'Collection',
  72. id: collection_uri,
  73. first: {
  74. type: 'CollectionPage',
  75. partOf: collection_uri,
  76. items: items,
  77. }
  78. }.with_indifferent_access
  79. end
  80. before do
  81. stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload), headers: { 'Content-Type': 'application/activity+json' })
  82. end
  83. it_behaves_like 'synchronizes followers'
  84. end
  85. end
  86. end