Commit 31e817f2 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch '11380-dast-site-array' into 'master'

Handle case where site property is an array in DAST report

Closes #11380

See merge request gitlab-org/gitlab-ee!13775
parents dd3d132a a0cc8721
......@@ -4,6 +4,7 @@ import {
parseSastIssues,
parseDependencyScanningIssues,
filterByKey,
getDastSite,
parseDastIssues,
getUnapprovedVulnerabilities,
findIssueIndex,
......@@ -176,9 +177,11 @@ export default {
},
[types.RECEIVE_DAST_REPORTS](state, reports) {
const headSite = getDastSite(reports.head.site);
if (reports.head && reports.base) {
const headIssues = parseDastIssues(reports.head.site.alerts, reports.enrichData);
const baseIssues = parseDastIssues(reports.base.site.alerts, reports.enrichData);
const baseSite = getDastSite(reports.base.site);
const headIssues = parseDastIssues(headSite.alerts, reports.enrichData);
const baseIssues = parseDastIssues(baseSite.alerts, reports.enrichData);
const filterKey = 'pluginid';
const newIssues = filterByKey(headIssues, baseIssues, filterKey);
const resolvedIssues = filterByKey(baseIssues, headIssues, filterKey);
......@@ -186,8 +189,8 @@ export default {
Vue.set(state.dast, 'newIssues', newIssues);
Vue.set(state.dast, 'resolvedIssues', resolvedIssues);
Vue.set(state.dast, 'isLoading', false);
} else if (reports.head && reports.head.site && !reports.base) {
const newIssues = parseDastIssues(reports.head.site.alerts, reports.enrichData);
} else if (reports.head && headSite && !reports.base) {
const newIssues = parseDastIssues(headSite.alerts, reports.enrichData);
Vue.set(state.dast, 'newIssues', newIssues);
Vue.set(state.dast, 'isLoading', false);
......
......@@ -197,6 +197,14 @@ export const parseDependencyScanningIssues = (report = [], feedback = [], path =
});
};
/**
* Extracts the site property out of a DAST report
* This should be dropped once we support multi-sites reports
*
* @param {Object|Array} site
*/
export const getDastSite = site => (Array.isArray(site) && site.length ? site[0] : site);
/**
* Parses DAST into a common format to allow to use the same Vue component.
* DAST report is currently the straigh output from the underlying tool (ZAProxy)
......
---
title: Handle case where site property is an array in DAST report
merge_request: 13775
author:
type: fixed
......@@ -238,6 +238,10 @@ describe('security reports mutations', () => {
});
describe('RECEIVE_DAST_REPORTS', () => {
const makeDastWithSiteArray = dastReport => ({
site: [dastReport.site],
});
describe('with head and base', () => {
it('sets new and resolved issues with the given data', () => {
mutations[types.RECEIVE_DAST_REPORTS](stateCopy, {
......@@ -250,6 +254,32 @@ describe('security reports mutations', () => {
expect(stateCopy.dast.newIssues).toEqual(parsedDastNewIssues);
expect(stateCopy.dast.resolvedIssues).toEqual([]);
});
it("parses site property if it's an array instead of an object", () => {
const dastWithSiteArray = makeDastWithSiteArray(dast);
const dastBaseWithSiteArray = makeDastWithSiteArray(dastBase);
mutations[types.RECEIVE_DAST_REPORTS](stateCopy, {
head: dastWithSiteArray,
base: dastBaseWithSiteArray,
});
expect(stateCopy.dast.isLoading).toEqual(false);
expect(stateCopy.dast.newIssues).toEqual(parsedDastNewIssues);
expect(stateCopy.dast.resolvedIssues).toEqual([]);
});
it('does not report any vulnerability if site is an empty array', () => {
mutations[types.RECEIVE_DAST_REPORTS](stateCopy, {
head: { site: [] },
base: { site: [] },
});
expect(stateCopy.dast.isLoading).toEqual(false);
expect(stateCopy.dast.newIssues).toEqual([]);
expect(stateCopy.dast.resolvedIssues).toEqual([]);
});
});
describe('with head', () => {
......@@ -261,6 +291,28 @@ describe('security reports mutations', () => {
expect(stateCopy.dast.isLoading).toEqual(false);
expect(stateCopy.dast.newIssues).toEqual(parsedDast);
});
it("parses site property if it's an array instead of an object", () => {
const dastWithSiteArray = makeDastWithSiteArray(dast);
mutations[types.RECEIVE_DAST_REPORTS](stateCopy, {
head: dastWithSiteArray,
});
expect(stateCopy.dast.isLoading).toEqual(false);
expect(stateCopy.dast.newIssues).toEqual(parsedDast);
});
it('does not report any vulnerability if site is an empty array', () => {
mutations[types.RECEIVE_DAST_REPORTS](stateCopy, {
head: { site: [] },
});
expect(stateCopy.dast.isLoading).toEqual(false);
expect(stateCopy.dast.newIssues).toEqual([]);
expect(stateCopy.dast.resolvedIssues).toEqual([]);
});
});
});
......
......@@ -4,6 +4,7 @@ import {
findMatchingRemediations,
parseSastIssues,
parseDependencyScanningIssues,
getDastSite,
parseDastIssues,
filterByKey,
getUnapprovedVulnerabilities,
......@@ -349,6 +350,16 @@ describe('security reports utils', () => {
});
});
describe('getDastSite', () => {
it.each([{}, 'site', 1, [], undefined])('returns argument as is if arg is %p', arg => {
expect(getDastSite(arg)).toEqual(arg);
});
it('returns first item if arg is a non-empty array', () => {
expect(getDastSite([{}])).toEqual({});
});
});
describe('parseDastIssues', () => {
it('parses dast report', () => {
expect(parseDastIssues(dast.site.alerts)).toEqual(parsedDast);
......
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