Commit f67a23d1 authored by Fatih Acet's avatar Fatih Acet

Merge branch '13539-license-compliance-approval-required' into 'master'

Show approval required status in license compliance

Closes #13539

See merge request gitlab-org/gitlab!19114
parents 31ca3288 ae74237e
---
title: Show approval required status in license compliance
merge_request: 19114
author:
type: changed
......@@ -307,6 +307,7 @@ export default {
:license-management-settings-path="mr.licenseManagement.license_management_settings_path"
:base-path="mr.licenseManagement.base_path"
:head-path="mr.licenseManagement.head_path"
:security-approvals-help-page-path="mr.securityApprovalsHelpPagePath"
report-section-class="mr-widget-border-top"
/>
<grouped-test-reports-app
......
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import { GlLink } from '@gitlab/ui';
import ReportSection from '~/reports/components/report_section.vue';
import Icon from '~/vue_shared/components/icon.vue';
import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin';
......@@ -15,6 +16,7 @@ export default {
componentNames,
store,
components: {
GlLink,
ReportSection,
SetLicenseApprovalModal,
Icon,
......@@ -63,10 +65,20 @@ export default {
required: false,
default: false,
},
securityApprovalsHelpPagePath: {
type: String,
required: false,
default: '',
},
},
computed: {
...mapState(['loadLicenseReportError']),
...mapGetters(['licenseReport', 'isLoading', 'licenseSummaryText']),
...mapGetters([
'licenseReport',
'isLoading',
'licenseSummaryText',
'reportContainsBlacklistedLicense',
]),
hasLicenseReportIssues() {
const { licenseReport } = this;
return licenseReport && licenseReport.length > 0;
......@@ -116,7 +128,6 @@ export default {
<set-license-approval-modal />
<report-section
:status="licenseReportStatus"
:success-text="licenseSummaryText"
:loading-text="licenseSummaryText"
:error-text="licenseSummaryText"
:neutral-issues="licenseReport"
......@@ -126,6 +137,17 @@ export default {
:always-open="alwaysOpen"
class="license-report-widget mr-report"
>
<template #success>
{{ licenseSummaryText }}
<gl-link
v-if="reportContainsBlacklistedLicense && securityApprovalsHelpPagePath"
:href="securityApprovalsHelpPagePath"
class="js-security-approval-help-link"
target="_blank"
>
<icon :size="12" name="question" />
</gl-link>
</template>
<div v-if="showActionButtons" slot="actionButtons" class="append-right-default">
<a
v-if="licenseManagementSettingsPath"
......
import { n__, s__, sprintf } from '~/locale';
import { parseLicenseReportMetrics } from './utils';
import { LICENSE_APPROVAL_STATUS } from '../constants';
export const isLoading = state => state.isLoadingManagedLicenses || state.isLoadingLicenseReport;
......@@ -27,19 +28,33 @@ export const licenseSummaryText = (state, getters) => {
}
if (hasReportItems) {
const licenseReportLength = getters.licenseReport.length;
if (!baseReportHasLicenses) {
return n__(
'LicenseCompliance|License Compliance detected %d license for the source branch only',
'LicenseCompliance|License Compliance detected %d licenses for the source branch only',
getters.licenseReport.length,
);
return getters.reportContainsBlacklistedLicense
? n__(
'LicenseCompliance|License Compliance detected %d license for the source branch only; approval required',
'LicenseCompliance|License Compliance detected %d licenses for the source branch only; approval required',
licenseReportLength,
)
: n__(
'LicenseCompliance|License Compliance detected %d license for the source branch only',
'LicenseCompliance|License Compliance detected %d licenses for the source branch only',
licenseReportLength,
);
}
return n__(
'LicenseCompliance|License Compliance detected %d new license',
'LicenseCompliance|License Compliance detected %d new licenses',
getters.licenseReport.length,
);
return getters.reportContainsBlacklistedLicense
? n__(
'LicenseCompliance|License Compliance detected %d new license; approval required',
'LicenseCompliance|License Compliance detected %d new licenses; approval required',
licenseReportLength,
)
: n__(
'LicenseCompliance|License Compliance detected %d new license',
'LicenseCompliance|License Compliance detected %d new licenses',
licenseReportLength,
);
}
if (!baseReportHasLicenses) {
......@@ -51,5 +66,10 @@ export const licenseSummaryText = (state, getters) => {
return s__('LicenseCompliance|License Compliance detected no new licenses');
};
export const reportContainsBlacklistedLicense = (_state, getters) =>
(getters.licenseReport || []).some(
license => license.approvalStatus === LICENSE_APPROVAL_STATUS.BLACKLISTED,
);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -14,6 +14,7 @@ import {
describe('License Report MR Widget', () => {
const Component = Vue.extend(LicenseManagement);
const apiUrl = `${TEST_HOST}/license_management`;
const securityApprovalsHelpPagePath = `${TEST_HOST}/path/to/security/approvals/help`;
let vm;
const defaultState = {
......@@ -32,6 +33,9 @@ describe('License Report MR Widget', () => {
licenseSummaryText() {
return 'FOO';
},
reportContainsBlacklistedLicense() {
return false;
},
};
const defaultProps = {
......@@ -44,6 +48,7 @@ describe('License Report MR Widget', () => {
licenseManagementSettingsPath: `${TEST_HOST}/lm_settings`,
fullReportPath: `${TEST_HOST}/path/to/the/full/report`,
apiUrl,
securityApprovalsHelpPagePath,
};
const defaultActions = {
......@@ -257,6 +262,31 @@ describe('License Report MR Widget', () => {
expect(actions.loadParsedLicenseReport).not.toHaveBeenCalled();
});
describe('approval status', () => {
const findSecurityApprovalHelpLink = () =>
vm.$el.querySelector('.js-security-approval-help-link');
it('does not show a link to security approval help page if report does not contain blacklisted licenses', () => {
expect(findSecurityApprovalHelpLink()).toBeNull();
});
it('shows a link to security approval help page if report contains blacklisted licenses', () => {
const getters = {
...defaultGetters,
reportContainsBlacklistedLicense() {
return true;
},
};
vm = mountComponent({ getters });
const securityApprovalHelpLink = findSecurityApprovalHelpLink();
expect(findSecurityApprovalHelpLink()).not.toBeNull();
expect(securityApprovalHelpLink.getAttribute('href')).toEqual(
securityApprovalsHelpPagePath,
);
});
});
});
describe('with the `parsedLicenseReport` feature flag turned on', () => {
......
......@@ -132,6 +132,17 @@ describe('getters', () => {
'License Compliance detected 2 new licenses',
);
});
it('should be `License Compliance detected 2 new licenses; approval required`, if the report has two elements and including some blacklisted', () => {
const mockGetters = {
licenseReport: [licenseReportMock[0], licenseReportMock[0]],
reportContainsBlacklistedLicense: true,
};
expect(getters.licenseSummaryText(state, mockGetters)).toBe(
'License Compliance detected 2 new licenses; approval required',
);
});
});
describe('when there are no licences on the BASE', () => {
......@@ -162,6 +173,38 @@ describe('getters', () => {
'License Compliance detected 2 licenses for the source branch only',
);
});
it('should be `License Compliance detected 2 licenses for the source branch only; approval required` with two new licences including some blacklisted', () => {
const mockGetters = {
licenseReport: [licenseReportMock[0], licenseReportMock[0]],
reportContainsBlacklistedLicense: true,
};
expect(getters.licenseSummaryText(state, mockGetters)).toBe(
'License Compliance detected 2 licenses for the source branch only; approval required',
);
});
});
});
describe('reportContainsBlacklistedLicense', () => {
it('should be false if the report does not contain blacklisted licenses', () => {
const mockGetters = {
licenseReport: [licenseReportMock[0], licenseReportMock[0]],
};
expect(getters.reportContainsBlacklistedLicense(state, mockGetters)).toBe(false);
});
it('should be true if the report contains blacklisted licenses', () => {
const mockGetters = {
licenseReport: [
licenseReportMock[0],
{ ...licenseReportMock[0], approvalStatus: 'blacklisted' },
],
};
expect(getters.reportContainsBlacklistedLicense(state, mockGetters)).toBe(true);
});
});
});
......@@ -9814,11 +9814,21 @@ msgid_plural "LicenseCompliance|License Compliance detected %d licenses for the
msgstr[0] ""
msgstr[1] ""
msgid "LicenseCompliance|License Compliance detected %d license for the source branch only; approval required"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses for the source branch only; approval required"
msgstr[0] ""
msgstr[1] ""
msgid "LicenseCompliance|License Compliance detected %d new license"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
msgstr[0] ""
msgstr[1] ""
msgid "LicenseCompliance|License Compliance detected %d new license; approval required"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses; approval required"
msgstr[0] ""
msgstr[1] ""
msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
msgstr ""
......
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