Merge commit '9e04007020
' into upstream-20240725
This commit is contained in:
commit
a99f174d98
322 changed files with 8093 additions and 1586 deletions
|
@ -33,7 +33,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
end
|
||||
|
||||
context 'when the account does not have a inbox' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
actor[:inbox] = nil
|
||||
|
@ -52,7 +52,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
end
|
||||
|
||||
context 'when URI and WebFinger share the same host' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -74,7 +74,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -98,7 +98,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -115,7 +115,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI after a redirection' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -33,7 +33,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
end
|
||||
|
||||
context 'when the account does not have a inbox' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
actor[:inbox] = nil
|
||||
|
@ -52,7 +52,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
end
|
||||
|
||||
context 'when URI and WebFinger share the same host' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -74,7 +74,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -98,7 +98,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -115,7 +115,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI after a redirection' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
RSpec.describe ActivityPub::FetchRemoteKeyService do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
let(:public_key_pem) do
|
||||
<<~TEXT
|
||||
|
|
|
@ -227,7 +227,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
|
||||
context 'with statuses referencing other statuses', :inline_jobs do
|
||||
before do
|
||||
stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5
|
||||
stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 3
|
||||
end
|
||||
|
||||
context 'when using inReplyTo' do
|
||||
|
@ -243,7 +243,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
end
|
||||
|
||||
before do
|
||||
8.times do |i|
|
||||
5.times do |i|
|
||||
status_json = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: "https://foo.bar/@foo/#{i}",
|
||||
|
@ -257,12 +257,10 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
end
|
||||
end
|
||||
|
||||
it 'creates at least some statuses' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2)
|
||||
end
|
||||
|
||||
it 'creates no more account than the limit allows' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5)
|
||||
it 'creates statuses but not more than limit allows' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }
|
||||
.to change { sender.statuses.count }.by_at_least(2)
|
||||
.and change { sender.statuses.count }.by_at_most(3)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -287,7 +285,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
end
|
||||
|
||||
before do
|
||||
8.times do |i|
|
||||
5.times do |i|
|
||||
status_json = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: "https://foo.bar/@foo/#{i}",
|
||||
|
@ -309,12 +307,10 @@ RSpec.describe ActivityPub::FetchRemoteStatusService do
|
|||
end
|
||||
end
|
||||
|
||||
it 'creates at least some statuses' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2)
|
||||
end
|
||||
|
||||
it 'creates no more account than the limit allows' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5)
|
||||
it 'creates statuses but not more than limit allows' do
|
||||
expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }
|
||||
.to change { sender.statuses.count }.by_at_least(2)
|
||||
.and change { sender.statuses.count }.by_at_most(3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -601,7 +601,7 @@ RSpec.describe ActivityPub::ProcessAccountService do
|
|||
}.with_indifferent_access
|
||||
webfinger = {
|
||||
subject: "acct:user#{i}@foo.test",
|
||||
links: [{ rel: 'self', href: "https://foo.test/users/#{i}" }],
|
||||
links: [{ rel: 'self', href: "https://foo.test/users/#{i}", type: 'application/activity+json' }],
|
||||
}.with_indifferent_access
|
||||
stub_request(:get, "https://foo.test/users/#{i}").to_return(status: 200, body: actor_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
|
||||
stub_request(:get, "https://foo.test/users/#{i}/featured").to_return(status: 200, body: featured_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -46,14 +46,13 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
end
|
||||
|
||||
describe '#call' do
|
||||
it 'updates text' do
|
||||
it 'updates text and content warning' do
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.text).to eq 'Hello universe'
|
||||
end
|
||||
|
||||
it 'updates content warning' do
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.spoiler_text).to eq 'Show more'
|
||||
expect(status.reload)
|
||||
.to have_attributes(
|
||||
text: eq('Hello universe'),
|
||||
spoiler_text: eq('Show more')
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the changes are only in sanitized-out HTML' do
|
||||
|
@ -73,12 +72,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits and does not mark status edited' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.edited?).to be false
|
||||
expect(status).to_not be_edited
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,15 +92,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits, mark status edited, or update text' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.reload.edited?).to be false
|
||||
end
|
||||
|
||||
it 'does not update the text' do
|
||||
expect(status.reload).to_not be_edited
|
||||
expect(status.reload.text).to eq 'Hello world'
|
||||
end
|
||||
end
|
||||
|
@ -143,19 +133,10 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits, mark status edited, update text but does update tallies' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.reload.edited?).to be false
|
||||
end
|
||||
|
||||
it 'does not update the text' do
|
||||
expect(status.reload).to_not be_edited
|
||||
expect(status.reload.text).to eq 'Hello world'
|
||||
end
|
||||
|
||||
it 'updates tallies' do
|
||||
expect(status.poll.reload.cached_tallies).to eq [4, 3]
|
||||
end
|
||||
end
|
||||
|
@ -195,19 +176,10 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits, mark status edited, update text, or update tallies' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.reload.edited?).to be false
|
||||
end
|
||||
|
||||
it 'does not update the text' do
|
||||
expect(status.reload).to_not be_edited
|
||||
expect(status.reload.text).to eq 'Hello world'
|
||||
end
|
||||
|
||||
it 'does not update tallies' do
|
||||
expect(status.poll.reload.cached_tallies).to eq [0, 0]
|
||||
end
|
||||
end
|
||||
|
@ -219,13 +191,10 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
status.snapshot!(rate_limit: false)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
expect { subject.call(status, json, json) }.to_not(change { status.reload.edits.pluck(&:id) })
|
||||
end
|
||||
|
||||
it 'does not update the text, spoiler_text or edited_at' do
|
||||
it 'does not create any edits or update relevant attributes' do
|
||||
expect { subject.call(status, json, json) }
|
||||
.to_not(change { status.reload.attributes.slice('text', 'spoiler_text', 'edited_at').values })
|
||||
.to not_change { status.reload.edits.pluck(&:id) }
|
||||
.and(not_change { status.reload.attributes.slice('text', 'spoiler_text', 'edited_at').values })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -243,12 +212,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits or mark status edited' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.edited?).to be false
|
||||
expect(status).to_not be_edited
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -267,12 +233,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'does not create any edits' do
|
||||
it 'does not create any edits or mark status edited' do
|
||||
expect(status.reload.edits).to be_empty
|
||||
end
|
||||
|
||||
it 'does not mark status as edited' do
|
||||
expect(status.edited?).to be false
|
||||
expect(status).to_not be_edited
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -456,11 +419,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'removes poll' do
|
||||
it 'removes poll and records media change in edit' do
|
||||
expect(status.reload.poll).to be_nil
|
||||
end
|
||||
|
||||
it 'records media change in edit' do
|
||||
expect(status.edits.reload.last.poll_options).to be_nil
|
||||
end
|
||||
end
|
||||
|
@ -486,26 +446,21 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||
subject.call(status, json, json)
|
||||
end
|
||||
|
||||
it 'creates a poll' do
|
||||
it 'creates a poll and records media change in edit' do
|
||||
poll = status.reload.poll
|
||||
|
||||
expect(poll).to_not be_nil
|
||||
expect(poll.options).to eq %w(Foo Bar Baz)
|
||||
end
|
||||
|
||||
it 'records media change in edit' do
|
||||
expect(status.edits.reload.last.poll_options).to eq %w(Foo Bar Baz)
|
||||
end
|
||||
end
|
||||
|
||||
it 'creates edit history' do
|
||||
it 'creates edit history and sets edit timestamp' do
|
||||
subject.call(status, json, json)
|
||||
expect(status.edits.reload.map(&:text)).to eq ['Hello world', 'Hello universe']
|
||||
end
|
||||
|
||||
it 'sets edited timestamp' do
|
||||
subject.call(status, json, json)
|
||||
expect(status.reload.edited_at.to_s).to eq '2021-09-08 22:39:25 UTC'
|
||||
expect(status.edits.reload.map(&:text))
|
||||
.to eq ['Hello world', 'Hello universe']
|
||||
expect(status.reload.edited_at.to_s)
|
||||
.to eq '2021-09-08 22:39:25 UTC'
|
||||
end
|
||||
|
||||
describe 'ng word is set' do
|
||||
|
|
|
@ -13,11 +13,9 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
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),
|
||||
]
|
||||
[alice, eve, mallory].map do |account|
|
||||
ActivityPub::TagManager.instance.uri_for(account)
|
||||
end
|
||||
end
|
||||
|
||||
let(:payload) do
|
||||
|
@ -40,20 +38,15 @@ RSpec.describe ActivityPub::SynchronizeFollowersService do
|
|||
subject.call(actor, collection_uri)
|
||||
end
|
||||
|
||||
it 'keeps expected followers' do
|
||||
expect(alice.following?(actor)).to be true
|
||||
end
|
||||
|
||||
it 'removes local followers not in the remote list' do
|
||||
expect(bob.following?(actor)).to be false
|
||||
end
|
||||
|
||||
it 'converts follow requests to follow relationships when they have been accepted' do
|
||||
expect(mallory.following?(actor)).to be true
|
||||
end
|
||||
|
||||
it 'sends an Undo Follow to the actor' do
|
||||
expect(ActivityPub::DeliveryWorker).to have_received(:perform_async).with(anything, eve.id, actor.inbox_url)
|
||||
it 'maintains following records and sends Undo Follow to actor' do
|
||||
expect(alice)
|
||||
.to be_following(actor) # Keep expected followers
|
||||
expect(bob)
|
||||
.to_not be_following(actor) # Remove local followers not in remote list
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ RSpec.describe BackupService do
|
|||
|
||||
aggregate_failures do
|
||||
expect(body.scan('@context').count).to eq 1
|
||||
expect(body.scan('orderedItems').count).to eq 1
|
||||
expect(json['@context']).to_not be_nil
|
||||
expect(json['type']).to eq 'OrderedCollection'
|
||||
expect(json['totalItems']).to eq 4
|
||||
|
|
|
@ -85,29 +85,15 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is public' do
|
||||
let(:visibility) { 'public' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'adds status to home feed of author and followers and broadcasts', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(tom))
|
||||
.and be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of the mentioned follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
end
|
||||
|
||||
it 'is added to the home feed of a follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
expect(home_feed_of(tom)).to include status.id
|
||||
end
|
||||
|
||||
it 'is added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to include status.id
|
||||
end
|
||||
|
||||
it 'is broadcast to the hashtag stream', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge:local', anything)
|
||||
end
|
||||
|
||||
it 'is broadcast to the public stream', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:public', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:public:local', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:public:media', anything)
|
||||
|
@ -116,12 +102,9 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when local timeline is disabled', :inline_jobs do
|
||||
let(:ltl_enabled) { false }
|
||||
|
||||
it 'is broadcast to the hashtag stream', :inline_jobs do
|
||||
it 'does not add status to local timeline', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge:local', anything)
|
||||
end
|
||||
|
||||
it 'is broadcast to the public stream', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:public', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:public:local', anything)
|
||||
end
|
||||
|
@ -286,25 +269,16 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is limited' do
|
||||
let(:visibility) { 'limited' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'adds status to home feed of author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tom))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of the mentioned follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
end
|
||||
|
||||
it 'is not added to the home feed of the other follower', :inline_jobs do
|
||||
expect(home_feed_of(tom)).to_not include status.id
|
||||
end
|
||||
|
||||
it 'is not added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to_not include status.id
|
||||
end
|
||||
|
||||
it 'is not broadcast publicly', :inline_jobs do
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:public', anything)
|
||||
expect_no_broadcasting
|
||||
end
|
||||
|
||||
context 'with list' do
|
||||
|
@ -349,26 +323,15 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is private' do
|
||||
let(:visibility) { 'private' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(tom))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of a follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
expect(home_feed_of(tom)).to include status.id
|
||||
end
|
||||
|
||||
it 'is not added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to_not include status.id
|
||||
end
|
||||
|
||||
it 'is not broadcast publicly', :inline_jobs do
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:public', anything)
|
||||
end
|
||||
|
||||
it 'is added to the home feed of the mentioned follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
expect_no_broadcasting
|
||||
end
|
||||
|
||||
context 'with list' do
|
||||
|
@ -430,20 +393,14 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is public_unlisted' do
|
||||
let(:visibility) { 'public_unlisted' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(tom))
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of a follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
expect(home_feed_of(tom)).to include status.id
|
||||
end
|
||||
|
||||
it 'is added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to include status.id
|
||||
end
|
||||
|
||||
it 'is broadcast publicly', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:public:local', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:public', anything)
|
||||
|
@ -549,20 +506,14 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is unlisted' do
|
||||
let(:visibility) { 'unlisted' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(tom))
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of a follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
expect(home_feed_of(tom)).to include status.id
|
||||
end
|
||||
|
||||
it 'is added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to include status.id
|
||||
end
|
||||
|
||||
it 'is not broadcast publicly', :inline_jobs do
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:public', anything)
|
||||
end
|
||||
|
@ -570,27 +521,25 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'with searchability public_unlisted' do
|
||||
let(:searchability) { 'public_unlisted' }
|
||||
|
||||
it 'is broadcast to the hashtag stream', :inline_jobs do
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(tagf))
|
||||
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:hashtag:hoge:local', anything)
|
||||
end
|
||||
|
||||
it 'is added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to include status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'with searchability private' do
|
||||
let(:searchability) { 'private' }
|
||||
|
||||
it 'is not broadcast to the hashtag stream', :inline_jobs do
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tagf))
|
||||
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge:local', anything)
|
||||
end
|
||||
|
||||
it 'is not added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to_not include status.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when local timeline is disabled' do
|
||||
|
@ -670,25 +619,16 @@ RSpec.describe FanOutOnWriteService do
|
|||
context 'when status is direct' do
|
||||
let(:visibility) { 'direct' }
|
||||
|
||||
it 'is added to the home feed of its author', :inline_jobs do
|
||||
expect(home_feed_of(alice)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tom))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tagf))
|
||||
|
||||
it 'is added to the home feed of the mentioned follower', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
end
|
||||
|
||||
it 'is not added to the home feed of the other follower', :inline_jobs do
|
||||
expect(home_feed_of(tom)).to_not include status.id
|
||||
end
|
||||
|
||||
it 'is not added to the tag follower', :inline_jobs do
|
||||
expect(home_feed_of(tagf)).to_not include status.id
|
||||
end
|
||||
|
||||
it 'is not broadcast publicly', :inline_jobs do
|
||||
expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge', anything)
|
||||
expect(redis).to_not have_received(:publish).with('timeline:public', anything)
|
||||
expect_no_broadcasting
|
||||
end
|
||||
|
||||
context 'with list' do
|
||||
|
@ -746,16 +686,15 @@ RSpec.describe FanOutOnWriteService do
|
|||
expect(notification.mention.status_id).to eq status.id
|
||||
end
|
||||
|
||||
it 'inserts home feed for reply', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(zilu))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tom))
|
||||
|
||||
it 'inserts home feed for non-replied but mentioned and following replied account', :inline_jobs do
|
||||
expect(home_feed_of(zilu)).to include status.id
|
||||
end
|
||||
|
||||
it 'does not insert home feed for non-replied, non-following replied account but mentioned', :inline_jobs do
|
||||
expect(home_feed_of(tom)).to_not include status.id
|
||||
expect_no_broadcasting
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -776,16 +715,15 @@ RSpec.describe FanOutOnWriteService do
|
|||
expect(notification.mention.status_id).to eq status.id
|
||||
end
|
||||
|
||||
it 'inserts home feed for reply', :inline_jobs do
|
||||
expect(home_feed_of(bob)).to include status.id
|
||||
end
|
||||
it 'is added to the home feed of its author and mentioned followers and does not broadcast', :inline_jobs do
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
.and be_in(home_feed_of(bob))
|
||||
.and be_in(home_feed_of(zilu))
|
||||
expect(status.id)
|
||||
.to_not be_in(home_feed_of(tom))
|
||||
|
||||
it 'inserts home feed for non-replied but mentioned and following replied account', :inline_jobs do
|
||||
expect(home_feed_of(zilu)).to include status.id
|
||||
end
|
||||
|
||||
it 'does not insert home feed for non-replied, non-following replied account but mentioned', :inline_jobs do
|
||||
expect(home_feed_of(tom)).to_not include status.id
|
||||
expect_no_broadcasting
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -820,4 +758,13 @@ RSpec.describe FanOutOnWriteService do
|
|||
expect(notification).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def expect_no_broadcasting
|
||||
expect(redis)
|
||||
.to_not have_received(:publish)
|
||||
.with('timeline:hashtag:hoge', anything)
|
||||
expect(redis)
|
||||
.to_not have_received(:publish)
|
||||
.with('timeline:public', anything)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,11 @@ RSpec.describe ReportService do
|
|||
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
|
||||
end
|
||||
|
||||
it 'does not have an application' do
|
||||
report = subject.call(source_account, remote_account)
|
||||
expect(report.application).to be_nil
|
||||
end
|
||||
|
||||
context 'when forward is true', :inline_jobs do
|
||||
let(:forward) { true }
|
||||
|
||||
|
@ -96,6 +101,15 @@ RSpec.describe ReportService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when passed an application' do
|
||||
let(:application) { Fabricate(:application) }
|
||||
|
||||
it 'has an application' do
|
||||
report = subject.call(source_account, target_account, application: application)
|
||||
expect(report.application).to eq application
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the reported status is a DM' do
|
||||
subject do
|
||||
-> { described_class.new.call(source_account, target_account, status_ids: [status.id]) }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue