# frozen_string_literal: true

require 'spec_helper'

RSpec.describe VulnerabilityPresenter do
  let_it_be(:project) { create(:project) }
  let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
  let_it_be(:sast_scan) do
    { type: 'sast', status: 'success', start_time: 'placeholder', end_time: 'placeholder' }
  end

  let_it_be(:finding) { create(:vulnerabilities_finding, :with_secret_detection, pipelines: [pipeline], project: project, description: 'Finding Description') }
  let_it_be(:finding2) { create(:vulnerabilities_finding, :with_secret_detection, scan: sast_scan) }

  subject  { described_class.new(finding.vulnerability) }

  describe '#scanner' do
    it 'returns the scanner for a finding' do
      expect(subject.scanner).to eql(finding.scanner)
    end

    it 'returns empty hash if scanner is missing for a vulnerabilities_finding' do
      finding2.scanner = nil

      expect(described_class.new(finding2.vulnerability).scanner).to eql({})
    end
  end

  describe '#scan' do
    it 'returns the scan for a finding' do
      expect(described_class.new(finding2.vulnerability).scan).to eql(finding2.scan)
    end

    it 'returns empty hash if scan is missing for a vulnerabilities_finding' do
      finding2.scan = nil

      expect(described_class.new(finding2.vulnerability).scan).to eql({})
    end
  end

  describe '#remediations' do
    let(:finding) { create(:vulnerabilities_finding, :with_secret_detection, :with_remediation, pipelines: [pipeline], project: project) }

    it 'returns remediations' do
      expect(subject.remediations.count).to be(1)
    end
  end

  describe '#location_link_with_raw_path' do
    it 'returns the location link in raw format' do
      path = subject.location_link_with_raw_path

      expect(path).to include('raw')
      expect(path).to include(finding.file)
      expect(path).to include("#L#{finding.location['start_line']}")
    end
  end

  describe '#location_link' do
    it 'returns the location link in blob format' do
      path = subject.location_link

      expect(path).to include('blob')
      expect(path).to include(finding.file)
      expect(path).to include("#L#{finding.location['start_line']}")
    end
  end

  describe '#blob_path' do
    it 'returns the path in blob format' do
      path = subject.blob_path

      expect(path).to include('blob')
      expect(path).to include(finding.file)
      expect(path).to include("#L#{finding.location['start_line']}")
    end

    it 'returns nil if file is missing in the finding' do
      allow(subject).to receive(:file).and_return(nil)

      expect(subject.blob_path).to be(nil)
    end
  end

  describe '#raw_path' do
    it 'returns the path in raw format' do
      path = subject.raw_path

      expect(path).to include('raw')
      expect(path).to include(finding.file)
      expect(path).to include("#L#{finding.location['start_line']}")
    end

    it 'returns nil if file is missing in the finding' do
      allow(subject).to receive(:file).and_return(nil)

      expect(subject.raw_path).to be(nil)
    end
  end

  describe '#jira_issue_description' do
    let(:expected_jira_issue_description) do
      <<-JIRA.strip_heredoc
        Issue created from vulnerability [#{finding.vulnerability.id}|http://localhost/#{project.full_path}/-/security/vulnerabilities/#{finding.vulnerability.id}]

        h3. Description:

        Description of #{finding.vulnerability.title}

        * Severity: high
        * Confidence: medium
        * Location: [aws-key.py:5|http://localhost/#{project.full_path}/-/blob/b83d6e391c22777fca1ed3012fce84f633d7fed0/aws-key.py#L5]





        h3. Scanner:

        * Name: Find Security Bugs
      JIRA
    end

    it 'returns the jira description in string format' do
      jira_issue_description = subject.jira_issue_description

      expect(jira_issue_description).to eq(expected_jira_issue_description)
    end
  end

  describe '#description' do
    let(:vulnerability) { finding.vulnerability }

    context 'when the vulnerability description field is populated' do
      it 'returns the description for the vulnerability' do
        expect(subject.description).to eq(vulnerability.description)
      end
    end

    context 'when the vulnerability description field is empty' do
      before do
        vulnerability.description = nil
        vulnerability.save!
      end

      it 'returns the description for the vulnerability finding' do
        expect(subject.description).not_to eq(vulnerability.description)
        expect(subject.description).to eq(finding.description)
      end
    end
  end
end
