Merge commit '0ddc895282
' into kb_migration
This commit is contained in:
commit
9027195ae3
66 changed files with 1037 additions and 250 deletions
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::InstanceAccountsDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::InstanceLanguagesDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
18
spec/lib/admin/metrics/dimension/languages_dimension_spec.rb
Normal file
18
spec/lib/admin/metrics/dimension/languages_dimension_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::LanguagesDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
18
spec/lib/admin/metrics/dimension/servers_dimension_spec.rb
Normal file
18
spec/lib/admin/metrics/dimension/servers_dimension_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::ServersDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::SoftwareVersionsDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
18
spec/lib/admin/metrics/dimension/sources_dimension_spec.rb
Normal file
18
spec/lib/admin/metrics/dimension/sources_dimension_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::SourcesDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::SpaceUsageDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::TagLanguagesDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Dimension::TagServersDimension do
|
||||
subject(:dimension) { described_class.new(start_at, end_at, limit, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:limit) { 10 }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { dimension.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
17
spec/lib/admin/metrics/measure/active_users_measure_spec.rb
Normal file
17
spec/lib/admin/metrics/measure/active_users_measure_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::ActiveUsersMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -37,4 +37,10 @@ describe Admin::Metrics::Measure::InstanceAccountsMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,4 +39,10 @@ describe Admin::Metrics::Measure::InstanceFollowersMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,4 +39,10 @@ describe Admin::Metrics::Measure::InstanceFollowsMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,4 +40,10 @@ describe Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,4 +36,10 @@ describe Admin::Metrics::Measure::InstanceReportsMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,4 +36,10 @@ describe Admin::Metrics::Measure::InstanceStatusesMeasure do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
17
spec/lib/admin/metrics/measure/interactions_measure_spec.rb
Normal file
17
spec/lib/admin/metrics/measure/interactions_measure_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::InteractionsMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
17
spec/lib/admin/metrics/measure/new_users_measure_spec.rb
Normal file
17
spec/lib/admin/metrics/measure/new_users_measure_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::NewUsersMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::OpenedReportsMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::ResolvedReportsMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
19
spec/lib/admin/metrics/measure/tag_accounts_measure_spec.rb
Normal file
19
spec/lib/admin/metrics/measure/tag_accounts_measure_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::TagAccountsMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let!(:tag) { Fabricate(:tag) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new(id: tag.id) }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
19
spec/lib/admin/metrics/measure/tag_servers_measure_spec.rb
Normal file
19
spec/lib/admin/metrics/measure/tag_servers_measure_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::TagServersMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let!(:tag) { Fabricate(:tag) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new(id: tag.id) }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
19
spec/lib/admin/metrics/measure/tag_uses_measure_spec.rb
Normal file
19
spec/lib/admin/metrics/measure/tag_uses_measure_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Admin::Metrics::Measure::TagUsesMeasure do
|
||||
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||
|
||||
let!(:tag) { Fabricate(:tag) }
|
||||
|
||||
let(:start_at) { 2.days.ago }
|
||||
let(:end_at) { Time.now.utc }
|
||||
let(:params) { ActionController::Parameters.new(id: tag.id) }
|
||||
|
||||
describe '#data' do
|
||||
it 'runs data query without error' do
|
||||
expect { measure.data }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,6 +26,7 @@ RSpec.describe FeedManager do
|
|||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
|
||||
let(:jeff) { Fabricate(:account, username: 'jeff') }
|
||||
let(:list) { Fabricate(:list, account: alice) }
|
||||
|
||||
context 'with home feed' do
|
||||
it 'returns false for followee\'s status' do
|
||||
|
@ -153,6 +154,42 @@ RSpec.describe FeedManager do
|
|||
status = Fabricate(:status, text: 'Hallo Welt', account: bob, language: 'de')
|
||||
expect(FeedManager.instance.filter?(:home, status, alice)).to be false
|
||||
end
|
||||
|
||||
it 'returns true for post from followee on exclusive list' do
|
||||
list.exclusive = true
|
||||
alice.follow!(bob)
|
||||
list.accounts << bob
|
||||
allow(List).to receive(:where).and_return(list)
|
||||
status = Fabricate(:status, text: 'I post a lot', account: bob)
|
||||
expect(FeedManager.instance.filter?(:home, status, alice)).to be true
|
||||
end
|
||||
|
||||
it 'returns true for reblog from followee on exclusive list' do
|
||||
list.exclusive = true
|
||||
alice.follow!(jeff)
|
||||
list.accounts << jeff
|
||||
allow(List).to receive(:where).and_return(list)
|
||||
status = Fabricate(:status, text: 'I post a lot', account: bob)
|
||||
reblog = Fabricate(:status, reblog: status, account: jeff)
|
||||
expect(FeedManager.instance.filter?(:home, reblog, alice)).to be true
|
||||
end
|
||||
|
||||
it 'returns false for post from followee on non-exclusive list' do
|
||||
list.exclusive = false
|
||||
alice.follow!(bob)
|
||||
list.accounts << bob
|
||||
status = Fabricate(:status, text: 'I post a lot', account: bob)
|
||||
expect(FeedManager.instance.filter?(:home, status, alice)).to be false
|
||||
end
|
||||
|
||||
it 'returns false for reblog from followee on non-exclusive list' do
|
||||
list.exclusive = false
|
||||
alice.follow!(jeff)
|
||||
list.accounts << jeff
|
||||
status = Fabricate(:status, text: 'I post a lot', account: bob)
|
||||
reblog = Fabricate(:status, reblog: status, account: jeff)
|
||||
expect(FeedManager.instance.filter?(:home, reblog, alice)).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'with mentions feed' do
|
||||
|
|
|
@ -998,4 +998,254 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge' do
|
||||
shared_examples 'an account not found' do |acct|
|
||||
it 'exits with an error message indicating that there is no such account' do
|
||||
expect { cli.invoke(:merge, arguments) }.to output(
|
||||
a_string_including("No such account (#{acct})")
|
||||
).to_stdout
|
||||
.and raise_error(SystemExit)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "from_account" is not found' do
|
||||
let(:to_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:arguments) { ['non_existent_username@domain.com', "#{to_account.username}@#{to_account.domain}"] }
|
||||
|
||||
it_behaves_like 'an account not found', 'non_existent_username@domain.com'
|
||||
end
|
||||
|
||||
context 'when "from_account" is a local account' do
|
||||
let(:from_account) { Fabricate(:account, domain: nil, username: 'bob') }
|
||||
let(:to_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:arguments) { [from_account.username, "#{to_account.username}@#{to_account.domain}"] }
|
||||
|
||||
it_behaves_like 'an account not found', 'bob'
|
||||
end
|
||||
|
||||
context 'when "to_account" is not found' do
|
||||
let(:from_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:arguments) { ["#{from_account.username}@#{from_account.domain}", 'non_existent_username'] }
|
||||
|
||||
it_behaves_like 'an account not found', 'non_existent_username'
|
||||
end
|
||||
|
||||
context 'when "to_account" is local' do
|
||||
let(:from_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let(:to_account) { Fabricate(:account, domain: nil, username: 'bob') }
|
||||
let(:arguments) do
|
||||
["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
|
||||
end
|
||||
|
||||
it_behaves_like 'an account not found', 'bob@'
|
||||
end
|
||||
|
||||
context 'when "from_account" and "to_account" public keys do not match' do
|
||||
let(:from_account) { instance_double(Account, username: 'bob', domain: 'example1.com', local?: false, public_key: 'from_account') }
|
||||
let(:to_account) { instance_double(Account, username: 'bob', domain: 'example2.com', local?: false, public_key: 'to_account') }
|
||||
let(:arguments) do
|
||||
["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Account).to receive(:find_remote).with(from_account.username, from_account.domain).and_return(from_account)
|
||||
allow(Account).to receive(:find_remote).with(to_account.username, to_account.domain).and_return(to_account)
|
||||
end
|
||||
|
||||
it 'exits with an error message indicating that the accounts do not have the same pub key' do
|
||||
expect { cli.invoke(:merge, arguments) }.to output(
|
||||
a_string_including("Accounts don't have the same public key, might not be duplicates!\nOverride with --force")
|
||||
).to_stdout
|
||||
.and raise_error(SystemExit)
|
||||
end
|
||||
|
||||
context 'with --force option' do
|
||||
let(:options) { { force: true } }
|
||||
|
||||
before do
|
||||
allow(to_account).to receive(:merge_with!)
|
||||
allow(from_account).to receive(:destroy)
|
||||
end
|
||||
|
||||
it 'merges "from_account" into "to_account"' do
|
||||
cli.invoke(:merge, arguments, options)
|
||||
|
||||
expect(to_account).to have_received(:merge_with!).with(from_account).once
|
||||
end
|
||||
|
||||
it 'deletes "from_account"' do
|
||||
cli.invoke(:merge, arguments, options)
|
||||
|
||||
expect(from_account).to have_received(:destroy).once
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "from_account" and "to_account" public keys match' do
|
||||
let(:from_account) { instance_double(Account, username: 'bob', domain: 'example1.com', local?: false, public_key: 'pub_key') }
|
||||
let(:to_account) { instance_double(Account, username: 'bob', domain: 'example2.com', local?: false, public_key: 'pub_key') }
|
||||
let(:arguments) do
|
||||
["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Account).to receive(:find_remote).with(from_account.username, from_account.domain).and_return(from_account)
|
||||
allow(Account).to receive(:find_remote).with(to_account.username, to_account.domain).and_return(to_account)
|
||||
allow(to_account).to receive(:merge_with!)
|
||||
allow(from_account).to receive(:destroy)
|
||||
end
|
||||
|
||||
it 'merges "from_account" into "to_account"' do
|
||||
cli.invoke(:merge, arguments)
|
||||
|
||||
expect(to_account).to have_received(:merge_with!).with(from_account).once
|
||||
end
|
||||
|
||||
it 'deletes "from_account"' do
|
||||
cli.invoke(:merge, arguments)
|
||||
|
||||
expect(from_account).to have_received(:destroy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#cull' do
|
||||
let(:delete_account_service) { instance_double(DeleteAccountService, call: nil) }
|
||||
let!(:tom) { Fabricate(:account, updated_at: 30.days.ago, username: 'tom', uri: 'https://example.com/users/tom', domain: 'example.com') }
|
||||
let!(:bob) { Fabricate(:account, updated_at: 30.days.ago, last_webfingered_at: nil, username: 'bob', uri: 'https://example.org/users/bob', domain: 'example.org') }
|
||||
let!(:gon) { Fabricate(:account, updated_at: 15.days.ago, last_webfingered_at: 15.days.ago, username: 'gon', uri: 'https://example.net/users/gon', domain: 'example.net') }
|
||||
let!(:ana) { Fabricate(:account, username: 'ana', uri: 'https://example.com/users/ana', domain: 'example.com') }
|
||||
let!(:tales) { Fabricate(:account, updated_at: 10.days.ago, last_webfingered_at: nil, username: 'tales', uri: 'https://example.net/users/tales', domain: 'example.net') }
|
||||
|
||||
before do
|
||||
allow(DeleteAccountService).to receive(:new).and_return(delete_account_service)
|
||||
end
|
||||
|
||||
context 'when no domain is specified' do
|
||||
let(:scope) { Account.remote.where(protocol: :activitypub).partitioned }
|
||||
|
||||
before do
|
||||
allow(cli).to receive(:parallelize_with_progress).and_yield(tom)
|
||||
.and_yield(bob)
|
||||
.and_yield(gon)
|
||||
.and_yield(ana)
|
||||
.and_yield(tales)
|
||||
.and_return([5, 3])
|
||||
stub_request(:head, 'https://example.org/users/bob').to_return(status: 404)
|
||||
stub_request(:head, 'https://example.net/users/gon').to_return(status: 410)
|
||||
stub_request(:head, 'https://example.net/users/tales').to_return(status: 200)
|
||||
end
|
||||
|
||||
it 'deletes all inactive remote accounts that longer exist in the origin server' do
|
||||
cli.cull
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(delete_account_service).to have_received(:call).with(bob, reserve_username: false).once
|
||||
expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
|
||||
end
|
||||
|
||||
it 'does not delete any active remote account that still exists in the origin server' do
|
||||
cli.cull
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(delete_account_service).to_not have_received(:call).with(tom, reserve_username: false)
|
||||
expect(delete_account_service).to_not have_received(:call).with(ana, reserve_username: false)
|
||||
expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
|
||||
end
|
||||
|
||||
it 'touches inactive remote accounts that have not been deleted' do
|
||||
allow(tales).to receive(:touch)
|
||||
|
||||
cli.cull
|
||||
|
||||
expect(tales).to have_received(:touch).once
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
expect { cli.cull }.to output(
|
||||
a_string_including('Visited 5 accounts, removed 3')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a domain is specified' do
|
||||
let(:domain) { 'example.net' }
|
||||
let(:scope) { Account.remote.where(protocol: :activitypub, domain: domain).partitioned }
|
||||
|
||||
before do
|
||||
allow(cli).to receive(:parallelize_with_progress).and_yield(gon)
|
||||
.and_yield(tales)
|
||||
.and_return([2, 2])
|
||||
stub_request(:head, 'https://example.net/users/gon').to_return(status: 410)
|
||||
stub_request(:head, 'https://example.net/users/tales').to_return(status: 404)
|
||||
end
|
||||
|
||||
it 'deletes inactive remote accounts that longer exist in the specified domain' do
|
||||
cli.cull(domain)
|
||||
|
||||
expect(cli).to have_received(:parallelize_with_progress).with(scope).once
|
||||
expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
|
||||
expect(delete_account_service).to have_received(:call).with(tales, reserve_username: false).once
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
expect { cli.cull }.to output(
|
||||
a_string_including('Visited 2 accounts, removed 2')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a domain is unavailable' do
|
||||
shared_examples 'an unavailable domain' do
|
||||
before do
|
||||
allow(cli).to receive(:parallelize_with_progress).and_yield(tales).and_return([1, 0])
|
||||
end
|
||||
|
||||
it 'skips accounts from the unavailable domain' do
|
||||
cli.cull
|
||||
|
||||
expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
|
||||
end
|
||||
|
||||
it 'displays the summary correctly' do
|
||||
expect { cli.cull }.to output(
|
||||
a_string_including("Visited 1 accounts, removed 0\nThe following domains were not available during the check:\n example.net")
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a connection timeout occurs' do
|
||||
before do
|
||||
stub_request(:head, 'https://example.net/users/tales').to_timeout
|
||||
end
|
||||
|
||||
it_behaves_like 'an unavailable domain'
|
||||
end
|
||||
|
||||
context 'when a connection error occurs' do
|
||||
before do
|
||||
stub_request(:head, 'https://example.net/users/tales').to_raise(HTTP::ConnectionError)
|
||||
end
|
||||
|
||||
it_behaves_like 'an unavailable domain'
|
||||
end
|
||||
|
||||
context 'when an ssl error occurs' do
|
||||
before do
|
||||
stub_request(:head, 'https://example.net/users/tales').to_raise(OpenSSL::SSL::SSLError)
|
||||
end
|
||||
|
||||
it_behaves_like 'an unavailable domain'
|
||||
end
|
||||
|
||||
context 'when a private network address error occurs' do
|
||||
before do
|
||||
stub_request(:head, 'https://example.net/users/tales').to_raise(Mastodon::PrivateNetworkAddressError)
|
||||
end
|
||||
|
||||
it_behaves_like 'an unavailable domain'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,9 +4,57 @@ require 'rails_helper'
|
|||
require 'mastodon/cli/canonical_email_blocks'
|
||||
|
||||
describe Mastodon::CLI::CanonicalEmailBlocks do
|
||||
let(:cli) { described_class.new }
|
||||
|
||||
describe '.exit_on_failure?' do
|
||||
it 'returns true' do
|
||||
expect(described_class.exit_on_failure?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#find' do
|
||||
let(:arguments) { ['user@example.com'] }
|
||||
|
||||
context 'when a block is present' do
|
||||
before { Fabricate(:canonical_email_block, email: 'user@example.com') }
|
||||
|
||||
it 'announces the presence of the block' do
|
||||
expect { cli.invoke(:find, arguments) }.to output(
|
||||
a_string_including('user@example.com is blocked')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a block is not present' do
|
||||
it 'announces the absence of the block' do
|
||||
expect { cli.invoke(:find, arguments) }.to output(
|
||||
a_string_including('user@example.com is not blocked')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#remove' do
|
||||
let(:arguments) { ['user@example.com'] }
|
||||
|
||||
context 'when a block is present' do
|
||||
before { Fabricate(:canonical_email_block, email: 'user@example.com') }
|
||||
|
||||
it 'removes the block' do
|
||||
expect { cli.invoke(:remove, arguments) }.to output(
|
||||
a_string_including('Unblocked user@example.com')
|
||||
).to_stdout
|
||||
|
||||
expect(CanonicalEmailBlock.matching_email('user@example.com')).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a block is not present' do
|
||||
it 'announces the absence of the block' do
|
||||
expect { cli.invoke(:remove, arguments) }.to output(
|
||||
a_string_including('user@example.com is not blocked')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue