diff options
Diffstat (limited to 'spec/lib/gitlab/ci/parsers/security')
-rw-r--r-- | spec/lib/gitlab/ci/parsers/security/common_spec.rb | 236 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb | 662 |
2 files changed, 747 insertions, 151 deletions
diff --git a/spec/lib/gitlab/ci/parsers/security/common_spec.rb b/spec/lib/gitlab/ci/parsers/security/common_spec.rb index 1e96c717a4f..dfc5dec1481 100644 --- a/spec/lib/gitlab/ci/parsers/security/common_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/common_spec.rb @@ -4,6 +4,18 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Parsers::Security::Common do describe '#parse!' do + let_it_be(:scanner_data) do + { + scan: { + scanner: { + id: "gemnasium", + name: "Gemnasium", + version: "2.1.0" + } + } + } + end + where(vulnerability_finding_signatures_enabled: [true, false]) with_them do let_it_be(:pipeline) { create(:ci_pipeline) } @@ -30,7 +42,9 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do describe 'schema validation' do let(:validator_class) { Gitlab::Ci::Parsers::Security::Validators::SchemaValidator } - let(:parser) { described_class.new('{}', report, vulnerability_finding_signatures_enabled, validate: validate) } + let(:data) { {}.merge(scanner_data) } + let(:json_data) { data.to_json } + let(:parser) { described_class.new(json_data, report, vulnerability_finding_signatures_enabled, validate: validate) } subject(:parse_report) { parser.parse! } @@ -38,172 +52,138 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do allow(validator_class).to receive(:new).and_call_original end - context 'when show_report_validation_warnings is enabled' do - before do - stub_feature_flags(show_report_validation_warnings: true) - end - - context 'when the validate flag is set to `false`' do - let(:validate) { false } - let(:valid?) { false } - let(:errors) { ['foo'] } - - before do - allow_next_instance_of(validator_class) do |instance| - allow(instance).to receive(:valid?).and_return(valid?) - allow(instance).to receive(:errors).and_return(errors) - end - - allow(parser).to receive_messages(create_scanner: true, create_scan: true) - end - - it 'instantiates the validator with correct params' do - parse_report - - expect(validator_class).to have_received(:new).with(report.type, {}, report.version) - end - - context 'when the report data is not valid according to the schema' do - it 'adds warnings to the report' do - expect { parse_report }.to change { report.warnings }.from([]).to([{ message: 'foo', type: 'Schema' }]) - end - - it 'keeps the execution flow as normal' do - parse_report + context 'when the validate flag is set to `false`' do + let(:validate) { false } + let(:valid?) { false } + let(:errors) { ['foo'] } + let(:warnings) { ['bar'] } - expect(parser).to have_received(:create_scanner) - expect(parser).to have_received(:create_scan) - end + before do + allow_next_instance_of(validator_class) do |instance| + allow(instance).to receive(:valid?).and_return(valid?) + allow(instance).to receive(:errors).and_return(errors) + allow(instance).to receive(:warnings).and_return(warnings) end - context 'when the report data is valid according to the schema' do - let(:valid?) { true } - let(:errors) { [] } - - it 'does not add warnings to the report' do - expect { parse_report }.not_to change { report.errors } - end - - it 'keeps the execution flow as normal' do - parse_report - - expect(parser).to have_received(:create_scanner) - expect(parser).to have_received(:create_scan) - end - end + allow(parser).to receive_messages(create_scanner: true, create_scan: true) end - context 'when the validate flag is set to `true`' do - let(:validate) { true } - let(:valid?) { false } - let(:errors) { ['foo'] } + it 'instantiates the validator with correct params' do + parse_report - before do - allow_next_instance_of(validator_class) do |instance| - allow(instance).to receive(:valid?).and_return(valid?) - allow(instance).to receive(:errors).and_return(errors) - end + expect(validator_class).to have_received(:new).with( + report.type, + data.deep_stringify_keys, + report.version, + project: pipeline.project, + scanner: data.dig(:scan, :scanner).deep_stringify_keys + ) + end - allow(parser).to receive_messages(create_scanner: true, create_scan: true) + context 'when the report data is not valid according to the schema' do + it 'adds warnings to the report' do + expect { parse_report }.to change { report.warnings }.from([]).to( + [ + { message: 'foo', type: 'Schema' }, + { message: 'bar', type: 'Schema' } + ] + ) end - it 'instantiates the validator with correct params' do + it 'keeps the execution flow as normal' do parse_report - expect(validator_class).to have_received(:new).with(report.type, {}, report.version) + expect(parser).to have_received(:create_scanner) + expect(parser).to have_received(:create_scan) end + end - context 'when the report data is not valid according to the schema' do - it 'adds errors to the report' do - expect { parse_report }.to change { report.errors }.from([]).to([{ message: 'foo', type: 'Schema' }]) - end - - it 'does not try to create report entities' do - parse_report + context 'when the report data is valid according to the schema' do + let(:valid?) { true } + let(:errors) { [] } + let(:warnings) { [] } - expect(parser).not_to have_received(:create_scanner) - expect(parser).not_to have_received(:create_scan) - end + it 'does not add errors to the report' do + expect { parse_report }.not_to change { report.errors } end - context 'when the report data is valid according to the schema' do - let(:valid?) { true } - let(:errors) { [] } - - it 'does not add errors to the report' do - expect { parse_report }.not_to change { report.errors }.from([]) - end + it 'does not add warnings to the report' do + expect { parse_report }.not_to change { report.warnings } + end - it 'keeps the execution flow as normal' do - parse_report + it 'keeps the execution flow as normal' do + parse_report - expect(parser).to have_received(:create_scanner) - expect(parser).to have_received(:create_scan) - end + expect(parser).to have_received(:create_scanner) + expect(parser).to have_received(:create_scan) end end end - context 'when show_report_validation_warnings is disabled' do - before do - stub_feature_flags(show_report_validation_warnings: false) - end - - context 'when the validate flag is set as `false`' do - let(:validate) { false } + context 'when the validate flag is set to `true`' do + let(:validate) { true } + let(:valid?) { false } + let(:errors) { ['foo'] } + let(:warnings) { ['bar'] } - it 'does not run the validation logic' do - parse_report - - expect(validator_class).not_to have_received(:new) + before do + allow_next_instance_of(validator_class) do |instance| + allow(instance).to receive(:valid?).and_return(valid?) + allow(instance).to receive(:errors).and_return(errors) + allow(instance).to receive(:warnings).and_return(warnings) end + + allow(parser).to receive_messages(create_scanner: true, create_scan: true) end - context 'when the validate flag is set as `true`' do - let(:validate) { true } - let(:valid?) { false } + it 'instantiates the validator with correct params' do + parse_report - before do - allow_next_instance_of(validator_class) do |instance| - allow(instance).to receive(:valid?).and_return(valid?) - allow(instance).to receive(:errors).and_return(['foo']) - end + expect(validator_class).to have_received(:new).with( + report.type, + data.deep_stringify_keys, + report.version, + project: pipeline.project, + scanner: data.dig(:scan, :scanner).deep_stringify_keys + ) + end - allow(parser).to receive_messages(create_scanner: true, create_scan: true) + context 'when the report data is not valid according to the schema' do + it 'adds errors to the report' do + expect { parse_report }.to change { report.errors }.from([]).to( + [ + { message: 'foo', type: 'Schema' }, + { message: 'bar', type: 'Schema' } + ] + ) end - it 'instantiates the validator with correct params' do + it 'does not try to create report entities' do parse_report - expect(validator_class).to have_received(:new).with(report.type, {}, report.version) + expect(parser).not_to have_received(:create_scanner) + expect(parser).not_to have_received(:create_scan) end + end - context 'when the report data is not valid according to the schema' do - it 'adds errors to the report' do - expect { parse_report }.to change { report.errors }.from([]).to([{ message: 'foo', type: 'Schema' }]) - end - - it 'does not try to create report entities' do - parse_report + context 'when the report data is valid according to the schema' do + let(:valid?) { true } + let(:errors) { [] } + let(:warnings) { [] } - expect(parser).not_to have_received(:create_scanner) - expect(parser).not_to have_received(:create_scan) - end + it 'does not add errors to the report' do + expect { parse_report }.not_to change { report.errors }.from([]) end - context 'when the report data is valid according to the schema' do - let(:valid?) { true } - - it 'does not add errors to the report' do - expect { parse_report }.not_to change { report.errors }.from([]) - end + it 'does not add warnings to the report' do + expect { parse_report }.not_to change { report.warnings }.from([]) + end - it 'keeps the execution flow as normal' do - parse_report + it 'keeps the execution flow as normal' do + parse_report - expect(parser).to have_received(:create_scanner) - expect(parser).to have_received(:create_scan) - end + expect(parser).to have_received(:create_scanner) + expect(parser).to have_received(:create_scan) end end end diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb index c83427b68ef..f6409c8b01f 100644 --- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb @@ -3,6 +3,18 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do + let_it_be(:project) { create(:project) } + + let(:scanner) do + { + 'id' => 'gemnasium', + 'name' => 'Gemnasium', + 'version' => '2.1.0' + } + end + + let(:validator) { described_class.new(report_type, report_data, report_version, project: project, scanner: scanner) } + describe 'SUPPORTED_VERSIONS' do schema_path = Rails.root.join("lib", "gitlab", "ci", "parsers", "security", "validators", "schemas") @@ -47,48 +59,652 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do end end - using RSpec::Parameterized::TableSyntax + describe '#valid?' do + subject { validator.valid? } - where(:report_type, :report_version, :expected_errors, :valid_data) do - 'sast' | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] } - :sast | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] } - :secret_detection | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] } - end + context 'when given a supported schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } - with_them do - let(:validator) { described_class.new(report_type, report_data, report_version) } + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end - describe '#valid?' do - subject { validator.valid? } + it { is_expected.to be_truthy } + end - context 'when given data is invalid according to the schema' do - let(:report_data) { {} } + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end it { is_expected.to be_falsey } + + it 'logs related information' do + expect(Gitlab::AppLogger).to receive(:info).with( + message: "security report schema validation problem", + security_report_type: report_type, + security_report_version: report_version, + project_id: project.id, + security_report_failure: 'schema_validation_fails', + security_report_scanner_id: 'gemnasium', + security_report_scanner_version: '2.1.0' + ) + + subject + end end + end + + context 'when given a deprecated schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } - context 'when given data is valid according to the schema' do - let(:report_data) { valid_data } + context 'and the report passes schema validation' do + let(:report_data) do + { + 'version' => '10.0.0', + 'vulnerabilities' => [] + } + end it { is_expected.to be_truthy } + + it 'logs related information' do + expect(Gitlab::AppLogger).to receive(:info).with( + message: "security report schema validation problem", + security_report_type: report_type, + security_report_version: report_version, + project_id: project.id, + security_report_failure: 'using_deprecated_schema_version', + security_report_scanner_id: 'gemnasium', + security_report_scanner_version: '2.1.0' + ) + + subject + end end - context 'when no report_version is provided' do - let(:report_version) { nil } - let(:report_data) { valid_data } + context 'and the report does not pass schema validation' do + context 'and enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end - it 'does not fail' do - expect { subject }.not_to raise_error + it { is_expected.to be_falsey } + end + + context 'and enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end + + it { is_expected.to be_truthy } end end end - describe '#errors' do - let(:report_data) { { 'version' => '10.0.0' } } + context 'when given an unsupported schema version' do + let(:report_type) { :dast } + let(:report_version) { "12.37.0" } + + context 'if enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + it { is_expected.to be_falsey } + + it 'logs related information' do + expect(Gitlab::AppLogger).to receive(:info).with( + message: "security report schema validation problem", + security_report_type: report_type, + security_report_version: report_version, + project_id: project.id, + security_report_failure: 'using_unsupported_schema_version', + security_report_scanner_id: 'gemnasium', + security_report_scanner_version: '2.1.0' + ) + + subject + end + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + context 'and scanner information is empty' do + let(:scanner) { {} } + + it 'logs related information' do + expect(Gitlab::AppLogger).to receive(:info).with( + message: "security report schema validation problem", + security_report_type: report_type, + security_report_version: report_version, + project_id: project.id, + security_report_failure: 'schema_validation_fails', + security_report_scanner_id: nil, + security_report_scanner_version: nil + ) + + expect(Gitlab::AppLogger).to receive(:info).with( + message: "security report schema validation problem", + security_report_type: report_type, + security_report_version: report_version, + project_id: project.id, + security_report_failure: 'using_unsupported_schema_version', + security_report_scanner_id: nil, + security_report_scanner_version: nil + ) + + subject + end + end + + it { is_expected.to be_falsey } + end + end + + context 'if enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + it { is_expected.to be_truthy } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + it { is_expected.to be_truthy } + end + end + end + end - subject { validator.errors } + describe '#errors' do + subject { validator.errors } - it { is_expected.to eq(expected_errors) } + context 'when given a supported schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + context 'if enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: project) + end + + let(:expected_errors) do + [ + 'root is missing required keys: vulnerabilities' + ] + end + + it { is_expected.to match_array(expected_errors) } + end + + context 'if enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + end + end + + context 'when given a deprecated schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } + + context 'and the report passes schema validation' do + let(:report_data) do + { + 'version' => '10.0.0', + 'vulnerabilities' => [] + } + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + + context 'and the report does not pass schema validation' do + context 'and enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end + + let(:expected_errors) do + [ + "property '/version' does not match pattern: ^[0-9]+\\.[0-9]+\\.[0-9]+$", + "root is missing required keys: vulnerabilities" + ] + end + + it { is_expected.to match_array(expected_errors) } + end + + context 'and enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + end + end + + context 'when given an unsupported schema version' do + let(:report_type) { :dast } + let(:report_version) { "12.37.0" } + + context 'if enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_errors) do + [ + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1" + ] + end + + it { is_expected.to match_array(expected_errors) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + let(:expected_errors) do + [ + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1", + "root is missing required keys: vulnerabilities" + ] + end + + it { is_expected.to match_array(expected_errors) } + end + end + + context 'if enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + let(:expected_errors) { [] } + + it { is_expected.to match_array(expected_errors) } + end + end + end + end + + describe '#deprecation_warnings' do + subject { validator.deprecation_warnings } + + context 'when given a supported schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } + + let(:expected_deprecation_warnings) { [] } + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + it { is_expected.to match_array(expected_deprecation_warnings) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + it { is_expected.to match_array(expected_deprecation_warnings) } + end + end + + context 'when given a deprecated schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } + let(:expected_deprecation_warnings) do + [ + "Version V2.7.0 for report type dast has been deprecated, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1" + ] + end + + context 'and the report passes schema validation' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + it { is_expected.to match_array(expected_deprecation_warnings) } + end + + context 'and the report does not pass schema validation' do + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end + + it { is_expected.to match_array(expected_deprecation_warnings) } + end + end + + context 'when given an unsupported schema version' do + let(:report_type) { :dast } + let(:report_version) { "21.37.0" } + let(:expected_deprecation_warnings) { [] } + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + it { is_expected.to match_array(expected_deprecation_warnings) } + end + end + + describe '#warnings' do + subject { validator.warnings } + + context 'when given a supported schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + context 'if enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: project) + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + + context 'if enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:expected_warnings) do + [ + 'root is missing required keys: vulnerabilities' + ] + end + + it { is_expected.to match_array(expected_warnings) } + end + end + end + + context 'when given a deprecated schema version' do + let(:report_type) { :dast } + let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last } + + context 'and the report passes schema validation' do + let(:report_data) do + { + 'vulnerabilities' => [] + } + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + + context 'and the report does not pass schema validation' do + let(:report_data) do + { + 'version' => 'V2.7.0' + } + end + + context 'and enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + + context 'and enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + let(:expected_warnings) do + [ + "property '/version' does not match pattern: ^[0-9]+\\.[0-9]+\\.[0-9]+$", + "root is missing required keys: vulnerabilities" + ] + end + + it { is_expected.to match_array(expected_warnings) } + end + end + end + + context 'when given an unsupported schema version' do + let(:report_type) { :dast } + let(:report_version) { "12.37.0" } + + context 'if enforce_security_report_validation is enabled' do + before do + stub_feature_flags(enforce_security_report_validation: true) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + let(:expected_warnings) { [] } + + it { is_expected.to match_array(expected_warnings) } + end + end + + context 'if enforce_security_report_validation is disabled' do + before do + stub_feature_flags(enforce_security_report_validation: false) + end + + context 'and the report is valid' do + let(:report_data) do + { + 'version' => report_version, + 'vulnerabilities' => [] + } + end + + let(:expected_warnings) do + [ + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1" + ] + end + + it { is_expected.to match_array(expected_warnings) } + end + + context 'and the report is invalid' do + let(:report_data) do + { + 'version' => report_version + } + end + + let(:expected_warnings) do + [ + "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1", + "root is missing required keys: vulnerabilities" + ] + end + + it { is_expected.to match_array(expected_warnings) } + end + end end end end |