# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Vulnerabilities::StarboardVulnerabilityCreateService do
  let(:agent) { create(:cluster_agent) }
  let(:project) { agent.project }
  let(:user) { agent.created_by_user }
  let(:params) do
    {
      vulnerability: {
        name: 'CVE-123-4567 in libc',
        message: 'Vulnerability message',
        description: 'Vulnerability description',
        severity: 'high',
        confidence: 'unknown',
        location: {
          kubernetes_resource: {
            namespace: 'production',
            kind: 'deployment',
            name: 'nginx',
            container: 'nginx'
          }
        },
        identifiers: [
          {
            type: 'cve',
            name: 'CVE-123-4567',
            value: 'CVE-123-4567'
          }
        ]
      },
      scanner: {
        id: 'starboard_trivy',
        name: 'Trivy (via Starboard Operator)',
        vendor: {
          name: 'GitLab'
        }
      }
    }
  end

  subject { described_class.new(agent, params: params).execute }

  context 'with authorized user' do
    before do
      project.add_developer(user)
    end

    context 'with feature enabled' do
      let(:vulnerability) { subject.payload[:vulnerability] }

      before do
        stub_licensed_features(security_dashboard: true)
      end

      it 'creates Vulnerability' do
        expect { subject }.to change(Vulnerability, :count).by(1)
      end

      it 'has correct data' do
        expect(vulnerability.report_type).to eq("cluster_image_scanning")
        expect(vulnerability.title).to eq(params.dig(:vulnerability, :name))

        finding = vulnerability.finding
        expect(finding.message).to eq(params.dig(:vulnerability, :message))
        expect(finding.description).to eq(params.dig(:vulnerability, :description))
        expect(finding.severity).to eq(params.dig(:vulnerability, :severity))
        expect(finding.confidence).to eq(params.dig(:vulnerability, :confidence))

        scanner = finding.scanner
        expect(scanner.external_id).to eq(params.dig(:scanner, :id))
        expect(scanner.name).to eq(params.dig(:scanner, :name))
        expect(scanner.vendor).to eq(params.dig(:scanner, :vendor, :name))
      end
    end

    context 'with feature disabled' do
      before do
        stub_licensed_features(security_dashboard: false)
      end

      it 'raises AccessDeniedError' do
        expect { subject }.to raise_error(Gitlab::Access::AccessDeniedError)
      end
    end

    context 'with unauthorized user' do
      before do
        project.add_reporter(user)
      end

      it 'raises AccessDeniedError' do
        expect { subject }.to raise_error(Gitlab::Access::AccessDeniedError)
      end
    end
  end
end
