Commit a2639ccd authored by Etienne Baqué's avatar Etienne Baqué

Merge branch 'philipcunningham-validation-failed-alert-322609' into 'master'

Add status filter to project.dastSiteValidations

See merge request gitlab-org/gitlab!70126
parents 250215a6 dd35063d
......@@ -3,4 +3,3 @@ filenames:
- ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/api_fuzzing_ci_configuration.query.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/create_api_fuzzing_configuration.mutation.graphql
- ee/app/assets/javascripts/security_configuration/dast_profiles/graphql/dast_failed_site_validations.query.graphql
......@@ -12547,6 +12547,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdastsitevalidationsnormalizedtargeturls"></a>`normalizedTargetUrls` | [`[String!]`](#string) | Normalized URL of the target to be scanned. |
| <a id="projectdastsitevalidationsstatus"></a>`status` | [`DastSiteValidationStatusEnum`](#dastsitevalidationstatusenum) | Status of the site validation. Ignored if `dast_failed_site_validations` feature flag is disabled. |
##### `Project.environment`
......@@ -15397,6 +15398,15 @@ Unit for the duration of Dast Profile Cadence.
| <a id="dastsiteprofilevalidationstatusenumpassed_validation"></a>`PASSED_VALIDATION` | Site validation process finished successfully. |
| <a id="dastsiteprofilevalidationstatusenumpending_validation"></a>`PENDING_VALIDATION` | Site validation process has not started. |
### `DastSiteValidationStatusEnum`
| Value | Description |
| ----- | ----------- |
| <a id="dastsitevalidationstatusenumfailed_validation"></a>`FAILED_VALIDATION` | Site validation process finished but failed. |
| <a id="dastsitevalidationstatusenuminprogress_validation"></a>`INPROGRESS_VALIDATION` | Site validation process is in progress. |
| <a id="dastsitevalidationstatusenumpassed_validation"></a>`PASSED_VALIDATION` | Site validation process finished successfully. |
| <a id="dastsitevalidationstatusenumpending_validation"></a>`PENDING_VALIDATION` | Site validation process has not started. |
### `DastSiteValidationStrategyEnum`
| Value | Description |
......
query DastFailedSiteValidations($fullPath: ID!) {
project(fullPath: $fullPath) {
validations: dastSiteValidations(normalizedTargetUrls: $urls, status: "FAILED_VALIDATION") {
validations: dastSiteValidations(status: FAILED_VALIDATION) {
nodes {
normalizedTargetUrl
}
......
......@@ -10,9 +10,15 @@ module Resolvers
required: false,
description: 'Normalized URL of the target to be scanned.'
argument :status, Types::DastSiteValidationStatusEnum,
required: false,
description: 'Status of the site validation. Ignored if `dast_failed_site_validations` feature flag is disabled.'
def resolve(**args)
args.delete(:status) unless Feature.enabled?(:dast_failed_site_validations, project, default_enabled: :yaml)
DastSiteValidationsFinder
.new(project_id: project.id, url_base: args[:normalized_target_urls], most_recent: true)
.new(project_id: project.id, url_base: args[:normalized_target_urls], state: args[:status], most_recent: true)
.execute
end
end
......
# frozen_string_literal: true
module Types
class DastSiteValidationStatusEnum < BaseEnum
value 'PENDING_VALIDATION', value: 'pending', description: 'Site validation process has not started.'
value 'INPROGRESS_VALIDATION', value: 'inprogress', description: 'Site validation process is in progress.'
value 'PASSED_VALIDATION', value: 'passed', description: 'Site validation process finished successfully.'
value 'FAILED_VALIDATION', value: 'failed', description: 'Site validation process finished but failed.'
end
end
......@@ -9,11 +9,13 @@ RSpec.describe Resolvers::DastSiteValidationResolver do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:dast_site_token1) { create(:dast_site_token, project: project, url: target_url) }
let_it_be(:dast_site_validation1) { create(:dast_site_validation, dast_site_token: dast_site_token1) }
let_it_be(:dast_site_validation1) { create(:dast_site_validation, dast_site_token: dast_site_token1, state: :pending) }
let_it_be(:dast_site_token2) { create(:dast_site_token, project: project, url: generate(:url)) }
let_it_be(:dast_site_validation2) { create(:dast_site_validation, dast_site_token: dast_site_token2) }
let_it_be(:dast_site_validation2) { create(:dast_site_validation, dast_site_token: dast_site_token2, state: :inprogress) }
let_it_be(:dast_site_token3) { create(:dast_site_token, project: project, url: generate(:url)) }
let_it_be(:dast_site_validation3) { create(:dast_site_validation, dast_site_token: dast_site_token3) }
let_it_be(:dast_site_validation3) { create(:dast_site_validation, dast_site_token: dast_site_token3, state: :passed) }
let_it_be(:dast_site_token4) { create(:dast_site_token, project: project, url: generate(:url)) }
let_it_be(:dast_site_validation4) { create(:dast_site_validation, dast_site_token: dast_site_token4, state: :failed) }
before do
project.add_maintainer(current_user)
......@@ -24,12 +26,18 @@ RSpec.describe Resolvers::DastSiteValidationResolver do
expect(described_class).to have_nullable_graphql_type(Types::DastSiteValidationType.connection_type)
end
shared_examples 'there is no filtering' do
it { is_expected.to contain_exactly(dast_site_validation4, dast_site_validation3, dast_site_validation2, dast_site_validation1) }
end
context 'when resolving multiple DAST site validations' do
subject { dast_site_validations(**args) }
let(:args) { {} }
context 'when there is no filtering' do
let(:args) { {} }
it { is_expected.to contain_exactly(dast_site_validation3, dast_site_validation2, dast_site_validation1) }
it_behaves_like 'there is no filtering'
end
context 'when multiple normalized_target_urls are specified' do
let(:args) { { normalized_target_urls: [dast_site_validation1.url_base, dast_site_validation3.url_base] } }
......@@ -48,6 +56,44 @@ RSpec.describe Resolvers::DastSiteValidationResolver do
it { is_expected.to be_empty }
end
context 'when status is specified' do
let(:args) { { status: Types::DastSiteValidationStatusEnum.values.fetch(status).value } }
context 'when filtering by pending' do
let(:status) { 'PENDING_VALIDATION' }
it { is_expected.to contain_exactly(dast_site_validation1) }
end
context 'when filtering by in progress' do
let(:status) { 'INPROGRESS_VALIDATION' }
it { is_expected.to contain_exactly(dast_site_validation2) }
end
context 'when filtering by passed' do
let(:status) { 'PASSED_VALIDATION' }
it { is_expected.to contain_exactly(dast_site_validation3) }
end
context 'when filtering by failed' do
let(:status) { 'FAILED_VALIDATION' }
it { is_expected.to contain_exactly(dast_site_validation4) }
end
context 'when dast_failed_site_validations feature flag is disabled' do
let(:status) { 'PASSED_VALIDATION' }
before do
stub_feature_flags(dast_failed_site_validations: false)
end
it_behaves_like 'there is no filtering'
end
end
end
private
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['DastSiteValidation'] do
let_it_be(:dast_site_validation) { create(:dast_site_validation) }
let_it_be(:dast_site_validation) { create(:dast_site_validation, state: :passed) }
let_it_be(:project) { dast_site_validation.dast_site_token.project }
let_it_be(:user) { create(:user) }
let_it_be(:fields) { %i[id status normalizedTargetUrl] }
......@@ -16,7 +16,8 @@ RSpec.describe GitlabSchema.types['DastSiteValidation'] do
},
variables: {
fullPath: project.full_path,
normalized_target_urls: [dast_site_validation.url_base]
normalized_target_urls: [dast_site_validation.url_base],
status: Types::DastSiteValidationStatusEnum.values.fetch('PASSED_VALIDATION').value
}
).as_json
end
......@@ -50,7 +51,7 @@ RSpec.describe GitlabSchema.types['DastSiteValidation'] do
describe 'status field' do
subject { response.dig('data', 'project', 'dastSiteValidations', 'edges', 0, 'node', 'status') }
it { is_expected.to eq('PENDING_VALIDATION') }
it { is_expected.to eq('PASSED_VALIDATION') }
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment