Commit e1d3bc04 authored by Philip Cunningham's avatar Philip Cunningham Committed by Bob Van Landuyt

Remove DAST site validation feature flags

parent 31462b14
---
name: dast_meta_tag_validation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67945
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337711
milestone: '14.2'
type: development
group: group::dynamic analysis
default_enabled: true
---
name: dast_runner_site_validation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61649
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331082
milestone: '14.0'
type: development
group: group::dynamic analysis
default_enabled: true
...@@ -1049,11 +1049,7 @@ When an API site type is selected, a [host override](#host-override) is used to ...@@ -1049,11 +1049,7 @@ When an API site type is selected, a [host override](#host-override) is used to
#### Site profile validation #### Site profile validation
> - Site profile validation [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233020) in GitLab 13.8. > - Site profile validation [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233020) in GitLab 13.8.
> - Meta tag validation [enabled on GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/6460) in GitLab 14.2 and is ready for production use. > - Meta tag validation [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6460) in GitLab 14.2.
> - Meta tag validation [enabled with `dast_meta_tag_validation flag` flag](https://gitlab.com/gitlab-org/gitlab/-/issues/337711) for self-managed GitLab in GitLab 14.2 and is ready for production use.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the `dast_meta_tag_validation` flag](../../../administration/feature_flags.md). On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
Site profile validation reduces the risk of running an active scan against the wrong website. A site Site profile validation reduces the risk of running an active scan against the wrong website. A site
must be validated before an active scan can run against it. The site validation methods are as must be validated before an active scan can run against it. The site validation methods are as
......
...@@ -18,7 +18,6 @@ import download from '~/lib/utils/downloader'; ...@@ -18,7 +18,6 @@ import download from '~/lib/utils/downloader';
import { cleanLeadingSeparator, joinPaths, stripPathTail } from '~/lib/utils/url_utility'; import { cleanLeadingSeparator, joinPaths, stripPathTail } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue'; import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { import {
DAST_SITE_VALIDATION_MODAL_ID, DAST_SITE_VALIDATION_MODAL_ID,
DAST_SITE_VALIDATION_HTTP_HEADER_KEY, DAST_SITE_VALIDATION_HTTP_HEADER_KEY,
...@@ -47,7 +46,6 @@ export default { ...@@ -47,7 +46,6 @@ export default {
GlTruncate, GlTruncate,
GlLink, GlLink,
}, },
mixins: [glFeatureFlagMixin()],
props: { props: {
fullPath: { fullPath: {
type: String, type: String,
...@@ -91,11 +89,7 @@ export default { ...@@ -91,11 +89,7 @@ export default {
}; };
}, },
validationMethodOptions() { validationMethodOptions() {
const options = Object.values(DAST_SITE_VALIDATION_METHODS); return Object.values(DAST_SITE_VALIDATION_METHODS);
if (!this.glFeatures.dastMetaTagValidation) {
return options.filter(({ value }) => value !== DAST_SITE_VALIDATION_METHOD_META_TAG);
}
return options;
}, },
urlObject() { urlObject() {
try { try {
......
...@@ -8,7 +8,6 @@ module Projects ...@@ -8,7 +8,6 @@ module Projects
before_action do before_action do
authorize_read_on_demand_scans! authorize_read_on_demand_scans!
push_frontend_feature_flag(:dast_failed_site_validations, @project, default_enabled: :yaml) push_frontend_feature_flag(:dast_failed_site_validations, @project, default_enabled: :yaml)
push_frontend_feature_flag(:dast_meta_tag_validation, @project, default_enabled: :yaml)
end end
feature_category :dynamic_application_security_testing feature_category :dynamic_application_security_testing
......
...@@ -6,8 +6,7 @@ class DastSite < ApplicationRecord ...@@ -6,8 +6,7 @@ class DastSite < ApplicationRecord
has_many :dast_site_profiles has_many :dast_site_profiles
validates :url, length: { maximum: 255 }, uniqueness: { scope: :project_id } validates :url, length: { maximum: 255 }, uniqueness: { scope: :project_id }
validates :url, addressable_url: true, if: :runner_validation_enabled? validates :url, addressable_url: true
validates :url, public_url: true, unless: :runner_validation_enabled?
validates :project_id, presence: true validates :project_id, presence: true
validate :dast_site_validation_project_id_fk validate :dast_site_validation_project_id_fk
...@@ -21,8 +20,4 @@ class DastSite < ApplicationRecord ...@@ -21,8 +20,4 @@ class DastSite < ApplicationRecord
errors.add(:project_id, 'does not match dast_site_validation.project') errors.add(:project_id, 'does not match dast_site_validation.project')
end end
end end
def runner_validation_enabled?
::Feature.enabled?(:dast_runner_site_validation, project, default_enabled: :yaml)
end
end end
...@@ -9,8 +9,6 @@ class DastSiteValidation < ApplicationRecord ...@@ -9,8 +9,6 @@ class DastSiteValidation < ApplicationRecord
validates :dast_site_token_id, presence: true validates :dast_site_token_id, presence: true
validates :validation_strategy, presence: true validates :validation_strategy, presence: true
validate :meta_tag_validation_must_happen_on_runner, if: :meta_tag?
scope :by_project_id, -> (project_id) do scope :by_project_id, -> (project_id) do
joins(:dast_site_token).where(dast_site_tokens: { project_id: project_id }) joins(:dast_site_token).where(dast_site_tokens: { project_id: project_id })
end end
...@@ -81,11 +79,4 @@ class DastSiteValidation < ApplicationRecord ...@@ -81,11 +79,4 @@ class DastSiteValidation < ApplicationRecord
def set_normalized_url_base def set_normalized_url_base
self.url_base = self.class.get_normalized_url_base(dast_site_token.url) self.url_base = self.class.get_normalized_url_base(dast_site_token.url)
end end
def meta_tag_validation_must_happen_on_runner
return if ::Feature.enabled?(:dast_runner_site_validation, project, default_enabled: :yaml) &&
::Feature.enabled?(:dast_meta_tag_validation, project, default_enabled: :yaml)
errors.add(:base, 'Meta tag validation is not enabled')
end
end end
...@@ -22,8 +22,7 @@ module AppSec ...@@ -22,8 +22,7 @@ module AppSec
private private
def allowed? def allowed?
can?(current_user, :create_on_demand_dast_scan, project) && can?(current_user, :create_on_demand_dast_scan, project)
::Feature.enabled?(:dast_runner_site_validation, project, default_enabled: :yaml)
end end
def dast_site_validation def dast_site_validation
......
...@@ -12,7 +12,7 @@ module DastSiteValidations ...@@ -12,7 +12,7 @@ module DastSiteValidations
associate_dast_site!(dast_site_validation) associate_dast_site!(dast_site_validation)
perform_async_validation(dast_site_validation) perform_runner_validation(dast_site_validation)
rescue ActiveRecord::RecordInvalid => err rescue ActiveRecord::RecordInvalid => err
ServiceResponse.error(message: err.record.errors.full_messages) ServiceResponse.error(message: err.record.errors.full_messages)
rescue KeyError => err rescue KeyError => err
...@@ -66,29 +66,7 @@ module DastSiteValidations ...@@ -66,29 +66,7 @@ module DastSiteValidations
) )
end end
def perform_async_validation(dast_site_validation) def perform_runner_validation(dast_site_validation)
if Feature.enabled?(:dast_runner_site_validation, dast_site_validation.project, default_enabled: :yaml)
runner_validation(dast_site_validation)
else
worker_validation(dast_site_validation)
end
end
def worker_validation(dast_site_validation)
jid = DastSiteValidationWorker.perform_async(dast_site_validation.id)
unless jid.present?
log_error(message: 'Unable to validate dast_site_validation', dast_site_validation_id: dast_site_validation.id)
dast_site_validation.fail_op
return ServiceResponse.error(message: 'Validation failed')
end
ServiceResponse.success(payload: dast_site_validation)
end
def runner_validation(dast_site_validation)
AppSec::Dast::SiteValidations::RunnerService.new( AppSec::Dast::SiteValidations::RunnerService.new(
project: dast_site_validation.project, project: dast_site_validation.project,
current_user: current_user, current_user: current_user,
......
# frozen_string_literal: true
module DastSiteValidations
class ValidateService < BaseContainerService
PermissionsError = Class.new(StandardError)
TokenNotFound = Class.new(StandardError)
def execute!
raise PermissionsError, 'Insufficient permissions' unless allowed?
return if dast_site_validation.passed?
if dast_site_validation.pending?
dast_site_validation.start
else
dast_site_validation.retry
end
response = make_http_request!
validate!(response)
end
private
def allowed?
container.feature_available?(:security_on_demand_scans)
end
def dast_site_validation
@dast_site_validation ||= params.fetch(:dast_site_validation)
end
def make_http_request!
Gitlab::HTTP.get(dast_site_validation.validation_url, use_read_total_timeout: true)
end
def token_found?(response)
token = dast_site_validation.dast_site_token.token
case dast_site_validation.validation_strategy
when 'text_file'
response.content_type == 'text/plain' && response.body.rstrip == token
when 'header'
response.headers[DastSiteValidation::HEADER] == token
else
false
end
end
def validate!(response)
raise TokenNotFound, 'Could not find token' unless token_found?(response)
dast_site_validation.pass
end
end
end
...@@ -14,18 +14,8 @@ class DastSiteValidationWorker ...@@ -14,18 +14,8 @@ class DastSiteValidationWorker
feature_category :dynamic_application_security_testing feature_category :dynamic_application_security_testing
tags :exclude_from_kubernetes tags :exclude_from_kubernetes
sidekiq_retries_exhausted do |job| def perform(_dast_site_validation_id)
dast_site_validation = DastSiteValidation.find(job['args'][0]) # Scheduled for removal in %15.0
dast_site_validation.fail_op # Please see https://gitlab.com/gitlab-org/gitlab/-/issues/339088
end
def perform(dast_site_validation_id)
dast_site_validation = DastSiteValidation.find(dast_site_validation_id)
project = dast_site_validation.project
DastSiteValidations::ValidateService.new(
container: project,
params: { dast_site_validation: dast_site_validation }
).execute!
end end
end end
...@@ -15,9 +15,7 @@ module API ...@@ -15,9 +15,7 @@ module API
namespace :internal do namespace :internal do
namespace :dast do namespace :dast do
resource :site_validations do resource :site_validations do
desc 'Transitions a DAST site validation to a new state.' do desc 'Transitions a DAST site validation to a new state.'
detail 'This feature is gated by the :dast_runner_site_validation feature flag.'
end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
params do params do
requires :event, type: Symbol, values: %i[start fail_op retry pass], desc: 'The transition event.' requires :event, type: Symbol, values: %i[start fail_op retry pass], desc: 'The transition event.'
...@@ -25,10 +23,6 @@ module API ...@@ -25,10 +23,6 @@ module API
post ':id/transition' do post ':id/transition' do
validation = DastSiteValidation.find(params[:id]) validation = DastSiteValidation.find(params[:id])
unless Feature.enabled?(:dast_runner_site_validation, validation.project, default_enabled: :yaml)
render_api_error!('404 Feature flag disabled: :dast_runner_site_validation', 404)
end
authorize!(:create_on_demand_dast_scan, validation) authorize!(:create_on_demand_dast_scan, validation)
bad_request!('Project mismatch') unless current_authenticated_job.project == validation.project bad_request!('Project mismatch') unless current_authenticated_job.project == validation.project
......
...@@ -57,9 +57,6 @@ describe('DastSiteValidationModal', () => { ...@@ -57,9 +57,6 @@ describe('DastSiteValidationModal', () => {
static: true, static: true,
visible: true, visible: true,
}, },
provide: {
glFeatures: { dastMetaTagValidation: true },
},
}, },
mountOptions, mountOptions,
{ {
...@@ -324,22 +321,6 @@ describe('DastSiteValidationModal', () => { ...@@ -324,22 +321,6 @@ describe('DastSiteValidationModal', () => {
}); });
}); });
describe('with the dastMetaTagValidation feature flag disabled', () => {
beforeEach(() => {
createFullComponent({
provide: {
glFeatures: {
dastMetaTagValidation: false,
},
},
});
});
it('does not render the meta tag validation method', () => {
expect(findRadioInputForValidationMethod('meta tag')).toBe(null);
});
});
describe.each(validationMethods)('"%s" validation submission', (validationMethod) => { describe.each(validationMethods)('"%s" validation submission', (validationMethod) => {
beforeEach(async () => { beforeEach(async () => {
createFullComponent(); createFullComponent();
......
...@@ -29,7 +29,6 @@ RSpec.describe Mutations::DastSiteValidations::Create do ...@@ -29,7 +29,6 @@ RSpec.describe Mutations::DastSiteValidations::Create do
) )
end end
shared_examples 'a validation mutation' do
context 'when on demand scan feature is enabled' do context 'when on demand scan feature is enabled' do
context 'when the project does not exist' do context 'when the project does not exist' do
let(:full_path) { SecureRandom.hex } let(:full_path) { SecureRandom.hex }
...@@ -54,17 +53,4 @@ RSpec.describe Mutations::DastSiteValidations::Create do ...@@ -54,17 +53,4 @@ RSpec.describe Mutations::DastSiteValidations::Create do
end end
end end
end end
context 'worker validation' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it_behaves_like 'a validation mutation'
end
context 'runner validation' do
it_behaves_like 'a validation mutation'
end
end
end end
...@@ -38,23 +38,10 @@ RSpec.describe DastSite, type: :model do ...@@ -38,23 +38,10 @@ RSpec.describe DastSite, type: :model do
subject { build(:dast_site, project: project, url: 'http://127.0.0.1') } subject { build(:dast_site, project: project, url: 'http://127.0.0.1') }
context 'worker validation' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it 'is not valid', :aggregate_failures do
expect(subject).not_to be_valid
expect(subject.errors.full_messages).to include(message)
end
end
context 'runner validation' do
it 'is is valid', :aggregate_failures do it 'is is valid', :aggregate_failures do
expect(subject).to be_valid expect(subject).to be_valid
expect(subject.errors.full_messages).not_to include(message) expect(subject.errors.full_messages).not_to include(message)
end end
end end
end end
end
end end
...@@ -17,37 +17,6 @@ RSpec.describe DastSiteValidation, type: :model do ...@@ -17,37 +17,6 @@ RSpec.describe DastSiteValidation, type: :model do
describe 'validations' do describe 'validations' do
it { is_expected.to be_valid } it { is_expected.to be_valid }
it { is_expected.to validate_presence_of(:dast_site_token_id) } it { is_expected.to validate_presence_of(:dast_site_token_id) }
context 'when strategy is meta_tag' do
subject { build(:dast_site_validation, dast_site_token: dast_site_token, validation_strategy: :meta_tag) }
shared_examples 'meta tag validation is disabled' do
it 'is not valid', :aggregate_failures do
expect(subject).not_to be_valid
expect(subject.errors.full_messages).to include('Meta tag validation is not enabled')
end
end
context 'when dast_meta_tag_validation and dast_runner_site_validation are enabled' do
it { is_expected.to be_valid }
end
context 'when dast_meta_tag_validation is disabled' do
before do
stub_feature_flags(dast_meta_tag_validation: false)
end
it_behaves_like 'meta tag validation is disabled'
end
context 'when dast_runner_site_validation is disabled' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it_behaves_like 'meta tag validation is disabled'
end
end
end end
describe 'before_create' do describe 'before_create' do
......
...@@ -101,19 +101,6 @@ RSpec.describe API::Internal::AppSec::Dast::SiteValidations do ...@@ -101,19 +101,6 @@ RSpec.describe API::Internal::AppSec::Dast::SiteValidations do
end end
end end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it 'returns 404 and a contextual error message', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response).to eq('message' => '404 Feature flag disabled: :dast_runner_site_validation')
end
end
context 'when user has access to the site validation' do context 'when user has access to the site validation' do
context 'when the state transition is unknown' do context 'when the state transition is unknown' do
let(:event_param) { :unknown_transition } let(:event_param) { :unknown_transition }
......
...@@ -75,14 +75,6 @@ RSpec.describe AppSec::Dast::SiteValidations::RunnerService do ...@@ -75,14 +75,6 @@ RSpec.describe AppSec::Dast::SiteValidations::RunnerService do
expect { subject }.to change { dast_site_validation.state }.from('pending').to('failed') expect { subject }.to change { dast_site_validation.state }.from('pending').to('failed')
end end
end end
context 'when feature flag is disabled' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it_behaves_like 'a failure'
end
end end
end end
end end
...@@ -87,62 +87,6 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -87,62 +87,6 @@ RSpec.describe DastSiteValidations::CreateService do
end end
describe 'execute', :clean_gitlab_redis_shared_state do describe 'execute', :clean_gitlab_redis_shared_state do
context 'worker validation' do
before do
stub_feature_flags(dast_runner_site_validation: false)
end
it_behaves_like 'the licensed feature is not available'
it_behaves_like 'the licensed feature is available' do
it 'attempts to validate' do
expect(DastSiteValidationWorker).to receive(:perform_async)
subject
end
context 'when worker does not return a job id' do
before do
allow(DastSiteValidationWorker).to receive(:perform_async).and_return(nil)
end
let(:dast_site_validation) do
DastSiteValidation.find_by!(dast_site_token: dast_site_token, url_path: params[:url_path])
end
it 'communicates failure' do
aggregate_failures do
expect(subject.status).to eq(:error)
expect(subject.message).to eq('Validation failed')
end
end
it 'sets dast_site_validation.state to failed' do
subject
expect(dast_site_validation.state).to eq('failed')
end
it 'logs an error' do
allow(Gitlab::AppLogger).to receive(:error)
subject
expect(Gitlab::AppLogger).to have_received(:error).with(message: 'Unable to validate dast_site_validation', dast_site_validation_id: dast_site_validation.id)
end
end
it_behaves_like 'a dast_site_validation already exists' do
it 'does not attempt to re-validate' do
expect(DastSiteValidationWorker).not_to receive(:perform_async)
subject
end
end
end
end
context 'runner validation' do
it_behaves_like 'the licensed feature is not available' it_behaves_like 'the licensed feature is not available'
it_behaves_like 'the licensed feature is available' do it_behaves_like 'the licensed feature is available' do
...@@ -163,5 +107,4 @@ RSpec.describe DastSiteValidations::CreateService do ...@@ -163,5 +107,4 @@ RSpec.describe DastSiteValidations::CreateService do
end end
end end
end end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe DastSiteValidations::ValidateService do
let(:dast_site_validation) { create(:dast_site_validation) }
let(:token) { dast_site_validation.dast_site_token.token }
let(:headers) { { 'Content-Type' => 'text/plain; charset=utf-8' } }
subject do
described_class.new(
container: dast_site_validation.project,
params: { dast_site_validation: dast_site_validation }
).execute!
end
describe 'execute!' do
context 'when on demand scan licensed feature is not available' do
it 'communicates failure' do
stub_licensed_features(security_on_demand_scans: false)
expect { subject }.to raise_error(DastSiteValidations::ValidateService::PermissionsError)
end
end
context 'when the feature is available' do
before do
stub_licensed_features(security_on_demand_scans: true)
stub_request(:get, dast_site_validation.validation_url).to_return(body: token, headers: headers)
end
it 'validates the url before making an http request' do
uri = URI(dast_site_validation.validation_url)
opt = hash_including(allow_local_network: false, allow_localhost: false, dns_rebind_protection: true)
aggregate_failures do
expect(Gitlab::UrlBlocker).to receive(:validate!).with(uri, opt).and_call_original
expect(Gitlab::HTTP).to receive(:get).with(dast_site_validation.validation_url, use_read_total_timeout: true).and_call_original
end
subject
end
context 'when validation has already been attempted' do
let_it_be(:dast_site_validation) { create(:dast_site_validation, state: :failed) }
it 'marks the validation as a retry' do
freeze_time do
subject
expect(dast_site_validation.reload.validation_last_retried_at).to eq(Time.now.utc)
end
end
end
shared_examples 'a validation' do
context 'when the token is found' do
it 'calls dast_site_validation#start' do
expect(dast_site_validation).to receive(:start)
subject
end
it 'calls dast_site_validation#pass' do
expect(dast_site_validation).to receive(:pass)
subject
end
it 'marks the validation successful' do
subject
expect(dast_site_validation.reload.state).to eq('passed')
end
context 'when validation has already started' do
before do
dast_site_validation.update_column(:state, :inprogress)
end
it 'does not call dast_site_validation#pass' do
expect(dast_site_validation).not_to receive(:start)
subject
end
end
context 'when validation is already complete' do
before do
dast_site_validation.update_column(:state, :passed)
end
it 'does not re-validate' do
expect(Gitlab::HTTP).not_to receive(:get)
subject
end
end
end
context 'when the token is not found' do
let(:token) do
'<div>' + dast_site_validation.dast_site_token.token + '</div>'
end
it 'raises an exception' do
expect { subject }.to raise_error(DastSiteValidations::ValidateService::TokenNotFound)
end
end
end
context 'when validation_strategy=text_file' do
let(:dast_site_validation) { create(:dast_site_validation, validation_strategy: :text_file) }
before do
stub_request(:get, dast_site_validation.validation_url).to_return(body: token, headers: headers)
end
it_behaves_like 'a validation'
context 'when the http response body has trailing newlines after the token' do
let(:token) { dast_site_validation.dast_site_token.token + "\n\n" }
it 'does not raise an exception' do
expect { subject }.not_to raise_error(DastSiteValidations::ValidateService::TokenNotFound)
end
end
context 'when content type is incorrect' do
let(:headers) { { 'Content-Type' => 'text/html; charset=UTF-8' } }
it 'raises an exception' do
expect { subject }.to raise_error(DastSiteValidations::ValidateService::TokenNotFound)
end
end
end
context 'when validation_strategy=header' do
let(:dast_site_validation) { create(:dast_site_validation, validation_strategy: :header) }
before do
headers = { DastSiteValidation::HEADER => token }
stub_request(:get, dast_site_validation.validation_url).to_return(headers: headers)
end
it_behaves_like 'a validation'
end
end
end
end
...@@ -10,57 +10,10 @@ RSpec.describe DastSiteValidationWorker do ...@@ -10,57 +10,10 @@ RSpec.describe DastSiteValidationWorker do
end end
describe '#perform' do describe '#perform' do
it 'calls DastSiteValidations::ValidateService' do
double = double(DastSiteValidations::ValidateService, "execute!" => true)
args = { container: dast_site_validation.project, params: { dast_site_validation: dast_site_validation } }
expect(double).to receive(:execute!)
expect(DastSiteValidations::ValidateService).to receive(:new).with(args).and_return(double)
subject
end
context 'when the feature is available' do
let(:response_body) { dast_site_validation.dast_site_token.token }
let(:headers) { { 'Content-Type' => 'text/plain; charset=utf-8' } }
before do
stub_licensed_features(security_on_demand_scans: true)
stub_request(:get, dast_site_validation.validation_url).to_return(body: response_body, headers: headers)
end
context 'when the request body contains the token' do
include_examples 'an idempotent worker' do include_examples 'an idempotent worker' do
subject do subject do
perform_multiple([dast_site_validation.id], worker: described_class.new) perform_multiple([dast_site_validation.id], worker: described_class.new)
end end
end end
end end
end
end
describe '.sidekiq_retries_exhausted' do
it 'calls find with the correct id' do
job = { 'args' => [dast_site_validation.id], 'jid' => '1' }
expect(dast_site_validation.class).to receive(:find).with(dast_site_validation.id).and_call_original
described_class.sidekiq_retries_exhausted_block.call(job)
end
it 'marks validation failed' do
job = { 'args' => [dast_site_validation.id], 'jid' => '1' }
freeze_time do
described_class.sidekiq_retries_exhausted_block.call(job)
aggregate_failures do
obj = dast_site_validation.reload
expect(obj.state).to eq('failed')
expect(obj.validation_failed_at).to eq(Time.now.utc)
end
end
end
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