From 03a707f6a6c8bbefec630c04d183fc9f22b23d9d Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Mon, 5 Jun 2023 03:16:12 -0300 Subject: [PATCH] Add test coverage for `Mastodon::CLI::Accounts#merge` (#25199) --- spec/lib/mastodon/cli/accounts_spec.rb | 111 +++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index ba49e480a..50066572c 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -998,4 +998,115 @@ 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 end