# frozen_string_literal: true

require 'spec_helper'

describe ReleaseTools::Security::RelatedIssuesFinder do
  subject(:finder) { described_class.new(security_issue) }

  let(:client) { stub_const('ReleaseTools::GitlabClient', spy) }

  let(:raw_security_issue) do
    create(:issue, iid: 1, project_id: 1, references: { full: 'gitlab-org/security/gitlab#1' })
  end

  let(:security_issue) do
    ReleaseTools::Security::ImplementationIssue.new(raw_security_issue, [])
  end

  let(:canonical_issue) do
    create(:issue, iid: 2, project_id: 2, references: { full: 'gitlab-org/gitlab#1' })
  end

  let(:cve_issue) do
    create(:issue, references: { full: 'gitlab-org/cves#1' })
  end

  describe '#cves_issue' do
    before do
      allow(finder)
        .to receive(:canonical_issue)
        .and_return(canonical_issue)
    end

    context 'when the security issue has a cve issue associated' do
      before do
        allow(client)
          .to receive(:issue_links)
          .with(security_issue.project_id, security_issue.iid)
          .and_return([cve_issue])
      end

      it 'returns the cve issue' do
        expect(finder.cves_issue).to eq(cve_issue)
      end
    end

    context 'when the canonical issue has a cve issue associated' do
      before do
        allow(client)
          .to receive(:issue_links)
          .with(security_issue.project_id, security_issue.iid)
          .and_return([])

        allow(client)
          .to receive(:issue_links)
          .with(canonical_issue.project_id, canonical_issue.iid)
          .and_return([cve_issue])
      end

      it 'returns the cve issue' do
        expect(finder.cves_issue).to eq(cve_issue)
      end
    end

    context 'when there is no cve issue associated' do
      before do
        allow(client)
          .to receive(:issue_links)
          .and_return([])
      end

      it 'returns nothing' do
        expect(finder.cves_issue).to be_nil
      end
    end

    context 'when there is no canonical issue' do
      let(:canonical_issue) { nil }

      before do
        allow(client)
          .to receive(:issue_links)
          .with(security_issue.project_id, security_issue.iid)
          .and_return([cve_issue])
      end

      it 'returns the cve issue associated to the security issue' do
        expect(finder.cves_issue).to eq(cve_issue)
      end

      context 'with no cve issue associated' do
        before do
          allow(client)
          .to receive(:issue_links)
          .and_return([])
        end

        it 'returns nothing' do
          expect(finder.cves_issue).to be_nil
        end
      end
    end
  end

  describe '#canonical_issue' do
    it 'returns the canonical issue associated' do
      allow(client)
        .to receive(:issue_links)
        .with(security_issue.project_id, security_issue.iid)
        .and_return([canonical_issue, cve_issue])

      expect(finder.canonical_issue).to eq(canonical_issue)
    end

    context 'with no canonical issue' do
      it 'returns nothing' do
        allow(client)
          .to receive(:issue_links)
          .and_return([])

        expect(finder.canonical_issue).to be_nil
      end
    end
  end
end
