# frozen_string_literal: true

describe Gitlab::QA::Runner do
  let(:image) { Gitlab::QA::Scenario::Test::Instance::Image }
  let(:scenario_arg) { ['Test::Instance::Image'] }

  before do
    allow(image).to receive(:perform)
  end

  describe '.run' do
    shared_examples 'passes args to scenario' do
      it 'accepts defined options' do
        described_class.run(scenario_arg + passed_args)

        expect(image).to have_received(:perform).with(*passed_args)
      end
    end

    context 'when passing gitlab-qa and rspec args' do
      it_behaves_like 'passes args to scenario' do
        let(:passed_args) { %w[CE -- --tag smoke] }
      end
    end

    context 'when enabling a feature flag' do
      it_behaves_like 'passes args to scenario' do
        let(:passed_args) { %w[CE --enable-feature gitaly_enforce_requests_limits] }
      end
    end

    context 'when enabling a feature flag with scenarios with no release specified' do
      it_behaves_like 'passes args to scenario' do
        let(:passed_args) { %w[--enable-feature gitaly_enforce_requests_limits] }
      end
    end

    context 'when specifying an address' do
      it_behaves_like 'passes args to scenario' do
        let(:passed_args) { %w[CE --address http://testurl] }
      end
    end

    context 'when specifying a mattermost server address' do
      it_behaves_like 'passes args to scenario' do
        let(:passed_args) { %w[CE --mattermost-address http://mattermost-server] }
      end
    end

    it 'ignores unsupported options' do
      passed_args = %w[CE --foo]

      expect { described_class.run(scenario_arg + passed_args) }.not_to raise_error
    end

    it 'does not pass options to the tests if they are only for GitLab QA' do
      described_class.run(scenario_arg + %w[EE --no-teardown --no-tests --seed-db file1,file2 --no-admin-token])

      expect(image).to have_received(:perform).with('EE')
    end

    it 'includes the Default Omnibus configuration' do
      described_class.run(scenario_arg + %w[EE])

      expect(Gitlab::QA::Runtime::Scenario.omnibus_configuration.to_s)
        .to include(Gitlab::QA::Runtime::OmnibusConfigurations::Default.configuration.strip)
    end

    it 'disables seed_db option by default' do
      described_class.run(scenario_arg + %w[EE])

      expect(Gitlab::QA::Runtime::Scenario.seed_db).to be false
    end

    context 'with omnibus configurations specified' do
      let(:passed_args) { %w[EE --omnibus-config default] }
      let(:default) { 'Gitlab::QA::Runtime::OmnibusConfigurations::Default' }
      let(:config) { Gitlab::QA::Runtime::Scenario.omnibus_configuration.to_s.split("\n") }

      before do
        described_class.run(scenario_arg + passed_args)
      end

      it 'has a comment showing that GitLab QA is configuring Omnibus' do
        expect(config.first).to include('GitLab QA')
      end

      it 'adds a comment indicating which configuration is being loaded' do
        expect(config).to include("# #{default}")
      end

      it 'loads the default configuration' do
        # remove first two comment lines
        expect(config[2..]).to eq(Gitlab::QA::Runtime::OmnibusConfigurations::Default.new.configuration.split("\n"))
      end

      context 'with exec commands' do
        let(:passed_args) { %w[EE --omnibus-config default,decomposition_multiple_db] }

        it 'adds an item to the list of omnibus gitlab exec commands to execute' do
          expect(
            Gitlab::QA::Runtime::Scenario.omnibus_exec_commands.flatten).to include(/gitlab-rake db:schema:load:ci/
                                                                                   )
        end
      end
    end

    context 'with --seed-db option' do
      let(:options) { Gitlab::QA::Runtime::Scenario.seed_db }

      before do
        described_class.run(scenario_arg + passed_args)
      end

      context 'with specified seed scripts' do
        let(:passed_args) { %w[EE --seed-db file1,file2*.rb] }

        it 'returns correct file search patterns' do
          expect(options).to eq ['file1', 'file2*.rb']
        end
      end
    end
  end

  describe '.remove_gitlab_qa_args' do
    before do
      described_class.run(scenario_arg + passed_args)
    end

    context 'when specifying options with no arguments' do
      let(:passed_args) { %w[EE --no-teardown] }

      it 'removes options that accept no arguments' do
        expect(described_class.remove_gitlab_qa_args(passed_args)).to eq(%w[EE])
      end
    end

    context 'when specifying options with arguments' do
      let(:passed_args) { %w[EE --omnibus-config default --] }

      it 'removes options that accept arguments' do
        expect(described_class.remove_gitlab_qa_args(passed_args)).to eq(%w[EE --])
      end
    end
  end
end
