# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Resolvers::VulnerabilitySeveritiesCountResolver do
  include GraphqlHelpers

  describe '#resolve' do
    subject { resolve(described_class, obj: vulnerable, args: filters, ctx: { current_user: current_user }) }

    let_it_be(:project) { create(:project) }
    let_it_be(:user) { create(:user, security_dashboard_projects: [project]) }

    let_it_be(:low_vulnerability) do
      create(:vulnerability, :with_findings, :detected, :low, :dast, project: project)
    end

    let_it_be(:critical_vulnerability) do
      create(:vulnerability, :with_findings, :detected, :critical, :sast, project: project)
    end

    let_it_be(:high_vulnerability) do
      create(:vulnerability, :with_findings, :dismissed, :high, :container_scanning, project: project)
    end

    let(:current_user) { user }
    let(:filters) { {} }
    let(:vulnerable) { project }

    context 'when the user does not have access' do
      it 'is redacted' do
        is_expected.to be_nil
      end
    end

    context 'when the user has access' do
      before do
        stub_licensed_features(security_dashboard: true)
        project.add_developer(current_user)
      end

      context 'when given severities' do
        let(:filters) { { severity: ['low'] } }

        it 'only returns count for low severity vulnerability' do
          is_expected.to eq('low' => 1)
        end
      end

      context 'when given states' do
        let(:filters) { { state: ['dismissed'] } }

        it 'only returns count for high severity vulnerability' do
          is_expected.to eq('high' => 1)
        end
      end

      context 'when given scanner' do
        let(:filters) { { scanner: [high_vulnerability.finding_scanner_external_id] } }

        it 'only returns count for high severity vulnerability' do
          is_expected.to eq('high' => 1)
        end
      end

      context 'when given report types' do
        let(:filters) { { report_type: %i[dast sast] } }

        it 'only returns count for vulnerabilities of the given report types' do
          is_expected.to eq('critical' => 1, 'low' => 1)
        end
      end

      context 'when resolving vulnerabilities for a project' do
        it "returns the project's vulnerabilities" do
          is_expected.to eq('critical' => 1, 'high' => 1, 'low' => 1)
        end
      end
    end

    context 'when resolving vulnerabilities for an instance security dashboard' do
      before do
        stub_licensed_features(security_dashboard: true)
        project.add_developer(user)
      end

      let(:vulnerable) { InstanceSecurityDashboard.new(current_user) }

      context 'when there is a current user' do
        it "returns vulnerabilities for all projects on the current user's instance security dashboard" do
          is_expected.to eq('critical' => 1, 'high' => 1, 'low' => 1)
        end
      end

      context 'without a current user' do
        let(:current_user) { nil }

        it 'returns no vulnerabilities' do
          is_expected.to be_blank
        end
      end
    end
  end
end
