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 { ...@@ -307,6 +307,7 @@ export default {
:license-management-settings-path="mr.licenseManagement.license_management_settings_path" :license-management-settings-path="mr.licenseManagement.license_management_settings_path"
:base-path="mr.licenseManagement.base_path" :base-path="mr.licenseManagement.base_path"
:head-path="mr.licenseManagement.head_path" :head-path="mr.licenseManagement.head_path"
:security-approvals-help-page-path="mr.securityApprovalsHelpPagePath"
report-section-class="mr-widget-border-top" report-section-class="mr-widget-border-top"
/> />
<grouped-test-reports-app <grouped-test-reports-app
......
<script> <script>
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import { GlLink } from '@gitlab/ui';
import ReportSection from '~/reports/components/report_section.vue'; import ReportSection from '~/reports/components/report_section.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin'; import reportsMixin from 'ee/vue_shared/security_reports/mixins/reports_mixin';
...@@ -15,6 +16,7 @@ export default { ...@@ -15,6 +16,7 @@ export default {
componentNames, componentNames,
store, store,
components: { components: {
GlLink,
ReportSection, ReportSection,
SetLicenseApprovalModal, SetLicenseApprovalModal,
Icon, Icon,
...@@ -63,10 +65,20 @@ export default { ...@@ -63,10 +65,20 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
securityApprovalsHelpPagePath: {
type: String,
required: false,
default: '',
},
}, },
computed: { computed: {
...mapState(['loadLicenseReportError']), ...mapState(['loadLicenseReportError']),
...mapGetters(['licenseReport', 'isLoading', 'licenseSummaryText']), ...mapGetters([
'licenseReport',
'isLoading',
'licenseSummaryText',
'reportContainsBlacklistedLicense',
]),
hasLicenseReportIssues() { hasLicenseReportIssues() {
const { licenseReport } = this; const { licenseReport } = this;
return licenseReport && licenseReport.length > 0; return licenseReport && licenseReport.length > 0;
...@@ -116,7 +128,6 @@ export default { ...@@ -116,7 +128,6 @@ export default {
<set-license-approval-modal /> <set-license-approval-modal />
<report-section <report-section
:status="licenseReportStatus" :status="licenseReportStatus"
:success-text="licenseSummaryText"
:loading-text="licenseSummaryText" :loading-text="licenseSummaryText"
:error-text="licenseSummaryText" :error-text="licenseSummaryText"
:neutral-issues="licenseReport" :neutral-issues="licenseReport"
...@@ -126,6 +137,17 @@ export default { ...@@ -126,6 +137,17 @@ export default {
:always-open="alwaysOpen" :always-open="alwaysOpen"
class="license-report-widget mr-report" 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"> <div v-if="showActionButtons" slot="actionButtons" class="append-right-default">
<a <a
v-if="licenseManagementSettingsPath" v-if="licenseManagementSettingsPath"
......
import { n__, s__, sprintf } from '~/locale'; import { n__, s__, sprintf } from '~/locale';
import { parseLicenseReportMetrics } from './utils'; import { parseLicenseReportMetrics } from './utils';
import { LICENSE_APPROVAL_STATUS } from '../constants';
export const isLoading = state => state.isLoadingManagedLicenses || state.isLoadingLicenseReport; export const isLoading = state => state.isLoadingManagedLicenses || state.isLoadingLicenseReport;
...@@ -27,18 +28,32 @@ export const licenseSummaryText = (state, getters) => { ...@@ -27,18 +28,32 @@ export const licenseSummaryText = (state, getters) => {
} }
if (hasReportItems) { if (hasReportItems) {
const licenseReportLength = getters.licenseReport.length;
if (!baseReportHasLicenses) { if (!baseReportHasLicenses) {
return n__( 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 license for the source branch only',
'LicenseCompliance|License Compliance detected %d licenses for the source branch only', 'LicenseCompliance|License Compliance detected %d licenses for the source branch only',
getters.licenseReport.length, licenseReportLength,
); );
} }
return n__( 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 license',
'LicenseCompliance|License Compliance detected %d new licenses', 'LicenseCompliance|License Compliance detected %d new licenses',
getters.licenseReport.length, licenseReportLength,
); );
} }
...@@ -51,5 +66,10 @@ export const licenseSummaryText = (state, getters) => { ...@@ -51,5 +66,10 @@ export const licenseSummaryText = (state, getters) => {
return s__('LicenseCompliance|License Compliance detected no new licenses'); 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 // prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
...@@ -14,6 +14,7 @@ import { ...@@ -14,6 +14,7 @@ import {
describe('License Report MR Widget', () => { describe('License Report MR Widget', () => {
const Component = Vue.extend(LicenseManagement); const Component = Vue.extend(LicenseManagement);
const apiUrl = `${TEST_HOST}/license_management`; const apiUrl = `${TEST_HOST}/license_management`;
const securityApprovalsHelpPagePath = `${TEST_HOST}/path/to/security/approvals/help`;
let vm; let vm;
const defaultState = { const defaultState = {
...@@ -32,6 +33,9 @@ describe('License Report MR Widget', () => { ...@@ -32,6 +33,9 @@ describe('License Report MR Widget', () => {
licenseSummaryText() { licenseSummaryText() {
return 'FOO'; return 'FOO';
}, },
reportContainsBlacklistedLicense() {
return false;
},
}; };
const defaultProps = { const defaultProps = {
...@@ -44,6 +48,7 @@ describe('License Report MR Widget', () => { ...@@ -44,6 +48,7 @@ describe('License Report MR Widget', () => {
licenseManagementSettingsPath: `${TEST_HOST}/lm_settings`, licenseManagementSettingsPath: `${TEST_HOST}/lm_settings`,
fullReportPath: `${TEST_HOST}/path/to/the/full/report`, fullReportPath: `${TEST_HOST}/path/to/the/full/report`,
apiUrl, apiUrl,
securityApprovalsHelpPagePath,
}; };
const defaultActions = { const defaultActions = {
...@@ -257,6 +262,31 @@ describe('License Report MR Widget', () => { ...@@ -257,6 +262,31 @@ describe('License Report MR Widget', () => {
expect(actions.loadParsedLicenseReport).not.toHaveBeenCalled(); 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', () => { describe('with the `parsedLicenseReport` feature flag turned on', () => {
......
...@@ -132,6 +132,17 @@ describe('getters', () => { ...@@ -132,6 +132,17 @@ describe('getters', () => {
'License Compliance detected 2 new licenses', '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', () => { describe('when there are no licences on the BASE', () => {
...@@ -162,6 +173,38 @@ describe('getters', () => { ...@@ -162,6 +173,38 @@ describe('getters', () => {
'License Compliance detected 2 licenses for the source branch only', '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 ...@@ -9814,11 +9814,21 @@ msgid_plural "LicenseCompliance|License Compliance detected %d licenses for the
msgstr[0] "" msgstr[0] ""
msgstr[1] "" 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 "LicenseCompliance|License Compliance detected %d new license"
msgid_plural "LicenseCompliance|License Compliance detected %d new licenses" msgid_plural "LicenseCompliance|License Compliance detected %d new licenses"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" 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" msgid "LicenseCompliance|License Compliance detected no licenses for the source branch only"
msgstr "" 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