# frozen_string_literal: true

require 'spec_helper'
require_migration!

RSpec.describe SetMissingTraversalIdsForVulnerabilityReads, feature_category: :vulnerability_management do
  let(:vulnerability_reads) { table(:vulnerability_reads) }
  let(:vulnerability_scanners) { table(:vulnerability_scanners) }
  let(:identifiers) { table(:vulnerability_identifiers) }
  let(:vulnerabilities) { table(:vulnerabilities) }
  let(:findings) { table(:vulnerability_occurrences) }
  let(:namespaces) { table(:namespaces) }
  let(:projects) { table(:projects) }
  let(:users) { table(:users) }

  let(:user) { users.create!(name: 'John Doe', email: 'test@example.com', projects_limit: 5) }

  let(:namespace_1) { namespaces.create!(name: 'Namespace 1', path: 'namespace-1', traversal_ids: [1]) }
  let(:namespace_2) { namespaces.create!(name: 'Namespace 2', path: 'namespace-2', traversal_ids: [2]) }

  let(:scanner) { vulnerability_scanners.create!(project_id: project_1.id, external_id: 'gitlab', name: 'GitLab') }

  let(:project_1) do
    projects.create!(
      namespace_id: namespace_1.id,
      project_namespace_id: namespace_1.id,
      name: 'Project 1',
      path: 'project-1'
    )
  end

  let(:project_2) do
    projects.create!(
      namespace_id: namespace_2.id,
      project_namespace_id: namespace_2.id,
      name: 'Project 2',
      path: 'project-2'
    )
  end

  let(:identifier) do
    identifiers.create!(
      project_id: project_1.id,
      fingerprint: 'foo',
      external_type: 'cve',
      external_id: '1234',
      name: 'cve-1234'
    )
  end

  let(:finding_1) do
    findings.create!(
      project_id: project_1.id,
      primary_identifier_id: identifier.id,
      scanner_id: scanner.id,
      severity: 5,
      confidence: 5,
      report_type: 1,
      uuid: SecureRandom.uuid,
      project_fingerprint: '',
      location_fingerprint: '',
      metadata_version: '1',
      raw_metadata: '{}',
      name: 'finding 1'
    )
  end

  let(:finding_2) do
    findings.create!(
      project_id: project_1.id,
      primary_identifier_id: identifier.id,
      scanner_id: scanner.id,
      severity: 5,
      confidence: 5,
      report_type: 1,
      uuid: SecureRandom.uuid,
      project_fingerprint: '',
      location_fingerprint: '',
      metadata_version: '1',
      raw_metadata: '{}',
      name: 'finding 2'
    )
  end

  let(:vulnerability_1) do
    vulnerabilities.create!(
      project_id: project_1.id,
      finding_id: finding_1.id,
      author_id: user.id,
      title: "Vulnerability 1",
      severity: 5,
      confidence: 5,
      report_type: 1
    )
  end

  let(:vulnerability_2) do
    vulnerabilities.create!(
      project_id: project_2.id,
      finding_id: finding_2.id,
      author_id: user.id,
      title: "Vulnerability 2",
      severity: 5,
      confidence: 5,
      report_type: 1
    )
  end

  let!(:vulnerability_read_1) do
    vulnerability_reads.create!(
      project_id: project_1.id,
      namespace_id: namespace_1.id,
      vulnerability_id: vulnerability_1.id,
      scanner_id: scanner.id,
      uuid: SecureRandom.uuid,
      severity: 5,
      report_type: 1,
      state: 1,
      traversal_ids: [0]
    )
  end

  let!(:vulnerability_read_2) do
    vulnerability_reads.create!(
      project_id: project_2.id,
      namespace_id: namespace_2.id,
      vulnerability_id: vulnerability_2.id,
      scanner_id: scanner.id,
      uuid: SecureRandom.uuid,
      severity: 5,
      report_type: 1,
      state: 1
    )
  end

  describe "#up" do
    before do
      allow(Gitlab).to receive(:com?).and_return(gitlab_com?)
    end

    context 'when is not running for GitLab.com' do
      let(:gitlab_com?) { false }

      it 'does not update the records' do
        expect { migrate! }.not_to change { vulnerability_read_2.reload.traversal_ids }
      end
    end

    context 'when running for GitLab.com' do
      let(:gitlab_com?) { true }

      it 'sets the traversal_ids for missing records' do
        expect { migrate! }.to change { vulnerability_read_2.reload.traversal_ids }.to(namespace_2.traversal_ids)
                           .and not_change { vulnerability_read_1.reload.traversal_ids }
      end
    end
  end
end
