~cytrogen/masto-fe

03a707f6a6c8bbefec630c04d183fc9f22b23d9d — Daniel M Brasil 2 years ago e498191
Add test coverage for `Mastodon::CLI::Accounts#merge` (#25199)

1 files changed, 111 insertions(+), 0 deletions(-)

M spec/lib/mastodon/cli/accounts_spec.rb
M spec/lib/mastodon/cli/accounts_spec.rb => spec/lib/mastodon/cli/accounts_spec.rb +111 -0
@@ 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