From 71d02ffcf3a79dfc1c413dcc7ff45c77ce9cb94c Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 2 May 2022 17:41:01 +0200 Subject: Fix compatibility with Friendica regarding pinned posts (#18254) * Fix multiple database queries when fetching pinned posts for remote account * Fix compatibility with Friendica regarding pinned posts Fixes #18066 * Add tests --- .../fetch_featured_collection_service_spec.rb | 123 +++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 spec/services/activitypub/fetch_featured_collection_service_spec.rb (limited to 'spec/services/activitypub/fetch_featured_collection_service_spec.rb') diff --git a/spec/services/activitypub/fetch_featured_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_collection_service_spec.rb new file mode 100644 index 000000000..f552b9dc0 --- /dev/null +++ b/spec/services/activitypub/fetch_featured_collection_service_spec.rb @@ -0,0 +1,123 @@ +require 'rails_helper' + +RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do + let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/account', featured_collection_url: 'https://example.com/account/pinned') } + + let!(:known_status) { Fabricate(:status, account: actor, uri: 'https://example.com/account/pinned/1') } + + let(:status_json_1) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Note', + id: 'https://example.com/account/pinned/1', + content: 'foo', + attributedTo: actor.uri, + to: 'https://www.w3.org/ns/activitystreams#Public', + } + end + + let(:status_json_2) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Note', + id: 'https://example.com/account/pinned/2', + content: 'foo', + attributedTo: actor.uri, + to: 'https://www.w3.org/ns/activitystreams#Public', + } + end + + let(:status_json_4) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Note', + id: 'https://example.com/account/pinned/4', + content: 'foo', + attributedTo: actor.uri, + to: 'https://www.w3.org/ns/activitystreams#Public', + } + end + + let(:items) do + [ + 'https://example.com/account/pinned/1', # known + status_json_2, # unknown inlined + 'https://example.com/account/pinned/3', # unknown unreachable + 'https://example.com/account/pinned/4', # unknown reachable + ] + end + + let(:payload) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Collection', + id: actor.featured_collection_url, + items: items, + }.with_indifferent_access + end + + subject { described_class.new } + + shared_examples 'sets pinned posts' do + before do + stub_request(:get, 'https://example.com/account/pinned/1').to_return(status: 200, body: Oj.dump(status_json_1)) + stub_request(:get, 'https://example.com/account/pinned/2').to_return(status: 200, body: Oj.dump(status_json_2)) + stub_request(:get, 'https://example.com/account/pinned/3').to_return(status: 404) + stub_request(:get, 'https://example.com/account/pinned/4').to_return(status: 200, body: Oj.dump(status_json_4)) + + subject.call(actor) + end + + it 'sets expected posts as pinned posts' do + expect(actor.pinned_statuses.pluck(:uri)).to match_array ['https://example.com/account/pinned/1', 'https://example.com/account/pinned/2', 'https://example.com/account/pinned/4'] + end + end + + describe '#call' do + context 'when the endpoint is a Collection' do + before do + stub_request(:get, actor.featured_collection_url).to_return(status: 200, body: Oj.dump(payload)) + end + + it_behaves_like 'sets pinned posts' + end + + context 'when the endpoint is an OrderedCollection' do + let(:payload) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'OrderedCollection', + id: actor.featured_collection_url, + orderedItems: items, + }.with_indifferent_access + end + + before do + stub_request(:get, actor.featured_collection_url).to_return(status: 200, body: Oj.dump(payload)) + end + + it_behaves_like 'sets pinned posts' + end + + context 'when the endpoint is a paginated Collection' do + let(:payload) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Collection', + id: actor.featured_collection_url, + first: { + type: 'CollectionPage', + partOf: actor.featured_collection_url, + items: items, + } + }.with_indifferent_access + end + + before do + stub_request(:get, actor.featured_collection_url).to_return(status: 200, body: Oj.dump(payload)) + end + + it_behaves_like 'sets pinned posts' + end + end +end -- cgit