# frozen_string_literal: true

require 'spec_helper'

describe ReleaseTools::UpdatePaths::DynamicPipeline do
  describe '#generate' do
    let(:base_expected_yaml) do
      {
        'image' => 'registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bookworm-ruby-3.2.5:docker-24.0.5',
        'services' => ['docker:${DOCKER_VERSION}-dind'],
        'variables' => {
          'DOCKER_VERSION' => '24.0.5',
          'DOCKER_HOST' => 'tcp://docker:2376',
          'DOCKER_TLS_VERIFY' => '1',
          'DOCKER_TLS_CERTDIR' => '/certs',
          'DOCKER_CERT_PATH' => '/certs/client',
          'GITLAB_QA_DEV_ACCESS_TOKEN' => '$RELEASE_BOT_DEV_TOKEN',
          'QA_GENERATE_ALLURE_REPORT' => 'true',
          'QA_CAN_TEST_PRAEFECT' => 'false',
          'QA_INTERCEPT_REQUESTS' => 'true',
          'QA_ARTIFACTS_DIR' => '$CI_PROJECT_DIR',
          'QA_ALLOW_LOCAL_REQUESTS' => 'true',
          'GITLAB_LICENSE_MODE' => 'test',
          'FF_NETWORK_PER_BUILD' => 'true'
        },
        'tags' => %w[docker],
        'extends' => [
          '.common-ci-tokens'
        ],
        'artifacts' => {
          'when' => 'always',
          'expire_in' => '30d',
          'paths' => ['gitlab-qa-run-*'],
          'reports' => {
            'junit' => 'gitlab-qa-run-*/**/rspec-*.xml'
          }
        }
      }
    end

    def build_expected_yaml(stage_name, job_name, version, previous_version, update_type)
      source_version = update_type == 'minor' ? version : previous_version
      {
        'stages' => [stage_name, "finish_notification"],
        job_name => base_expected_yaml.merge(
          'stage' => stage_name,
          'script' => [
            'git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/gitlab-org/gitlab-qa.git',
            'cd gitlab-qa',
            'bundle install',
            "bundle exec gitlab-qa Test::Omnibus::UpdateFromPrevious dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ee:#{version}-ee.0 #{source_version} #{update_type} -- --tag health_check"
          ]
        ),
        'notification_job_success' => {
          'image' => "$CI_REGISTRY_IMAGE/base:$CI_DEFAULT_BRANCH",
          'stage' => 'finish_notification',
          'script' => [
            "source scripts/setup_ssh.sh",
            "source scripts/setup_git.sh",
            "bundle exec rake \"release:update_paths:finish_notification[#{previous_version},#{version},success]\""
          ],
          'extends' => [
            '.with-bundle',
            '.common-ci-tokens'
          ],
          'when' => 'on_success'
        },
        'notification_job_failed' => {
          'image' => "$CI_REGISTRY_IMAGE/base:$CI_DEFAULT_BRANCH",
          'stage' => 'finish_notification',
          'script' => [
            "source scripts/setup_ssh.sh",
            "source scripts/setup_git.sh",
            "bundle exec rake \"release:update_paths:finish_notification[#{previous_version},#{version},failed]\""
          ],
          'extends' => [
            '.with-bundle',
            '.common-ci-tokens'
          ],
          'when' => 'on_failure'
        }
      }
    end

    context 'when generating for a patch-to-patch version' do
      let(:version) { '1.2.3' }
      let(:previous_version) { '1.2.2' }

      before do
        allow(ReleaseTools::GitlabReleasesGemClient)
          .to receive_messages(latest_patch_for_version: previous_version)
      end

      it 'generates YAML output' do
        job_name = "#{previous_version.tr('.', '-')}-to-#{version.tr('.', '-')}"
        expected_yaml = build_expected_yaml('patch-to-patch', job_name, version, previous_version, 'patch')

        publish_jobs = described_class.new(version)
        expect(YAML.safe_load(publish_jobs.generate)).to eq(expected_yaml)
      end
    end

    context 'when generating for a patch-to-monthly version' do
      let(:version) { '1.2.0' }
      let(:previous_version) { '1.1.5' }

      before do
        allow(ReleaseTools::GitlabReleasesGemClient)
          .to receive_messages(latest_patch_for_version: previous_version)
      end

      it 'generates YAML output' do
        job_name = "#{previous_version.tr('.', '-')}-to-#{version.tr('.', '-')}"
        # When updating from a patch version to a monthly version, we use a different scenario "minor" where the
        # previous version is also the same as the target version
        expected_yaml = build_expected_yaml('patch-to-monthly', job_name, version, previous_version, 'minor')

        publish_jobs = described_class.new(version)
        expect(YAML.safe_load(publish_jobs.generate)).to eq(expected_yaml)
      end
    end
  end
end
