Formalize some patterns in cli specs (#28255)
This commit is contained in:
		@@ -4,11 +4,16 @@ require 'rails_helper'
 | 
			
		||||
require 'mastodon/cli/ip_blocks'
 | 
			
		||||
 | 
			
		||||
describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
  subject { cli.invoke(action, arguments, options) }
 | 
			
		||||
 | 
			
		||||
  let(:cli) { described_class.new }
 | 
			
		||||
  let(:arguments) { [] }
 | 
			
		||||
  let(:options) { {} }
 | 
			
		||||
 | 
			
		||||
  it_behaves_like 'CLI Command'
 | 
			
		||||
 | 
			
		||||
  describe '#add' do
 | 
			
		||||
    let(:action) { :add }
 | 
			
		||||
    let(:ip_list) do
 | 
			
		||||
      [
 | 
			
		||||
        '192.0.2.1',
 | 
			
		||||
@@ -25,10 +30,11 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      ]
 | 
			
		||||
    end
 | 
			
		||||
    let(:options) { { severity: 'no_access' } }
 | 
			
		||||
    let(:arguments) { ip_list }
 | 
			
		||||
 | 
			
		||||
    shared_examples 'ip address blocking' do
 | 
			
		||||
      it 'blocks all specified IP addresses' do
 | 
			
		||||
        cli.invoke(:add, ip_list, options)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip)
 | 
			
		||||
        expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) }
 | 
			
		||||
@@ -37,7 +43,7 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'sets the severity for all blocked IP addresses' do
 | 
			
		||||
        cli.invoke(:add, ip_list, options)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity])
 | 
			
		||||
 | 
			
		||||
@@ -45,9 +51,8 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays a success message with a summary' do
 | 
			
		||||
        expect { cli.invoke(:add, ip_list, options) }.to output(
 | 
			
		||||
          a_string_including("Added #{ip_list.size}, skipped 0, failed 0")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("Added #{ip_list.size}, skipped 0, failed 0")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@@ -57,19 +62,19 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
 | 
			
		||||
    context 'when a specified IP address is already blocked' do
 | 
			
		||||
      let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) }
 | 
			
		||||
      let(:arguments) { ip_list }
 | 
			
		||||
 | 
			
		||||
      it 'skips the already blocked IP address' do
 | 
			
		||||
        allow(IpBlock).to receive(:new).and_call_original
 | 
			
		||||
 | 
			
		||||
        cli.invoke(:add, ip_list, options)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays the correct summary' do
 | 
			
		||||
        expect { cli.invoke(:add, ip_list, options) }.to output(
 | 
			
		||||
          a_string_including("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      context 'with --force option' do
 | 
			
		||||
@@ -77,7 +82,7 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
        let(:options) { { severity: 'sign_up_requires_approval', force: true } }
 | 
			
		||||
 | 
			
		||||
        it 'overwrites the existing IP block record' do
 | 
			
		||||
          expect { cli.invoke(:add, ip_list, options) }
 | 
			
		||||
          expect { subject }
 | 
			
		||||
            .to change { blocked_ip.reload.severity }
 | 
			
		||||
            .from('no_access')
 | 
			
		||||
            .to('sign_up_requires_approval')
 | 
			
		||||
@@ -89,11 +94,11 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
 | 
			
		||||
    context 'when a specified IP address is invalid' do
 | 
			
		||||
      let(:ip_list) { ['320.15.175.0', '9.5.105.255', '0.0.0.0'] }
 | 
			
		||||
      let(:arguments) { ip_list }
 | 
			
		||||
 | 
			
		||||
      it 'displays the correct summary' do
 | 
			
		||||
        expect { cli.invoke(:add, ip_list, options) }.to output(
 | 
			
		||||
          a_string_including("#{ip_list.first} is invalid\nAdded #{ip_list.size - 1}, skipped 0, failed 1")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{ip_list.first} is invalid\nAdded #{ip_list.size - 1}, skipped 0, failed 1")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@@ -124,6 +129,7 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
    context 'when a specified IP address fails to be blocked' do
 | 
			
		||||
      let(:ip_address) { '127.0.0.1' }
 | 
			
		||||
      let(:ip_block) { instance_double(IpBlock, ip: ip_address, save: false) }
 | 
			
		||||
      let(:arguments) { [ip_address] }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        allow(IpBlock).to receive(:new).and_return(ip_block)
 | 
			
		||||
@@ -132,24 +138,25 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays an error message' do
 | 
			
		||||
        expect { cli.invoke(:add, [ip_address], options) }
 | 
			
		||||
          .to output(
 | 
			
		||||
            a_string_including("#{ip_address} could not be saved")
 | 
			
		||||
          ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{ip_address} could not be saved")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'when no IP address is provided' do
 | 
			
		||||
      let(:arguments) { [] }
 | 
			
		||||
 | 
			
		||||
      it 'exits with an error message' do
 | 
			
		||||
        expect { cli.add }.to output(
 | 
			
		||||
          a_string_including('No IP(s) given')
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results('No IP(s) given')
 | 
			
		||||
          .and raise_error(SystemExit)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#remove' do
 | 
			
		||||
    let(:action) { :remove }
 | 
			
		||||
 | 
			
		||||
    context 'when removing exact matches' do
 | 
			
		||||
      let(:ip_list) do
 | 
			
		||||
        [
 | 
			
		||||
@@ -166,21 +173,21 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
          '::/128',
 | 
			
		||||
        ]
 | 
			
		||||
      end
 | 
			
		||||
      let(:arguments) { ip_list }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'removes exact IP blocks' do
 | 
			
		||||
        cli.invoke(:remove, ip_list)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        expect(IpBlock.where(ip: ip_list)).to_not exist
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays success message with a summary' do
 | 
			
		||||
        expect { cli.invoke(:remove, ip_list) }.to output(
 | 
			
		||||
          a_string_including("Removed #{ip_list.size}, skipped 0")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("Removed #{ip_list.size}, skipped 0")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@@ -192,13 +199,13 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      let(:options) { { force: true } }
 | 
			
		||||
 | 
			
		||||
      it 'removes blocks for IP ranges that cover given IP(s)' do
 | 
			
		||||
        cli.invoke(:remove, arguments, options)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not remove other IP ranges' do
 | 
			
		||||
        cli.invoke(:remove, arguments, options)
 | 
			
		||||
        subject
 | 
			
		||||
 | 
			
		||||
        expect(IpBlock.where(id: third_ip_range_block.id)).to exist
 | 
			
		||||
      end
 | 
			
		||||
@@ -206,47 +213,46 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
 | 
			
		||||
    context 'when a specified IP address is not blocked' do
 | 
			
		||||
      let(:unblocked_ip) { '192.0.2.1' }
 | 
			
		||||
      let(:arguments) { [unblocked_ip] }
 | 
			
		||||
 | 
			
		||||
      it 'skips the IP address' do
 | 
			
		||||
        expect { cli.invoke(:remove, [unblocked_ip]) }.to output(
 | 
			
		||||
          a_string_including("#{unblocked_ip} is not yet blocked")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{unblocked_ip} is not yet blocked")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays the summary correctly' do
 | 
			
		||||
        expect { cli.invoke(:remove, [unblocked_ip]) }.to output(
 | 
			
		||||
          a_string_including('Removed 0, skipped 1')
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results('Removed 0, skipped 1')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'when a specified IP address is invalid' do
 | 
			
		||||
      let(:invalid_ip) { '320.15.175.0' }
 | 
			
		||||
      let(:arguments) { [invalid_ip] }
 | 
			
		||||
 | 
			
		||||
      it 'skips the invalid IP address' do
 | 
			
		||||
        expect { cli.invoke(:remove, [invalid_ip]) }.to output(
 | 
			
		||||
          a_string_including("#{invalid_ip} is invalid")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{invalid_ip} is invalid")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'displays the summary correctly' do
 | 
			
		||||
        expect { cli.invoke(:remove, [invalid_ip]) }.to output(
 | 
			
		||||
          a_string_including('Removed 0, skipped 1')
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results('Removed 0, skipped 1')
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'when no IP address is provided' do
 | 
			
		||||
      it 'exits with an error message' do
 | 
			
		||||
        expect { cli.remove }.to output(
 | 
			
		||||
          a_string_including('No IP(s) given')
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results('No IP(s) given')
 | 
			
		||||
          .and raise_error(SystemExit)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#export' do
 | 
			
		||||
    let(:action) { :export }
 | 
			
		||||
 | 
			
		||||
    let(:first_ip_range_block) { IpBlock.create(ip: '192.168.0.0/24', severity: :no_access) }
 | 
			
		||||
    let(:second_ip_range_block) { IpBlock.create(ip: '10.0.0.0/16', severity: :no_access) }
 | 
			
		||||
    let(:third_ip_range_block) { IpBlock.create(ip: '127.0.0.1', severity: :sign_up_block) }
 | 
			
		||||
@@ -255,15 +261,13 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      let(:options) { { format: 'plain' } }
 | 
			
		||||
 | 
			
		||||
      it 'exports blocked IPs with "no_access" severity in plain format' do
 | 
			
		||||
        expect { cli.invoke(:export, nil, options) }.to output(
 | 
			
		||||
          a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not export bloked IPs with different severities' do
 | 
			
		||||
        expect { cli.invoke(:export, nil, options) }.to_not output(
 | 
			
		||||
          a_string_including("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to_not output_results("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@@ -271,23 +275,20 @@ describe Mastodon::CLI::IpBlocks do
 | 
			
		||||
      let(:options) { { format: 'nginx' } }
 | 
			
		||||
 | 
			
		||||
      it 'exports blocked IPs with "no_access" severity in plain format' do
 | 
			
		||||
        expect { cli.invoke(:export, nil, options) }.to output(
 | 
			
		||||
          a_string_including("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not export bloked IPs with different severities' do
 | 
			
		||||
        expect { cli.invoke(:export, nil, options) }.to_not output(
 | 
			
		||||
          a_string_including("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to_not output_results("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'when --format option is not provided' do
 | 
			
		||||
      it 'exports blocked IPs in plain format by default' do
 | 
			
		||||
        expect { cli.export }.to output(
 | 
			
		||||
          a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
 | 
			
		||||
        ).to_stdout
 | 
			
		||||
        expect { subject }
 | 
			
		||||
          .to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user