Merge commit '9c2d5b534f
' into upstream-20250314
This commit is contained in:
commit
6548462ecb
84 changed files with 1719 additions and 418 deletions
124
spec/services/activitypub/fetch_all_replies_service_spec.rb
Normal file
124
spec/services/activitypub/fetch_all_replies_service_spec.rb
Normal file
|
@ -0,0 +1,124 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::FetchAllRepliesService do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account') }
|
||||
let(:status) { Fabricate(:status, account: actor) }
|
||||
let(:collection_uri) { 'http://example.com/replies/1' }
|
||||
|
||||
let(:items) do
|
||||
%w(
|
||||
http://example.com/self-reply-1
|
||||
http://example.com/self-reply-2
|
||||
http://example.com/self-reply-3
|
||||
http://other.com/other-reply-1
|
||||
http://other.com/other-reply-2
|
||||
http://other.com/other-reply-3
|
||||
http://example.com/self-reply-4
|
||||
http://example.com/self-reply-5
|
||||
http://example.com/self-reply-6
|
||||
)
|
||||
end
|
||||
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
type: 'Collection',
|
||||
id: collection_uri,
|
||||
items: items,
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
it 'fetches more than the default maximum and from multiple domains' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(:push_bulk).with(
|
||||
%w(
|
||||
http://example.com/self-reply-1
|
||||
http://example.com/self-reply-2
|
||||
http://example.com/self-reply-3
|
||||
http://other.com/other-reply-1
|
||||
http://other.com/other-reply-2
|
||||
http://other.com/other-reply-3
|
||||
http://example.com/self-reply-4
|
||||
http://example.com/self-reply-5
|
||||
http://example.com/self-reply-6
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'with a recent status' do
|
||||
before do
|
||||
Fabricate(:status, uri: 'http://example.com/self-reply-2', fetched_replies_at: 1.second.ago, local: false)
|
||||
end
|
||||
|
||||
it 'skips statuses that have been updated recently' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(:push_bulk).with(
|
||||
%w(
|
||||
http://example.com/self-reply-1
|
||||
http://example.com/self-reply-3
|
||||
http://other.com/other-reply-1
|
||||
http://other.com/other-reply-2
|
||||
http://other.com/other-reply-3
|
||||
http://example.com/self-reply-4
|
||||
http://example.com/self-reply-5
|
||||
http://example.com/self-reply-6
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an old status' do
|
||||
before do
|
||||
Fabricate(:status, uri: 'http://other.com/other-reply-1', fetched_replies_at: 1.year.ago, created_at: 1.year.ago, account: actor)
|
||||
end
|
||||
|
||||
it 'updates the time that fetched statuses were last fetched' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status.uri, payload)
|
||||
|
||||
expect(Status.find_by(uri: 'http://other.com/other-reply-1').fetched_replies_at).to be >= 1.minute.ago
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unsubscribed replies' do
|
||||
before do
|
||||
remote_actor = Fabricate(:account, domain: 'other.com', uri: 'http://other.com/account')
|
||||
# reply not in the collection from the remote instance, but we know about anyway without anyone following the account
|
||||
Fabricate(:status, account: remote_actor, in_reply_to_id: status.id, uri: 'http://other.com/account/unsubscribed', fetched_replies_at: 1.year.ago, created_at: 1.year.ago)
|
||||
end
|
||||
|
||||
it 'updates the unsubscribed replies' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(:push_bulk).with(
|
||||
%w(
|
||||
http://example.com/self-reply-1
|
||||
http://example.com/self-reply-2
|
||||
http://example.com/self-reply-3
|
||||
http://other.com/other-reply-1
|
||||
http://other.com/other-reply-2
|
||||
http://other.com/other-reply-3
|
||||
http://example.com/self-reply-4
|
||||
http://example.com/self-reply-5
|
||||
http://example.com/self-reply-6
|
||||
http://other.com/account/unsubscribed
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,6 +9,9 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
|
||||
let!(:sender) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar') }
|
||||
|
||||
let(:follower) { Fabricate(:account, username: 'alice') }
|
||||
let(:follow) { nil }
|
||||
let(:response) { { body: Oj.dump(object), headers: { 'content-type': 'application/activity+json' } } }
|
||||
let(:existing_status) { nil }
|
||||
|
||||
let(:note) do
|
||||
|
@ -23,13 +26,14 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
|
||||
before do
|
||||
stub_request(:get, 'https://foo.bar/watch?v=12345').to_return(status: 404, body: '')
|
||||
stub_request(:get, object[:id]).to_return(body: Oj.dump(object))
|
||||
stub_request(:get, object[:id]).to_return(**response)
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
before do
|
||||
follow
|
||||
existing_status
|
||||
subject.call(object[:id], prefetched_body: Oj.dump(object))
|
||||
subject.call(object[:id])
|
||||
end
|
||||
|
||||
context 'with Note object' do
|
||||
|
@ -254,6 +258,45 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
expect(existing_status.text).to eq 'Lorem ipsum'
|
||||
expect(existing_status.edits).to_not be_empty
|
||||
end
|
||||
|
||||
context 'when the status appears to have been deleted at source' do
|
||||
let(:response) { { status: 404, body: '' } }
|
||||
|
||||
shared_examples 'no delete' do
|
||||
it 'does not delete the status' do
|
||||
existing_status.reload
|
||||
expect(existing_status.text).to eq 'Foo'
|
||||
expect(existing_status.edits).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the status is orphaned/unsubscribed' do
|
||||
it 'deletes the orphaned status' do
|
||||
expect { existing_status.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the status is from an account with only remote followers' do
|
||||
let(:follower) { Fabricate(:account, username: 'alice', domain: 'foo.bar') }
|
||||
let(:follow) { Fabricate(:follow, account: follower, target_account: sender, created_at: 2.days.ago) }
|
||||
|
||||
it 'deletes the orphaned status' do
|
||||
expect { existing_status.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
context 'when the status is private' do
|
||||
let(:existing_status) { Fabricate(:status, account: sender, text: 'Foo', uri: note[:id], visibility: :private) }
|
||||
|
||||
it_behaves_like 'no delete'
|
||||
end
|
||||
|
||||
context 'when the status is direct' do
|
||||
let(:existing_status) { Fabricate(:status, account: sender, text: 'Foo', uri: note[:id], visibility: :direct) }
|
||||
|
||||
it_behaves_like 'no delete'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a Create activity' do
|
||||
|
|
|
@ -40,7 +40,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'queues the expected worker' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, payload)
|
||||
subject.call(status.account.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1'])
|
||||
end
|
||||
|
@ -50,7 +50,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, payload)
|
||||
subject.call(status.account.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
@ -64,7 +64,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, collection_uri)
|
||||
subject.call(status.account.uri, collection_uri)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
@ -85,7 +85,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, payload)
|
||||
subject.call(status.account.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
@ -99,7 +99,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, collection_uri)
|
||||
subject.call(status.account.uri, collection_uri)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
@ -124,7 +124,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, payload)
|
||||
subject.call(status.account.uri, payload)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ RSpec.describe ActivityPub::FetchRepliesService do
|
|||
it 'spawns workers for up to 5 replies on the same server' do
|
||||
allow(FetchReplyWorker).to receive(:push_bulk)
|
||||
|
||||
subject.call(status, collection_uri)
|
||||
subject.call(status.account.uri, collection_uri)
|
||||
|
||||
expect(FetchReplyWorker).to have_received(: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'])
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue