Commit 089913d1 authored by Fatih Acet's avatar Fatih Acet

Merge branch '32030-move-licence-complience-to-the-backend-FE' into 'master'

Moves the license compliance reports to the Backend

Closes #32030

See merge request gitlab-org/gitlab!17905
parents 73ee3034 bfbc4f78
---
title: Moves the license compliance reports to the Backend
merge_request: 17905
author:
type: other
...@@ -15,6 +15,7 @@ export default () => { ...@@ -15,6 +15,7 @@ export default () => {
canManageLicenses, canManageLicenses,
apiUrl, apiUrl,
licenseManagementSettingsPath, licenseManagementSettingsPath,
licensesApiPath,
} = licensesTab.dataset; } = licensesTab.dataset;
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
...@@ -27,6 +28,7 @@ export default () => { ...@@ -27,6 +28,7 @@ export default () => {
return createElement('license-report-app', { return createElement('license-report-app', {
props: { props: {
apiUrl, apiUrl,
licensesApiPath,
licenseManagementSettingsPath, licenseManagementSettingsPath,
headPath: licenseHeadPath, headPath: licenseHeadPath,
canManageLicenses: parseBoolean(canManageLicenses), canManageLicenses: parseBoolean(canManageLicenses),
......
...@@ -145,6 +145,9 @@ export default { ...@@ -145,6 +145,9 @@ export default {
!this.mr.autoMergeEnabled !this.mr.autoMergeEnabled
); );
}, },
licensesApiPath() {
return (gl && gl.mrWidgetData && gl.mrWidgetData.license_management_comparison_path) || null;
},
}, },
created() { created() {
if (this.shouldRenderCodeQuality) { if (this.shouldRenderCodeQuality) {
...@@ -297,6 +300,7 @@ export default { ...@@ -297,6 +300,7 @@ export default {
<mr-widget-licenses <mr-widget-licenses
v-if="shouldRenderLicenseReport" v-if="shouldRenderLicenseReport"
:api-url="mr.licenseManagement.managed_licenses_path" :api-url="mr.licenseManagement.managed_licenses_path"
:licenses-api-path="licensesApiPath"
:pipeline-path="mr.pipeline.path" :pipeline-path="mr.pipeline.path"
:can-manage-licenses="mr.licenseManagement.can_manage_licenses" :can-manage-licenses="mr.licenseManagement.can_manage_licenses"
:full-report-path="mr.licenseManagement.license_management_full_report_path" :full-report-path="mr.licenseManagement.license_management_full_report_path"
......
...@@ -44,6 +44,11 @@ export default { ...@@ -44,6 +44,11 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
licensesApiPath: {
type: String,
required: false,
default: '',
},
canManageLicenses: { canManageLicenses: {
type: Boolean, type: Boolean,
required: true, required: true,
...@@ -79,20 +84,30 @@ export default { ...@@ -79,20 +84,30 @@ export default {
}, },
}, },
mounted() { mounted() {
const { headPath, basePath, apiUrl, canManageLicenses } = this; const { headPath, basePath, apiUrl, canManageLicenses, licensesApiPath } = this;
this.setAPISettings({ this.setAPISettings({
apiUrlManageLicenses: apiUrl, apiUrlManageLicenses: apiUrl,
headPath, headPath,
basePath, basePath,
canManageLicenses, canManageLicenses,
licensesApiPath,
}); });
if (gon.features && gon.features.parsedLicenseReport) {
this.loadParsedLicenseReport();
} else {
this.loadLicenseReport(); this.loadLicenseReport();
this.loadManagedLicenses(); this.loadManagedLicenses();
}
}, },
methods: { methods: {
...mapActions(['setAPISettings', 'loadManagedLicenses', 'loadLicenseReport']), ...mapActions([
'setAPISettings',
'loadManagedLicenses',
'loadLicenseReport',
'loadParsedLicenseReport',
]),
}, },
}; };
</script> </script>
......
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { LICENSE_APPROVAL_STATUS } from '../constants'; import { LICENSE_APPROVAL_STATUS } from '../constants';
import { convertToOldReportFormat } from './utils';
import { pollUntilComplete } from '../../security_reports/store/utils';
export const setAPISettings = ({ commit }, data) => { export const setAPISettings = ({ commit }, data) => {
commit(types.SET_API_SETTINGS, data); commit(types.SET_API_SETTINGS, data);
...@@ -61,6 +63,29 @@ export const loadManagedLicenses = ({ dispatch, state }) => { ...@@ -61,6 +63,29 @@ export const loadManagedLicenses = ({ dispatch, state }) => {
}); });
}; };
export const requestLoadParsedLicenseReport = ({ commit }) => {
commit(types.REQUEST_LOAD_PARSED_LICENSE_REPORT);
};
export const receiveLoadParsedLicenseReport = ({ commit }, reports) => {
commit(types.RECEIVE_LOAD_PARSED_LICENSE_REPORT, reports);
};
export const receiveLoadParsedLicenseReportError = ({ commit }, error) => {
commit(types.RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR, error);
};
export const loadParsedLicenseReport = ({ dispatch, state }) => {
dispatch('requestLoadParsedLicenseReport');
pollUntilComplete(state.licensesApiPath)
.then(({ data }) => {
const newLicenses = (data.new_licenses || data).map(convertToOldReportFormat);
const existingLicenses = (data.existing_licenses || []).map(convertToOldReportFormat);
dispatch('receiveLoadParsedLicenseReport', { newLicenses, existingLicenses });
})
.catch(() => {
dispatch('receiveLoadLicenseReportError');
});
};
export const requestLoadLicenseReport = ({ commit }) => { export const requestLoadLicenseReport = ({ commit }) => {
commit(types.REQUEST_LOAD_LICENSE_REPORT); commit(types.REQUEST_LOAD_LICENSE_REPORT);
}; };
......
...@@ -4,12 +4,15 @@ import { parseLicenseReportMetrics } from './utils'; ...@@ -4,12 +4,15 @@ import { parseLicenseReportMetrics } from './utils';
export const isLoading = state => state.isLoadingManagedLicenses || state.isLoadingLicenseReport; export const isLoading = state => state.isLoadingManagedLicenses || state.isLoadingLicenseReport;
export const licenseReport = state => export const licenseReport = state =>
parseLicenseReportMetrics(state.headReport, state.baseReport, state.managedLicenses); gon.features && gon.features.parsedLicenseReport
? state.newLicenses
: parseLicenseReportMetrics(state.headReport, state.baseReport, state.managedLicenses);
export const licenseSummaryText = (state, getters) => { export const licenseSummaryText = (state, getters) => {
const hasReportItems = getters.licenseReport && getters.licenseReport.length; const hasReportItems = getters.licenseReport && getters.licenseReport.length;
const baseReportHasLicenses = const baseReportHasLicenses =
state.baseReport && state.baseReport.licenses && state.baseReport.licenses.length; state.existingLicenses.length ||
(state.baseReport && state.baseReport.licenses && state.baseReport.licenses.length);
if (getters.isLoading) { if (getters.isLoading) {
return sprintf(s__('ciReport|Loading %{reportName} report'), { return sprintf(s__('ciReport|Loading %{reportName} report'), {
......
export const SET_API_SETTINGS = 'SET_API_SETTINGS';
export const RECEIVE_DELETE_LICENSE = 'RECEIVE_DELETE_LICENSE'; export const RECEIVE_DELETE_LICENSE = 'RECEIVE_DELETE_LICENSE';
export const RECEIVE_DELETE_LICENSE_ERROR = 'RECEIVE_DELETE_LICENSE_ERROR'; export const RECEIVE_DELETE_LICENSE_ERROR = 'RECEIVE_DELETE_LICENSE_ERROR';
export const RECEIVE_LOAD_LICENSE_REPORT = 'RECEIVE_LOAD_LICENSE_REPORT';
export const RECEIVE_LOAD_LICENSE_REPORT_ERROR = 'RECEIVE_LOAD_LICENSE_REPORT_ERROR';
export const RECEIVE_LOAD_MANAGED_LICENSES = 'RECEIVE_LOAD_MANAGED_LICENSES'; export const RECEIVE_LOAD_MANAGED_LICENSES = 'RECEIVE_LOAD_MANAGED_LICENSES';
export const RECEIVE_LOAD_MANAGED_LICENSES_ERROR = 'RECEIVE_LOAD_MANAGED_LICENSES_ERROR'; export const RECEIVE_LOAD_MANAGED_LICENSES_ERROR = 'RECEIVE_LOAD_MANAGED_LICENSES_ERROR';
export const RECEIVE_LOAD_PARSED_LICENSE_REPORT = 'RECEIVE_LOAD_PARSED_LICENSE_REPORT';
export const RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR = 'RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR';
export const RECEIVE_SET_LICENSE_APPROVAL = 'RECEIVE_SET_LICENSE_APPROVAL'; export const RECEIVE_SET_LICENSE_APPROVAL = 'RECEIVE_SET_LICENSE_APPROVAL';
export const RECEIVE_SET_LICENSE_APPROVAL_ERROR = 'RECEIVE_SET_LICENSE_APPROVAL_ERROR'; export const RECEIVE_SET_LICENSE_APPROVAL_ERROR = 'RECEIVE_SET_LICENSE_APPROVAL_ERROR';
export const RECEIVE_LOAD_LICENSE_REPORT = 'RECEIVE_LOAD_LICENSE_REPORT';
export const RECEIVE_LOAD_LICENSE_REPORT_ERROR = 'RECEIVE_LOAD_LICENSE_REPORT_ERROR';
export const REQUEST_DELETE_LICENSE = 'REQUEST_DELETE_LICENSE'; export const REQUEST_DELETE_LICENSE = 'REQUEST_DELETE_LICENSE';
export const REQUEST_LOAD_LICENSE_REPORT = 'REQUEST_LOAD_LICENSE_REPORT';
export const REQUEST_LOAD_MANAGED_LICENSES = 'REQUEST_LOAD_MANAGED_LICENSES'; export const REQUEST_LOAD_MANAGED_LICENSES = 'REQUEST_LOAD_MANAGED_LICENSES';
export const REQUEST_LOAD_PARSED_LICENSE_REPORT = 'REQUEST_LOAD_PARSED_LICENSE_REPORT';
export const REQUEST_SET_LICENSE_APPROVAL = 'REQUEST_SET_LICENSE_APPROVAL'; export const REQUEST_SET_LICENSE_APPROVAL = 'REQUEST_SET_LICENSE_APPROVAL';
export const REQUEST_LOAD_LICENSE_REPORT = 'REQUEST_LOAD_LICENSE_REPORT';
export const SET_LICENSE_IN_MODAL = 'SET_LICENSE_IN_MODAL';
export const RESET_LICENSE_IN_MODAL = 'RESET_LICENSE_IN_MODAL'; export const RESET_LICENSE_IN_MODAL = 'RESET_LICENSE_IN_MODAL';
export const SET_API_SETTINGS = 'SET_API_SETTINGS';
export const SET_LICENSE_IN_MODAL = 'SET_LICENSE_IN_MODAL';
// 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 () => {};
...@@ -38,6 +38,26 @@ export default { ...@@ -38,6 +38,26 @@ export default {
}); });
}, },
[types.RECEIVE_LOAD_PARSED_LICENSE_REPORT](state, { newLicenses, existingLicenses }) {
Object.assign(state, {
newLicenses,
existingLicenses,
isLoadingLicenseReport: false,
loadLicenseReportError: false,
});
},
[types.RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR](state, error) {
Object.assign(state, {
isLoadingLicenseReport: false,
loadLicenseReportError: error,
});
},
[types.REQUEST_LOAD_PARSED_LICENSE_REPORT](state) {
Object.assign(state, {
isLoadingLicenseReport: true,
});
},
[types.RECEIVE_LOAD_LICENSE_REPORT](state, reports) { [types.RECEIVE_LOAD_LICENSE_REPORT](state, reports) {
const { headReport, baseReport } = reports; const { headReport, baseReport } = reports;
......
export default () => ({ export default () => ({
apiUrlManageLicenses: null, apiUrlManageLicenses: null,
headPath: null, licensesApiPath: null,
basePath: null, basePath: null,
managedLicenses: [],
headReport: null,
baseReport: null, baseReport: null,
canManageLicenses: false,
currentLicenseInModal: null, currentLicenseInModal: null,
headPath: null,
headReport: null,
isDeleting: false, isDeleting: false,
isLoadingManagedLicenses: false,
isLoadingLicenseReport: false, isLoadingLicenseReport: false,
isLoadingManagedLicenses: false,
isSaving: false, isSaving: false,
loadManagedLicensesError: false,
loadLicenseReportError: false, loadLicenseReportError: false,
canManageLicenses: false, loadManagedLicensesError: false,
managedLicenses: [],
newLicenses: [],
existingLicenses: [],
}); });
...@@ -154,3 +154,26 @@ export const getPackagesString = (packages, truncate, maxPackages) => { ...@@ -154,3 +154,26 @@ export const getPackagesString = (packages, truncate, maxPackages) => {
lastPackage, lastPackage,
}); });
}; };
/**
* This converts the newer licence format into the old one so we can use it with our older components.
*
* NOTE: This helper is temporary and can be removed once we flip the `parsedLicenseReport` feature flag
* The below issue is for tracking its removal:
* https://gitlab.com/gitlab-org/gitlab/issues/33878
*
* @param {Object} license The license in the newer format that needs converting
* @returns {Object} The converted license;
*/
export const convertToOldReportFormat = license => {
const approvalStatus = license.classification.approval_status;
return {
...license,
approvalStatus,
id: license.classification.id,
packages: license.dependencies,
status: getIssueStatusFromLicenseStatus(approvalStatus),
};
};
...@@ -457,7 +457,11 @@ export const pollUntilComplete = endpoint => ...@@ -457,7 +457,11 @@ export const pollUntilComplete = endpoint =>
const eTagPoll = new Poll({ const eTagPoll = new Poll({
resource: { resource: {
getReports(url) { getReports(url) {
return axios.get(url); return axios.get(url, {
headers: {
'Content-Type': 'application/json',
},
});
}, },
}, },
data: endpoint, data: endpoint,
......
...@@ -39,6 +39,7 @@ describe('License Report MR Widget', () => { ...@@ -39,6 +39,7 @@ describe('License Report MR Widget', () => {
errorText: 'ERROR', errorText: 'ERROR',
headPath: `${TEST_HOST}/head.json`, headPath: `${TEST_HOST}/head.json`,
basePath: `${TEST_HOST}/head.json`, basePath: `${TEST_HOST}/head.json`,
licensesApiPath: `${TEST_HOST}/parsed_license_report.json`,
canManageLicenses: true, canManageLicenses: true,
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`,
...@@ -49,6 +50,7 @@ describe('License Report MR Widget', () => { ...@@ -49,6 +50,7 @@ describe('License Report MR Widget', () => {
setAPISettings: () => {}, setAPISettings: () => {},
loadManagedLicenses: () => {}, loadManagedLicenses: () => {},
loadLicenseReport: () => {}, loadLicenseReport: () => {},
loadParsedLicenseReport: () => {},
}; };
const mountComponent = ({ const mountComponent = ({
...@@ -73,6 +75,12 @@ describe('License Report MR Widget', () => { ...@@ -73,6 +75,12 @@ describe('License Report MR Widget', () => {
vm.$destroy(); vm.$destroy();
}); });
describe('with the `parsedLicenseReport` feature flag turned off', () => {
beforeAll(() => {
gon.features = gon.features || {};
gon.features.parsedLicenseReport = false;
});
describe('computed', () => { describe('computed', () => {
describe('hasLicenseReportIssues', () => { describe('hasLicenseReportIssues', () => {
it('should be false, if the report is empty', () => { it('should be false, if the report is empty', () => {
...@@ -217,6 +225,9 @@ describe('License Report MR Widget', () => { ...@@ -217,6 +225,9 @@ describe('License Report MR Widget', () => {
setAPISettings: jasmine.createSpy('setAPISettings').and.callFake(() => {}), setAPISettings: jasmine.createSpy('setAPISettings').and.callFake(() => {}),
loadManagedLicenses: jasmine.createSpy('loadManagedLicenses').and.callFake(() => {}), loadManagedLicenses: jasmine.createSpy('loadManagedLicenses').and.callFake(() => {}),
loadLicenseReport: jasmine.createSpy('loadLicenseReport').and.callFake(() => {}), loadLicenseReport: jasmine.createSpy('loadLicenseReport').and.callFake(() => {}),
loadParsedLicenseReport: jasmine
.createSpy('loadParsedLicenseReport')
.and.callFake(() => {}),
}; };
vm = mountComponent({ actions }); vm = mountComponent({ actions });
...@@ -226,6 +237,7 @@ describe('License Report MR Widget', () => { ...@@ -226,6 +237,7 @@ describe('License Report MR Widget', () => {
apiUrlManageLicenses: apiUrl, apiUrlManageLicenses: apiUrl,
headPath: defaultProps.headPath, headPath: defaultProps.headPath,
basePath: defaultProps.basePath, basePath: defaultProps.basePath,
licensesApiPath: defaultProps.licensesApiPath,
canManageLicenses: true, canManageLicenses: true,
}, },
undefined, undefined,
...@@ -242,5 +254,53 @@ describe('License Report MR Widget', () => { ...@@ -242,5 +254,53 @@ describe('License Report MR Widget', () => {
undefined, undefined,
undefined, undefined,
); );
expect(actions.loadParsedLicenseReport).not.toHaveBeenCalled();
});
});
describe('with the `parsedLicenseReport` feature flag turned on', () => {
beforeAll(() => {
gon.features = gon.features || {};
gon.features.parsedLicenseReport = true;
});
afterAll(() => {
gon.features.parsedLicenseReport = false;
});
it('should load the reports from the backend API', () => {
const actions = {
setAPISettings: jasmine.createSpy('setAPISettings').and.callFake(() => {}),
loadManagedLicenses: jasmine.createSpy('loadManagedLicenses').and.callFake(() => {}),
loadLicenseReport: jasmine.createSpy('loadLicenseReport').and.callFake(() => {}),
loadParsedLicenseReport: jasmine
.createSpy('loadParsedLicenseReport')
.and.callFake(() => {}),
};
vm = mountComponent({ actions });
expect(actions.setAPISettings).toHaveBeenCalledWith(
jasmine.any(Object),
{
apiUrlManageLicenses: apiUrl,
headPath: defaultProps.headPath,
basePath: defaultProps.basePath,
licensesApiPath: defaultProps.licensesApiPath,
canManageLicenses: true,
},
undefined,
);
expect(actions.loadParsedLicenseReport).toHaveBeenCalledWith(
jasmine.any(Object),
undefined,
undefined,
);
expect(actions.loadLicenseReport).not.toHaveBeenCalled();
expect(actions.loadManagedLicenses).not.toHaveBeenCalled();
});
}); });
}); });
...@@ -601,4 +601,200 @@ describe('License store actions', () => { ...@@ -601,4 +601,200 @@ describe('License store actions', () => {
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe('requestLoadParsedLicenseReport', () => {
it(`should commit ${mutationTypes.REQUEST_LOAD_PARSED_LICENSE_REPORT}`, done => {
testAction(
actions.requestLoadParsedLicenseReport,
null,
state,
[{ type: mutationTypes.REQUEST_LOAD_PARSED_LICENSE_REPORT }],
[],
)
.then(done)
.catch(done.fail);
});
});
describe('receiveLoadParsedLicenseReport', () => {
it(`should commit ${mutationTypes.RECEIVE_LOAD_PARSED_LICENSE_REPORT} with the correct payload`, done => {
const payload = { newLicenses: [{ name: 'foo' }] };
testAction(
actions.receiveLoadParsedLicenseReport,
payload,
state,
[{ type: mutationTypes.RECEIVE_LOAD_PARSED_LICENSE_REPORT, payload }],
[],
)
.then(done)
.catch(done.fail);
});
});
describe('receiveLoadParsedLicenseReportError', () => {
it(`should commit ${mutationTypes.RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR}`, done => {
const payload = new Error('Test');
testAction(
actions.receiveLoadParsedLicenseReportError,
payload,
state,
[{ type: mutationTypes.RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR, payload }],
[],
)
.then(done)
.catch(done.fail);
});
});
describe('loadParsedLicenseReport', () => {
const licensesApiPath = `${TEST_HOST}/licensesApiPath`;
let licensesApiMock;
let rawLicenseReport;
beforeEach(() => {
licensesApiMock = axiosMock.onGet(licensesApiPath);
state = {
...createState(),
licensesApiPath,
};
});
describe('pipeline reports', () => {
beforeEach(() => {
rawLicenseReport = [
{
name: 'MIT',
classification: { id: 2, approval_status: 'blacklisted', name: 'MIT' },
dependencies: [{ name: 'vue' }],
count: 1,
url: 'http://opensource.org/licenses/mit-license',
},
];
});
it('should fetch, parse, and dispatch the new licenses on a successful request', done => {
licensesApiMock.replyOnce(() => [200, rawLicenseReport]);
const parsedLicenses = {
existingLicenses: [],
newLicenses: [
{
...rawLicenseReport[0],
id: 2,
approvalStatus: 'blacklisted',
packages: [{ name: 'vue' }],
status: 'failed',
},
],
};
testAction(
actions.loadParsedLicenseReport,
null,
state,
[],
[
{ type: 'requestLoadParsedLicenseReport' },
{ type: 'receiveLoadParsedLicenseReport', payload: parsedLicenses },
],
)
.then(done)
.catch(done.fail);
});
it('should send an error on an unsuccesful request', done => {
licensesApiMock.replyOnce(400);
testAction(
actions.loadParsedLicenseReport,
null,
state,
[],
[{ type: 'requestLoadParsedLicenseReport' }, { type: 'receiveLoadLicenseReportError' }],
)
.then(done)
.catch(done.fail);
});
});
describe('MR widget reports', () => {
beforeEach(() => {
rawLicenseReport = {
new_licenses: [
{
name: 'Apache 2.0',
classification: { id: 1, approval_status: 'approved', name: 'Apache 2.0' },
dependencies: [{ name: 'echarts' }],
count: 1,
url: 'http://www.apache.org/licenses/LICENSE-2.0.txt',
},
{
name: 'New BSD',
classification: { id: 3, approval_status: 'unclassified', name: 'New BSD' },
dependencies: [{ name: 'zrender' }],
count: 1,
url: 'http://opensource.org/licenses/BSD-3-Clause',
},
],
existing_licenses: [
{
name: 'MIT',
classification: { id: 2, approval_status: 'blacklisted', name: 'MIT' },
dependencies: [{ name: 'vue' }],
count: 1,
url: 'http://opensource.org/licenses/mit-license',
},
],
removed_licenses: [],
};
});
it('should fetch, parse, and dispatch the new licenses on a successful request', done => {
licensesApiMock.replyOnce(() => [200, rawLicenseReport]);
const parsedLicenses = {
existingLicenses: [
{
...rawLicenseReport.existing_licenses[0],
id: 2,
approvalStatus: 'blacklisted',
packages: [{ name: 'vue' }],
status: 'failed',
},
],
newLicenses: [
{
...rawLicenseReport.new_licenses[0],
id: 1,
approvalStatus: 'approved',
packages: [{ name: 'echarts' }],
status: 'success',
},
{
...rawLicenseReport.new_licenses[1],
id: 3,
approvalStatus: 'unclassified',
packages: [{ name: 'zrender' }],
status: 'neutral',
},
],
};
testAction(
actions.loadParsedLicenseReport,
null,
state,
[],
[
{ type: 'requestLoadParsedLicenseReport' },
{ type: 'receiveLoadParsedLicenseReport', payload: parsedLicenses },
],
)
.then(done)
.catch(done.fail);
});
});
});
}); });
import createState from 'ee/vue_shared/license_management/store/state';
import * as getters from 'ee/vue_shared/license_management/store/getters'; import * as getters from 'ee/vue_shared/license_management/store/getters';
import { parseLicenseReportMetrics } from 'ee/vue_shared/license_management/store/utils'; import { parseLicenseReportMetrics } from 'ee/vue_shared/license_management/store/utils';
...@@ -9,9 +10,11 @@ import { ...@@ -9,9 +10,11 @@ import {
} from 'ee_spec/license_management/mock_data'; } from 'ee_spec/license_management/mock_data';
describe('getters', () => { describe('getters', () => {
let state;
describe('isLoading', () => { describe('isLoading', () => {
it('is true if `isLoadingManagedLicenses` is true OR `isLoadingLicenseReport` is true', () => { it('is true if `isLoadingManagedLicenses` is true OR `isLoadingLicenseReport` is true', () => {
const state = {}; state = createState();
state.isLoadingManagedLicenses = true; state.isLoadingManagedLicenses = true;
state.isLoadingLicenseReport = true; state.isLoadingLicenseReport = true;
...@@ -32,14 +35,21 @@ describe('getters', () => { ...@@ -32,14 +35,21 @@ describe('getters', () => {
}); });
describe('licenseReport', () => { describe('licenseReport', () => {
describe('with parsedLicenseReport set to false', () => {
beforeAll(() => {
gon.features = gon.features || {};
gon.features.parsedLicenseReport = false;
});
it('returns empty array, if the reports are empty', () => { it('returns empty array, if the reports are empty', () => {
const state = { headReport: {}, baseReport: {}, managedLicenses: [] }; state = { ...createState(), headReport: {}, baseReport: {}, managedLicenses: [] };
expect(getters.licenseReport(state)).toEqual([]); expect(getters.licenseReport(state)).toEqual([]);
}); });
it('returns license report, if the license report is not loading', () => { it('returns license report, if the license report is not loading', () => {
const state = { state = {
...createState(),
headReport: licenseHeadIssues, headReport: licenseHeadIssues,
baseReport: licenseBaseIssues, baseReport: licenseBaseIssues,
managedLicenses: [approvedLicense], managedLicenses: [approvedLicense],
...@@ -51,13 +61,35 @@ describe('getters', () => { ...@@ -51,13 +61,35 @@ describe('getters', () => {
}); });
}); });
describe('with parsedLicenseReport set to true', () => {
beforeAll(() => {
gon.features = gon.features || {};
gon.features.parsedLicenseReport = true;
});
afterAll(() => {
gon.features.parsedLicenseReport = false;
});
it('should return the new licenses from the state', () => {
const newLicenses = { test: 'foo' };
state = { ...createState(), newLicenses };
expect(getters.licenseReport(state)).toBe(newLicenses);
});
});
});
describe('licenseSummaryText', () => { describe('licenseSummaryText', () => {
describe('when licenses exist on both the HEAD and the BASE', () => { describe('when licenses exist on both the HEAD and the BASE', () => {
const state = { beforeEach(() => {
state = {
...createState(),
loadLicenseReportError: null, loadLicenseReportError: null,
headReport: licenseHeadIssues, headReport: licenseHeadIssues,
baseReport: licenseBaseIssues, baseReport: licenseBaseIssues,
}; };
});
it('should be `Loading License Compliance report` text if isLoading', () => { it('should be `Loading License Compliance report` text if isLoading', () => {
const mockGetters = {}; const mockGetters = {};
...@@ -70,10 +102,11 @@ describe('getters', () => { ...@@ -70,10 +102,11 @@ describe('getters', () => {
it('should be `Failed to load License Compliance report` text if an error has happened', () => { it('should be `Failed to load License Compliance report` text if an error has happened', () => {
const mockGetters = {}; const mockGetters = {};
state.loadLicenseReportError = new Error('Test');
expect( expect(getters.licenseSummaryText(state, mockGetters)).toBe(
getters.licenseSummaryText({ loadLicenseReportError: new Error('Test') }, mockGetters), 'Failed to load License Compliance report',
).toBe('Failed to load License Compliance report'); );
}); });
it('should be `License Compliance detected no new licenses`, if the report is empty', () => { it('should be `License Compliance detected no new licenses`, if the report is empty', () => {
...@@ -102,7 +135,9 @@ describe('getters', () => { ...@@ -102,7 +135,9 @@ describe('getters', () => {
}); });
describe('when there are no licences on the BASE', () => { describe('when there are no licences on the BASE', () => {
const state = { baseReport: {} }; beforeEach(() => {
state = { ...createState(), baseReport: {} };
});
it('should be `License Compliance detected no licenses for the source branch only` with no new licences', () => { it('should be `License Compliance detected no licenses for the source branch only` with no new licences', () => {
const mockGetters = { licenseReport: [] }; const mockGetters = { licenseReport: [] };
......
...@@ -229,4 +229,53 @@ describe('License store mutations', () => { ...@@ -229,4 +229,53 @@ describe('License store mutations', () => {
expect(store.state.isLoadingLicenseReport).toBe(true); expect(store.state.isLoadingLicenseReport).toBe(true);
}); });
}); });
describe('RECEIVE_LOAD_PARSED_LICENSE_REPORT', () => {
const newLicenses = [];
const existingLicenses = [];
beforeEach(() => {
store.state.isLoadingLicenseReport = true;
store.state.loadLicenseReportError = new Error('test');
store.commit(types.RECEIVE_LOAD_PARSED_LICENSE_REPORT, { newLicenses, existingLicenses });
});
it('should set the new and existing reports', () => {
expect(store.state.newLicenses).toBe(newLicenses);
expect(store.state.existingLicenses).toBe(existingLicenses);
});
it('should cancel loading and clear any errors', () => {
expect(store.state.isLoadingLicenseReport).toBe(false);
expect(store.state.loadLicenseReportError).toBe(false);
});
});
describe('RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR', () => {
const error = new Error('test');
beforeEach(() => {
store.state.isLoadingLicenseReport = true;
store.state.loadLicenseReportError = false;
store.commit(types.RECEIVE_LOAD_PARSED_LICENSE_REPORT_ERROR, error);
});
it('should set the error on the state', () => {
expect(store.state.loadLicenseReportError).toBe(error);
});
it('should cancel loading', () => {
expect(store.state.isLoadingLicenseReport).toBe(false);
});
});
describe('REQUEST_LOAD_PARSED_LICENSE_REPORT', () => {
beforeEach(() => {
store.state.isLoadingLicenseReport = false;
store.commit(types.REQUEST_LOAD_PARSED_LICENSE_REPORT);
});
it('should initiate loading', () => {
expect(store.state.isLoadingLicenseReport).toBe(true);
});
});
}); });
...@@ -4,6 +4,7 @@ import { ...@@ -4,6 +4,7 @@ import {
normalizeLicense, normalizeLicense,
getPackagesString, getPackagesString,
getIssueStatusFromLicenseStatus, getIssueStatusFromLicenseStatus,
convertToOldReportFormat,
} from 'ee/vue_shared/license_management/store/utils'; } from 'ee/vue_shared/license_management/store/utils';
import { LICENSE_APPROVAL_STATUS } from 'ee/vue_shared/license_management/constants'; import { LICENSE_APPROVAL_STATUS } from 'ee/vue_shared/license_management/constants';
import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants'; import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '~/reports/constants';
...@@ -164,4 +165,40 @@ describe('utils', () => { ...@@ -164,4 +165,40 @@ describe('utils', () => {
expect(getIssueStatusFromLicenseStatus()).toBe(STATUS_NEUTRAL); expect(getIssueStatusFromLicenseStatus()).toBe(STATUS_NEUTRAL);
}); });
}); });
describe('convertToOldReportFormat', () => {
const rawLicense = {
name: 'license',
classification: {
id: 1,
approval_status: LICENSE_APPROVAL_STATUS.APPROVED,
},
dependencies: [{ id: 1 }, { id: 2 }, { id: 3 }],
};
let parsedLicense;
beforeEach(() => {
parsedLicense = convertToOldReportFormat(rawLicense);
});
it('should get the approval status', () => {
expect(parsedLicense.approvalStatus).toEqual(rawLicense.classification.approval_status);
});
it('should get the packages', () => {
expect(parsedLicense.packages).toEqual(rawLicense.dependencies);
});
it('should get the id', () => {
expect(parsedLicense.id).toEqual(rawLicense.classification.id);
});
it('should get the status', () => {
expect(parsedLicense.status).toEqual(STATUS_SUCCESS);
});
it('should retain the license name', () => {
expect(parsedLicense.name).toEqual(rawLicense.name);
});
});
}); });
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