diff --git a/spec/models/account_reach_filter_spec.rb b/spec/models/account_reach_filter_spec.rb new file mode 100644 index 00000000000..5dbe7b2e5a0 --- /dev/null +++ b/spec/models/account_reach_filter_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AccountReachFilter do + describe 'basic functionality' do + let(:filter) { Fabricate(:account_reach_filter) } + + it 'allows correct membership tests' do + filter.add('mastodon.social') + expect(filter.include?('mastodon.social')).to be true + expect(filter.include?('mastodon.online')).to be false + end + + it 'allows correct membership tests after save/reload' do + filter.add('mastodon.social') + filter.save! + filter.reload + expect(filter.include?('mastodon.social')).to be true + expect(filter.include?('mastodon.online')).to be false + end + end +end diff --git a/spec/requests/accounts_spec.rb b/spec/requests/accounts_spec.rb index 26f8f577b09..c5aca88acc9 100644 --- a/spec/requests/accounts_spec.rb +++ b/spec/requests/accounts_spec.rb @@ -7,10 +7,16 @@ RSpec.describe 'Accounts show response' do context 'with numeric-based identifiers' do context 'with JSON format' do - it 'returns http success' do + before do + account.build_reach_filter + account.save! + end + + it 'returns http success and removes reach filter' do get "/ap/users/#{account.id}", headers: { 'ACCEPT' => 'application/json' } expect(response).to have_http_status(200) + expect(account.reload.reach_filter.present?).to be false end end @@ -198,14 +204,17 @@ RSpec.describe 'Accounts show response' do end end - context 'with signature' do - let(:remote_account) { Fabricate(:account, domain: 'example.com') } + context 'with signature', :inline_jobs do + let(:remote_account) { Fabricate(:account, domain: 'example.com', inbox_url: 'https://example.com/inbox') } before do + account.build_reach_filter + account.save! + get short_account_path(username: account.username), headers: headers, sign_with: remote_account end - it 'returns a JSON version of the account', :aggregate_failures do + it 'returns a JSON version of the account and removes reach filter', :aggregate_failures do expect(response) .to have_http_status(200) .and have_cacheable_headers.with_vary('Accept, Accept-Language, Cookie') @@ -214,12 +223,14 @@ RSpec.describe 'Accounts show response' do ) expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) + + expect(account.reload.reach_filter.present?).to be false end context 'with authorized fetch mode' do let(:authorized_fetch_mode) { true } - it 'returns a private signature JSON version of the account', :aggregate_failures do + it 'returns a private signature JSON version of the account and updates the reach filter', :aggregate_failures do expect(response) .to have_http_status(200) .and have_attributes( @@ -230,6 +241,9 @@ RSpec.describe 'Accounts show response' do expect(response.headers['Vary']).to include 'Signature' expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) + + expect(account.reach_filter.reload.include?('example.com')).to be true + expect(account.reach_filter.reload.include?('bad.com')).to be false end end end diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index 291ae8035c9..d1f41266fbe 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -75,20 +75,40 @@ RSpec.describe DeleteAccountService do before do stub_request(:post, remote_alice.inbox_url).to_return(status: 201) stub_request(:post, remote_bob.inbox_url).to_return(status: 201) + stub_request(:post, remote_eve.inbox_url).to_return(status: 201) end let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', domain: 'alice.com', protocol: :activitypub) } - let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', domain: 'bob.com', protocol: :activitypub) } + let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', domain: 'bob.com', protocol: :activitypub) } + let!(:remote_eve) { Fabricate(:account, inbox_url: 'https://eve.com/inbox', domain: 'eve.com', protocol: :activitypub) } it_behaves_like 'common behavior' do let(:account) { Fabricate(:account) } let(:local_follower) { Fabricate(:account) } let!(:collection) { Fabricate(:collection, account:) } # rubocop:disable RSpec/LetSetup - it 'sends a delete actor activity to all known inboxes' do - subject - expect(a_request(:post, remote_alice.inbox_url)).to have_been_made.once - expect(a_request(:post, remote_bob.inbox_url)).to have_been_made.once + context 'without a reach filter' do + it 'sends a delete actor activity to all known inboxes' do + subject + expect(a_request(:post, remote_alice.inbox_url)).to have_been_made.once + expect(a_request(:post, remote_bob.inbox_url)).to have_been_made.once + expect(a_request(:post, remote_eve.inbox_url)).to have_been_made.once + end + end + + context 'with a reach filter' do + before do + account.build_reach_filter + account.reach_filter.add('alice.com') + account.reach_filter.add('bob.com') + end + + it 'sends a delete actor activity to inboxes matching the reach filter' do + subject + expect(a_request(:post, remote_alice.inbox_url)).to have_been_made.once + expect(a_request(:post, remote_bob.inbox_url)).to have_been_made.once + expect(a_request(:post, remote_eve.inbox_url)).to_not have_been_made + end end end end diff --git a/spec/workers/update_account_reach_worker_spec.rb b/spec/workers/update_account_reach_worker_spec.rb new file mode 100644 index 00000000000..17a62f42c2f --- /dev/null +++ b/spec/workers/update_account_reach_worker_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe UpdateAccountReachWorker do + subject { described_class.new } + + describe 'perform' do + let(:account_reach_filter) { Fabricate(:account_reach_filter) } + + before do + 100.times { |i| redis.sadd("account_reach:#{account_reach_filter.id}:to_add", "test-domain-#{i}.org") } + end + + it 'consolidates pending additions' do + subject.perform(account_reach_filter.id) + account_reach_filter.reload + + 100.times { |i| expect(account_reach_filter.include?("test-domain-#{i}.org")).to be true } + + expect(account_reach_filter.include?('unknwon-domain.org')).to be false + end + end +end