Commit 38f666fa authored by Tetiana Chupryna's avatar Tetiana Chupryna Committed by Aleksei Lipniagov

Fix classification of custom licenses in License Compliance

parent e755595e
......@@ -38,24 +38,24 @@ module SCA
end
def report_for(policy)
build_policy(license_scan_report[policy.software_license.canonical_id], policy)
build_policy(reported_license_by_license_model(policy.software_license), policy)
end
def diff_with(other)
license_scan_report
.diff_with(other.license_scan_report)
license_scanning_report
.diff_with(other.license_scanning_report)
.transform_values do |reported_licenses|
reported_licenses.map do |reported_license|
matching_license_policy =
known_policies[reported_license.canonical_id] ||
known_policies[reported_license.id] ||
known_policies[reported_license&.name&.downcase]
build_policy(reported_license, matching_license_policy)
end
end
end
def license_scan_report
strong_memoize(:license_scan_report) do
def license_scanning_report
strong_memoize(:license_scanning_report) do
pipeline.blank? ? empty_report : pipeline.license_scanning_report
end
end
......@@ -74,9 +74,16 @@ module SCA
end
end
# When the license found in the report doesn't match any license
# of the SPDX License List, we need to find it by name explicitly.
def reported_license_by_license_model(software_license)
license_scanning_report[software_license.canonical_id] ||
license_scanning_report.by_license_name(software_license.name&.downcase)
end
def unclassified_policies
license_scan_report.licenses.map do |reported_license|
next if known_policies[reported_license.canonical_id]
license_scanning_report.licenses.map do |reported_license|
next if known_policies[reported_license.id] || known_policies[reported_license&.name&.downcase]
[reported_license.canonical_id, build_policy(reported_license, nil)]
end.compact.to_h
......
......@@ -34,7 +34,7 @@ module Gitlab
end
def by_license_name(name)
licenses.find { |license| license.name == name }
licenses.find { |license| license.name.casecmp?(name) }
end
def apply_details_from!(dependency_list_report)
......
......@@ -140,6 +140,12 @@ FactoryBot.define do
end
end
trait :license_scanning_custom_license do
after :build do |build|
build.job_artifacts << build(:ee_ci_job_artifact, :license_scanning_custom_license, job: build)
end
end
trait :requirements_report do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :all_passing_requirements, job: build)
......
......@@ -159,6 +159,16 @@ FactoryBot.define do
end
end
trait :license_scanning_custom_license do
file_type { :license_scanning }
file_format { :raw }
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/security_reports/license_compliance/gl-license-scanning-report-custom-license.json'), 'application/json')
end
end
trait :performance do
file_format { :raw }
file_type { :performance }
......@@ -338,7 +348,7 @@ FactoryBot.define do
trait :"v#{version}" do
after(:build) do |artifact, _|
filename = "gl-#{artifact.file_type.dasherize}-report-v#{version.sub(/_/, '.')}.json"
path = Rails.root.join("ee/spec/fixtures/security_reports/#{filename}")
path = Rails.root.join("ee/spec/fixtures/security_reports/license_compliance/#{filename}")
artifact.file = fixture_file_upload(path, "application/json")
end
end
......
......@@ -30,7 +30,7 @@ RSpec.describe 'EE > Projects > Licenses > Maintainer views policies', :js do
let_it_be(:mit_policy) { create(:software_license_policy, :denied, software_license: mit, project: project) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, project: project, builds: [create(:ee_ci_build, :license_scan_v2, :success)], status: :success) }
let(:report) { Gitlab::Json.parse(fixture_file('security_reports/gl-license-scanning-report-v2.json', dir: 'ee')) }
let(:report) { Gitlab::Json.parse(fixture_file('security_reports/license_compliance/gl-license-scanning-report-v2.json', dir: 'ee')) }
let(:known_licenses) { report['licenses'].find_all { |license| license['url'].present? } }
it 'displays licenses detected in the most recent scan report' do
......
{
"version": "2.1",
"licenses": [
{
"id": "BSD-3-Clause",
"name": "BSD 3-Clause \"New\" or \"Revised\" License",
"url": "https://opensource.org/licenses/BSD-3-Clause"
},
{
"id": "MIT",
"name": "MIT License",
"url": "https://opensource.org/licenses/MIT"
},
{
"id": "foo",
"name": "Foo License",
"url": ""
}
],
"dependencies": [
{
"name": "a",
"version": "1.0.0",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["MIT"]
},
{
"name": "b",
"version": "0.1.0",
"package_manager": "yarn",
"path": "yarn.lock",
"licenses": ["BSD-3-Clause"]
},
{
"name": "c",
"version": "1.1.0",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["MIT", "BSD-3-Clause"]
},
{
"name": "d",
"version": "1.1.1",
"package_manager": "bundler",
"path": "Gemfile.lock",
"licenses": ["foo"]
}
]
}
......@@ -42,7 +42,7 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
end
context 'when parsing a valid v1.1 report' do
let(:v1_1_data) { fixture_file('security_reports/gl-license-scanning-report-v1.1.json', dir: 'ee') }
let(:v1_1_data) { fixture_file('security_reports/license_compliance/gl-license-scanning-report-v1.1.json', dir: 'ee') }
before do
subject.parse!(v1_1_data, report)
......@@ -74,7 +74,7 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
end
context 'when parsing a valid v2 report' do
let(:v2_0_data) { fixture_file('security_reports/gl-license-scanning-report-v2.json', dir: 'ee') }
let(:v2_0_data) { fixture_file('security_reports/license_compliance/gl-license-scanning-report-v2.json', dir: 'ee') }
before do
subject.parse!(v2_0_data, report)
......@@ -106,7 +106,7 @@ RSpec.describe Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning do
end
context 'when parsing a valid v2.1 report' do
let(:v2_1_data) { fixture_file('security_reports/gl-license-scanning-report-v2.1.json', dir: 'ee') }
let(:v2_1_data) { fixture_file('security_reports/license_compliance/gl-license-scanning-report-v2.1.json', dir: 'ee') }
before do
subject.parse!(v2_1_data, report)
......
......@@ -11,7 +11,7 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
let(:report) { build(:ci_reports_license_scanning_report, :report_2) }
context 'with existing license' do
let(:name) { 'MIT' }
let(:name) { 'MIt' }
it 'finds right name' do
is_expected.to be_a(Gitlab::Ci::Reports::LicenseScanning::License)
......@@ -290,7 +290,7 @@ RSpec.describe Gitlab::Ci::Reports::LicenseScanning::Report do
context 'when parsing a v2 report' do
subject { described_class.parse_from(v2_json) }
let(:v2_json) { fixture_file('security_reports/gl-license-scanning-report-v2.json', dir: 'ee') }
let(:v2_json) { fixture_file('security_reports/license_compliance/gl-license-scanning-report-v2.json', dir: 'ee') }
it { expect(subject.version).to eql('2.0') }
it { expect(subject.licenses.count).to eq(3) }
......
......@@ -3,9 +3,10 @@
require "spec_helper"
RSpec.describe SCA::LicenseCompliance do
subject { project.license_compliance }
let(:license_compliance) { described_class.new(project, pipeline) }
let_it_be(:project) { create(:project, :repository, :private) }
let(:project) { create(:project, :repository, :private) }
let(:mit) { create(:software_license, :mit) }
let(:other_license) { create(:software_license, name: "SOFTWARE-LICENSE", spdx_identifier: "Other-Id") }
......@@ -14,44 +15,48 @@ RSpec.describe SCA::LicenseCompliance do
end
describe "#policies" do
subject(:policies) { license_compliance.policies }
context "when a pipeline has not been run for this project" do
it { expect(subject.policies.count).to be_zero }
let(:pipeline) { nil }
it { expect(policies.count).to be_zero }
context "when the project has policies configured" do
let!(:mit_policy) { create(:software_license_policy, :denied, software_license: mit, project: project) }
it "includes an a policy for a classified license that was not detected in the scan report" do
expect(subject.policies.count).to be(1)
expect(subject.policies[0].id).to eq(mit_policy.id)
expect(subject.policies[0].name).to eq(mit.name)
expect(subject.policies[0].url).to be_nil
expect(subject.policies[0].classification).to eq("denied")
expect(subject.policies[0].spdx_identifier).to eq(mit.spdx_identifier)
expect(policies.count).to eq(1)
expect(policies[0].id).to eq(mit_policy.id)
expect(policies[0].name).to eq(mit.name)
expect(policies[0].url).to be_nil
expect(policies[0].classification).to eq("denied")
expect(policies[0].spdx_identifier).to eq(mit.spdx_identifier)
end
end
end
context "when a pipeline has run" do
let!(:pipeline) { create(:ci_pipeline, :success, project: project, builds: builds) }
let(:pipeline) { create(:ci_pipeline, :success, project: project, builds: builds) }
let(:builds) { [] }
context "when a license scan job is not configured" do
let(:builds) { [create(:ci_build, :success)] }
it { expect(subject.policies).to be_empty }
it { expect(policies).to be_empty }
end
context "when the license scan job has not finished" do
let(:builds) { [create(:ci_build, :running, job_artifacts: [artifact])] }
let(:artifact) { create(:ci_job_artifact, file_type: :license_scanning, file_format: :raw) }
it { expect(subject.policies).to be_empty }
it { expect(policies).to be_empty }
end
context "when the license scan produces a poorly formatted report" do
let(:builds) { [create(:ee_ci_build, :running, :corrupted_license_scanning_report)] }
it { expect(subject.policies).to be_empty }
it { expect(policies).to be_empty }
end
context "when the dependency scan produces a poorly formatted report" do
......@@ -62,7 +67,7 @@ RSpec.describe SCA::LicenseCompliance do
]
end
it { expect(subject.policies.map(&:spdx_identifier)).to contain_exactly("BSD-3-Clause", "MIT", nil) }
it { expect(policies.map(&:spdx_identifier)).to contain_exactly("BSD-3-Clause", "MIT", nil) }
end
context "when a pipeline has successfully produced a v2.0 license scan report" do
......@@ -71,39 +76,39 @@ RSpec.describe SCA::LicenseCompliance do
let!(:other_license_policy) { create(:software_license_policy, :allowed, software_license: other_license, project: project) }
it "includes a policy for each detected license and classified license" do
expect(subject.policies.count).to eq(4)
expect(policies.count).to eq(4)
end
it 'includes a policy for a detected license that is unclassified' do
expect(subject.policies[0].id).to be_nil
expect(subject.policies[0].name).to eq("BSD 3-Clause \"New\" or \"Revised\" License")
expect(subject.policies[0].url).to eq("http://spdx.org/licenses/BSD-3-Clause.json")
expect(subject.policies[0].classification).to eq("unclassified")
expect(subject.policies[0].spdx_identifier).to eq("BSD-3-Clause")
expect(policies[0].id).to be_nil
expect(policies[0].name).to eq("BSD 3-Clause \"New\" or \"Revised\" License")
expect(policies[0].url).to eq("http://spdx.org/licenses/BSD-3-Clause.json")
expect(policies[0].classification).to eq("unclassified")
expect(policies[0].spdx_identifier).to eq("BSD-3-Clause")
end
it 'includes a policy for a classified license that was also detected in the scan report' do
expect(subject.policies[1].id).to eq(mit_policy.id)
expect(subject.policies[1].name).to eq(mit.name)
expect(subject.policies[1].url).to eq("http://spdx.org/licenses/MIT.json")
expect(subject.policies[1].classification).to eq("denied")
expect(subject.policies[1].spdx_identifier).to eq("MIT")
expect(policies[1].id).to eq(mit_policy.id)
expect(policies[1].name).to eq(mit.name)
expect(policies[1].url).to eq("http://spdx.org/licenses/MIT.json")
expect(policies[1].classification).to eq("denied")
expect(policies[1].spdx_identifier).to eq("MIT")
end
it 'includes a policy for a classified license that was not detected in the scan report' do
expect(subject.policies[2].id).to eq(other_license_policy.id)
expect(subject.policies[2].name).to eq(other_license.name)
expect(subject.policies[2].url).to be_blank
expect(subject.policies[2].classification).to eq("allowed")
expect(subject.policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
expect(policies[2].id).to eq(other_license_policy.id)
expect(policies[2].name).to eq(other_license.name)
expect(policies[2].url).to be_blank
expect(policies[2].classification).to eq("allowed")
expect(policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
end
it 'includes a policy for an unclassified and unknown license that was detected in the scan report' do
expect(subject.policies[3].id).to be_nil
expect(subject.policies[3].name).to eq("unknown")
expect(subject.policies[3].url).to be_blank
expect(subject.policies[3].classification).to eq("unclassified")
expect(subject.policies[3].spdx_identifier).to be_nil
expect(policies[3].id).to be_nil
expect(policies[3].name).to eq("unknown")
expect(policies[3].url).to be_blank
expect(policies[3].classification).to eq("unclassified")
expect(policies[3].spdx_identifier).to be_nil
end
end
......@@ -113,39 +118,39 @@ RSpec.describe SCA::LicenseCompliance do
let!(:other_license_policy) { create(:software_license_policy, :allowed, software_license: other_license, project: project) }
it "includes a policy for each detected license and classified license" do
expect(subject.policies.count).to eq(4)
expect(policies.count).to eq(4)
end
it 'includes a policy for a detected license that is unclassified' do
expect(subject.policies[0].id).to be_nil
expect(subject.policies[0].name).to eq("BSD 3-Clause \"New\" or \"Revised\" License")
expect(subject.policies[0].url).to eq("https://opensource.org/licenses/BSD-3-Clause")
expect(subject.policies[0].classification).to eq("unclassified")
expect(subject.policies[0].spdx_identifier).to eq("BSD-3-Clause")
expect(policies[0].id).to be_nil
expect(policies[0].name).to eq("BSD 3-Clause \"New\" or \"Revised\" License")
expect(policies[0].url).to eq("https://opensource.org/licenses/BSD-3-Clause")
expect(policies[0].classification).to eq("unclassified")
expect(policies[0].spdx_identifier).to eq("BSD-3-Clause")
end
it 'includes a policy for a classified license that was also detected in the scan report' do
expect(subject.policies[1].id).to eq(mit_policy.id)
expect(subject.policies[1].name).to eq(mit.name)
expect(subject.policies[1].url).to eq("https://opensource.org/licenses/MIT")
expect(subject.policies[1].classification).to eq("denied")
expect(subject.policies[1].spdx_identifier).to eq("MIT")
expect(policies[1].id).to eq(mit_policy.id)
expect(policies[1].name).to eq(mit.name)
expect(policies[1].url).to eq("https://opensource.org/licenses/MIT")
expect(policies[1].classification).to eq("denied")
expect(policies[1].spdx_identifier).to eq("MIT")
end
it 'includes a policy for a classified license that was not detected in the scan report' do
expect(subject.policies[2].id).to eq(other_license_policy.id)
expect(subject.policies[2].name).to eq(other_license.name)
expect(subject.policies[2].url).to be_blank
expect(subject.policies[2].classification).to eq("allowed")
expect(subject.policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
expect(policies[2].id).to eq(other_license_policy.id)
expect(policies[2].name).to eq(other_license.name)
expect(policies[2].url).to be_blank
expect(policies[2].classification).to eq("allowed")
expect(policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
end
it 'includes a policy for an unclassified and unknown license that was detected in the scan report' do
expect(subject.policies[3].id).to be_nil
expect(subject.policies[3].name).to eq("unknown")
expect(subject.policies[3].url).to be_blank
expect(subject.policies[3].classification).to eq("unclassified")
expect(subject.policies[3].spdx_identifier).to be_nil
expect(policies[3].id).to be_nil
expect(policies[3].name).to eq("unknown")
expect(policies[3].url).to be_blank
expect(policies[3].classification).to eq("unclassified")
expect(policies[3].spdx_identifier).to be_nil
end
end
......@@ -155,35 +160,35 @@ RSpec.describe SCA::LicenseCompliance do
let!(:other_license_policy) { create(:software_license_policy, :allowed, software_license: other_license, project: project) }
it 'includes a policy for an unclassified license detected in the scan report' do
expect(subject.policies[0].id).to be_nil
expect(subject.policies[0].name).to eq("BSD")
expect(subject.policies[0].url).to eq("http://spdx.org/licenses/BSD-4-Clause.json")
expect(subject.policies[0].classification).to eq("unclassified")
expect(subject.policies[0].spdx_identifier).to eq("BSD-4-Clause")
expect(policies[0].id).to be_nil
expect(policies[0].name).to eq("BSD")
expect(policies[0].url).to eq("http://spdx.org/licenses/BSD-4-Clause.json")
expect(policies[0].classification).to eq("unclassified")
expect(policies[0].spdx_identifier).to eq("BSD-4-Clause")
end
it 'includes a policy for a denied license found in the scan report' do
expect(subject.policies[1].id).to eq(mit_policy.id)
expect(subject.policies[1].name).to eq(mit.name)
expect(subject.policies[1].url).to eq("http://opensource.org/licenses/mit-license")
expect(subject.policies[1].classification).to eq("denied")
expect(subject.policies[1].spdx_identifier).to eq("MIT")
expect(policies[1].id).to eq(mit_policy.id)
expect(policies[1].name).to eq(mit.name)
expect(policies[1].url).to eq("http://opensource.org/licenses/mit-license")
expect(policies[1].classification).to eq("denied")
expect(policies[1].spdx_identifier).to eq("MIT")
end
it 'includes a policy for an allowed license NOT found in the scan report' do
expect(subject.policies[2].id).to eq(other_license_policy.id)
expect(subject.policies[2].name).to eq(other_license.name)
expect(subject.policies[2].url).to be_blank
expect(subject.policies[2].classification).to eq("allowed")
expect(subject.policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
expect(policies[2].id).to eq(other_license_policy.id)
expect(policies[2].name).to eq(other_license.name)
expect(policies[2].url).to be_blank
expect(policies[2].classification).to eq("allowed")
expect(policies[2].spdx_identifier).to eq(other_license.spdx_identifier)
end
it 'includes a policy for an unclassified and unknown license found in the scan report' do
expect(subject.policies[3].id).to be_nil
expect(subject.policies[3].name).to eq("unknown")
expect(subject.policies[3].url).to be_blank
expect(subject.policies[3].classification).to eq("unclassified")
expect(subject.policies[3].spdx_identifier).to be_nil
expect(policies[3].id).to be_nil
expect(policies[3].name).to eq("unknown")
expect(policies[3].url).to be_blank
expect(policies[3].classification).to eq("unclassified")
expect(policies[3].spdx_identifier).to be_nil
end
end
end
......@@ -202,10 +207,10 @@ RSpec.describe SCA::LicenseCompliance do
end
context "when searching for policies for licenses that were detected in a scan report" do
let(:results) { subject.find_policies(detected_only: true) }
let(:results) { license_compliance.find_policies(detected_only: true) }
it 'only includes licenses that appear in the latest license scan report' do
expect(results.count).to be(3)
expect(results.count).to eq(3)
end
it 'includes a policy for an unclassified and known license that was detected in the scan report' do
......@@ -240,10 +245,22 @@ RSpec.describe SCA::LicenseCompliance do
spdx_identifier: nil
)
end
context "with denied license without spdx identifier" do
let!(:pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :success, :license_scanning_custom_license)]) }
let(:custom_license) { create(:software_license, :user_entered, name: "foO licensE") }
let!(:custom_license_policy) { create(:software_license_policy, :denied, software_license: custom_license, project: project) }
let(:results) { license_compliance.find_policies(detected_only: true) }
it 'contains denied license' do
expect(results.count).to eq(3)
end
end
end
context "when searching for policies with a specific classification" do
let(:results) { subject.find_policies(classification: ['allowed']) }
let(:results) { license_compliance.find_policies(classification: ['allowed']) }
it 'includes an entry for each `allowed` licensed' do
expect(results.count).to eq(1)
......@@ -259,7 +276,7 @@ RSpec.describe SCA::LicenseCompliance do
end
context "when searching for policies by multiple classifications" do
let(:results) { subject.find_policies(classification: %w[allowed denied]) }
let(:results) { license_compliance.find_policies(classification: %w[allowed denied]) }
it 'includes an entry for each `allowed` and `denied` licensed' do
expect(results.count).to eq(2)
......@@ -283,7 +300,7 @@ RSpec.describe SCA::LicenseCompliance do
end
context "when searching for detected policies matching a classification" do
let(:results) { subject.find_policies(detected_only: true, classification: %w[allowed denied]) }
let(:results) { license_compliance.find_policies(detected_only: true, classification: %w[allowed denied]) }
it 'includes an entry for each entry that was detected in the report and matches a classification' do
expect(results.count).to eq(1)
......@@ -317,65 +334,68 @@ RSpec.describe SCA::LicenseCompliance do
end
with_them do
let(:results) { subject.find_policies(sort: { by: attribute, direction: direction }) }
let(:results) { license_compliance.find_policies(sort: { by: attribute, direction: direction }) }
it { expect(results.map(&:name)).to eq(expected) }
end
context 'when using the default sort options' do
it { expect(subject.find_policies.map(&:name)).to eq(sorted_by_name_asc) }
it { expect(license_compliance.find_policies.map(&:name)).to eq(sorted_by_name_asc) }
end
context 'when `nil` sort options are provided' do
it { expect(subject.find_policies(sort: nil).map(&:name)).to eq(sorted_by_name_asc) }
it { expect(license_compliance.find_policies(sort: nil).map(&:name)).to eq(sorted_by_name_asc) }
end
end
end
describe "#latest_build_for_default_branch" do
subject { license_compliance.latest_build_for_default_branch }
let(:pipeline) { nil }
let(:regular_build) { create(:ci_build, :success) }
let(:license_scan_build) { create(:ee_ci_build, :license_scan_v2_1, :success) }
context "when a pipeline has never been completed for the project" do
it { expect(subject.latest_build_for_default_branch).to be_nil }
let(:pipeline) { nil }
it { is_expected.to be_nil }
end
context "when a pipeline has completed successfully and produced a license scan report" do
let!(:pipeline) { create(:ci_pipeline, :success, project: project, builds: [regular_build, license_scan_build]) }
it { expect(subject.latest_build_for_default_branch).to eq(license_scan_build) }
it { is_expected.to eq(license_scan_build) }
end
context "when a pipeline has completed but does not contain a license scan report" do
let!(:pipeline) { create(:ci_pipeline, :success, project: project, builds: [regular_build]) }
it { expect(subject.latest_build_for_default_branch).to be_nil }
end
context "when latest pipeline doesn't contain license job" do
let!(:pipeline1) { create(:ci_pipeline, :success, project: project, builds: [license_scan_build]) }
let!(:pipeline2) { create(:ci_pipeline, :success, project: project, builds: [regular_build]) }
it { expect(subject.latest_build_for_default_branch).to eq(license_scan_build) }
it { is_expected.to be_nil }
end
end
describe "#diff_with" do
context "when the head pipeline has not run" do
subject { project.license_compliance(nil).diff_with(base_compliance) }
subject(:diff) { license_compliance.diff_with(base_compliance) }
let(:pipeline) { nil }
let!(:base_compliance) { project.license_compliance(base_pipeline) }
let!(:base_pipeline) { create(:ci_pipeline, :success, project: project, builds: [license_scan_build]) }
let(:license_scan_build) { create(:ee_ci_build, :license_scan_v2_1, :success) }
specify { expect(subject[:added]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(subject[:added].count).to eq(3) }
specify { expect(subject[:removed]).to be_empty }
specify { expect(subject[:unchanged]).to be_empty }
specify { expect(diff[:added]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(diff[:added].count).to eq(3) }
specify { expect(diff[:removed]).to be_empty }
specify { expect(diff[:unchanged]).to be_empty }
end
context "when nothing has changed between the head and the base pipeline" do
subject { project.license_compliance(head_pipeline).diff_with(base_compliance) }
subject(:diff) { license_compliance.diff_with(base_compliance) }
let(:pipeline) { head_pipeline }
let!(:head_compliance) { project.license_compliance(head_pipeline) }
let!(:head_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :license_scan_v2_1, :success)]) }
......@@ -383,14 +403,16 @@ RSpec.describe SCA::LicenseCompliance do
let!(:base_compliance) { project.license_compliance(base_pipeline) }
let!(:base_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :license_scan_v2_1, :success)]) }
specify { expect(subject[:added]).to be_empty }
specify { expect(subject[:removed]).to be_empty }
specify { expect(subject[:unchanged]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(subject[:unchanged].count).to eq(3) }
specify { expect(diff[:added]).to be_empty }
specify { expect(diff[:removed]).to be_empty }
specify { expect(diff[:unchanged]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(diff[:unchanged].count).to eq(3) }
end
context "when the base pipeline removed some licenses" do
subject { project.license_compliance(head_pipeline).diff_with(base_compliance) }
subject(:diff) { license_compliance.diff_with(base_compliance) }
let(:pipeline) { head_pipeline }
let!(:head_compliance) { project.license_compliance(head_pipeline) }
let!(:head_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :license_scan_v2_1, :success)]) }
......@@ -398,14 +420,16 @@ RSpec.describe SCA::LicenseCompliance do
let!(:base_compliance) { project.license_compliance(base_pipeline) }
let!(:base_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :success)]) }
specify { expect(subject[:added]).to be_empty }
specify { expect(subject[:unchanged]).to be_empty }
specify { expect(subject[:removed]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(subject[:removed].count).to eq(3) }
specify { expect(diff[:added]).to be_empty }
specify { expect(diff[:unchanged]).to be_empty }
specify { expect(diff[:removed]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(diff[:removed].count).to eq(3) }
end
context "when the base pipeline added some licenses" do
subject { project.license_compliance(head_pipeline).diff_with(base_compliance) }
subject(:diff) { license_compliance.diff_with(base_compliance) }
let(:pipeline) { head_pipeline }
let!(:head_compliance) { project.license_compliance(head_pipeline) }
let!(:head_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :success)]) }
......@@ -413,17 +437,17 @@ RSpec.describe SCA::LicenseCompliance do
let!(:base_compliance) { project.license_compliance(base_pipeline) }
let!(:base_pipeline) { create(:ci_pipeline, :success, project: project, builds: [create(:ee_ci_build, :license_scan_v2_1, :success)]) }
specify { expect(subject[:added]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(subject[:added].count).to eq(3) }
specify { expect(subject[:removed]).to be_empty }
specify { expect(subject[:unchanged]).to be_empty }
specify { expect(diff[:added]).to all(be_instance_of(::SCA::LicensePolicy)) }
specify { expect(diff[:added].count).to eq(3) }
specify { expect(diff[:removed]).to be_empty }
specify { expect(diff[:unchanged]).to be_empty }
context "when a software license record does not have an spdx identifier" do
let(:license_name) { 'MIT License' }
let!(:policy) { create(:software_license_policy, :allowed, project: project, software_license: create(:software_license, name: license_name)) }
it "falls back to matching detections based on name rather than spdx id" do
mit = subject[:added].find { |item| item.name == license_name }
mit = diff[:added].find { |item| item.name == license_name }
expect(mit).to be_present
expect(mit.classification).to eql('allowed')
......
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