Commit 433d959c authored by Alexander Turinske's avatar Alexander Turinske

Update security dashboard scanner columns

- update display values to be human readable
- add utility function to convert report types
- add additional tests
- update changelog
parent 7f716dc0
...@@ -6,6 +6,7 @@ import Icon from '~/vue_shared/components/icon.vue'; ...@@ -6,6 +6,7 @@ import Icon from '~/vue_shared/components/icon.vue';
import VulnerabilityActionButtons from './vulnerability_action_buttons.vue'; import VulnerabilityActionButtons from './vulnerability_action_buttons.vue';
import VulnerabilityIssueLink from './vulnerability_issue_link.vue'; import VulnerabilityIssueLink from './vulnerability_issue_link.vue';
import { DASHBOARD_TYPES } from '../store/constants'; import { DASHBOARD_TYPES } from '../store/constants';
import convertReportType from 'ee/vue_shared/security_reports/store/utils/convert_report_type';
import getPrimaryIdentifier from 'ee/vue_shared/security_reports/store/utils/get_primary_identifier'; import getPrimaryIdentifier from 'ee/vue_shared/security_reports/store/utils/get_primary_identifier';
export default { export default {
...@@ -47,10 +48,6 @@ export default { ...@@ -47,10 +48,6 @@ export default {
} }
return location && (location.image || location.file || location.path); return location && (location.image || location.file || location.path);
}, },
vulnerabilityScanner() {
const { scanner } = this.vulnerability;
return scanner?.name;
},
isDismissed() { isDismissed() {
return Boolean(this.vulnerability.dismissal_feedback); return Boolean(this.vulnerability.dismissal_feedback);
}, },
...@@ -70,6 +67,9 @@ export default { ...@@ -70,6 +67,9 @@ export default {
isSelected() { isSelected() {
return Boolean(this.selectedVulnerabilities[this.vulnerability.id]); return Boolean(this.selectedVulnerabilities[this.vulnerability.id]);
}, },
useConvertReportType() {
return convertReportType(this.vulnerability.report_type);
},
}, },
methods: { methods: {
...mapActions('vulnerabilities', ['openModal', 'selectVulnerability', 'deselectVulnerability']), ...mapActions('vulnerabilities', ['openModal', 'selectVulnerability', 'deselectVulnerability']),
...@@ -152,8 +152,8 @@ export default { ...@@ -152,8 +152,8 @@ export default {
<div class="table-section section-15"> <div class="table-section section-15">
<div class="table-mobile-header" role="rowheader">{{ s__('Reports|Scanner') }}</div> <div class="table-mobile-header" role="rowheader">{{ s__('Reports|Scanner') }}</div>
<div class="table-mobile-content"> <div class="table-mobile-content text-capitalize">
{{ vulnerabilityScanner }} {{ useConvertReportType }}
</div> </div>
</div> </div>
......
import { REPORT_TYPES } from 'ee/security_dashboard/store/constants';
/**
* Takes the report type, that is not human-readable and converts it to be human-readable
* @param {string} reportType that is not human-readable
* @returns {string} the conversion from REPORT_TYPES or a lowercase version without '_' in it to
* be paired with the CSS class `text-capitalize`
*/
const convertReportType = reportType => {
if (!reportType) return '';
const lowerCaseType = reportType.toLowerCase();
return REPORT_TYPES[lowerCaseType] || lowerCaseType.split('_').join(' ');
};
export default convertReportType;
...@@ -6,6 +6,7 @@ import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_ba ...@@ -6,6 +6,7 @@ import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_ba
import SelectionSummary from 'ee/security_dashboard/components/selection_summary.vue'; import SelectionSummary from 'ee/security_dashboard/components/selection_summary.vue';
import IssueLink from './issue_link.vue'; import IssueLink from './issue_link.vue';
import { VULNERABILITIES_PER_PAGE } from '../constants'; import { VULNERABILITIES_PER_PAGE } from '../constants';
import convertReportType from 'ee/vue_shared/security_reports/store/utils/convert_report_type';
export default { export default {
name: 'VulnerabilityList', name: 'VulnerabilityList',
...@@ -156,6 +157,9 @@ export default { ...@@ -156,6 +157,9 @@ export default {
issue(item) { issue(item) {
return item.issueLinks?.nodes[0]?.issue; return item.issueLinks?.nodes[0]?.issue;
}, },
useConvertReportType(reportType) {
return convertReportType(reportType);
},
}, },
VULNERABILITIES_PER_PAGE, VULNERABILITIES_PER_PAGE,
}; };
...@@ -230,7 +234,9 @@ export default { ...@@ -230,7 +234,9 @@ export default {
</template> </template>
<template #cell(reportType)="{ item }"> <template #cell(reportType)="{ item }">
<span class="text-capitalize js-reportType">{{ item.reportType }}</span> <span class="text-capitalize js-reportType">{{
useConvertReportType(item.reportType)
}}</span>
</template> </template>
<template #table-busy> <template #table-busy>
......
--- ---
title: Add scanner name to vulnerability row title: Add scanner type to vulnerability row
merge_request: 31775 merge_request: 35150
author: author:
type: changed type: changed
...@@ -81,12 +81,12 @@ describe('Security Dashboard Table Row', () => { ...@@ -81,12 +81,12 @@ describe('Security Dashboard Table Row', () => {
expect(findContent(2).text()).toContain(vulnerability.identifiers[0].name); expect(findContent(2).text()).toContain(vulnerability.identifiers[0].name);
}); });
it('should render the scanner name', () => { it('should render the report type', () => {
expect( expect(
findContent(2) findContent(2)
.text() .text()
.toLowerCase(), .toLowerCase(),
).toContain(wrapper.props().vulnerability.scanner.name.toLowerCase()); ).toContain(wrapper.props().vulnerability.report_type.toLowerCase());
}); });
describe('the project name', () => { describe('the project name', () => {
......
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
countVulnerabilities, countVulnerabilities,
groupedReportText, groupedReportText,
} from 'ee/vue_shared/security_reports/store/utils'; } from 'ee/vue_shared/security_reports/store/utils';
import convertReportType from 'ee/vue_shared/security_reports/store/utils/convert_report_type';
import filterByKey from 'ee/vue_shared/security_reports/store/utils/filter_by_key'; import filterByKey from 'ee/vue_shared/security_reports/store/utils/filter_by_key';
import getFileLocation from 'ee/vue_shared/security_reports/store/utils/get_file_location'; import getFileLocation from 'ee/vue_shared/security_reports/store/utils/get_file_location';
import { import {
...@@ -44,6 +45,20 @@ describe('security reports utils', () => { ...@@ -44,6 +45,20 @@ describe('security reports utils', () => {
}); });
}); });
describe('convertReportType', () => {
it.each([
['sast', 'SAST'],
['dependency_scanning', 'Dependency Scanning'],
['CONTAINER_SCANNING', 'Container Scanning'],
['CUSTOM_SCANNER', 'custom scanner'],
['mast', 'mast'],
['TAST', 'tast'],
[undefined, ''],
])('converts the report type "%s" to the human-readable string "%s"', (input, output) => {
expect(convertReportType(input)).toEqual(output);
});
});
describe('filterByKey', () => { describe('filterByKey', () => {
it('filters the array with the provided key', () => { it('filters the array with the provided key', () => {
const array1 = [{ id: '1234' }, { id: 'abg543' }, { id: '214swfA' }]; const array1 = [{ id: '1234' }, { id: 'abg543' }, { id: '214swfA' }];
......
export const generateVulnerabilities = () => [ export const generateVulnerabilities = () => [
{ {
id: 'id_0', id: 'id_0',
title: 'Vulnerability 1', title: 'Vulnerability 0',
severity: 'critical', severity: 'critical',
state: 'dismissed', state: 'dismissed',
reportType: 'sast', reportType: 'SAST',
location: { location: {
image: image:
'registry.gitlab.com/groulot/container-scanning-test/master:5f21de6956aee99ddb68ae49498662d9872f50ff', 'registry.gitlab.com/groulot/container-scanning-test/master:5f21de6956aee99ddb68ae49498662d9872f50ff',
...@@ -15,10 +15,10 @@ export const generateVulnerabilities = () => [ ...@@ -15,10 +15,10 @@ export const generateVulnerabilities = () => [
}, },
{ {
id: 'id_1', id: 'id_1',
title: 'Vulnerability 2', title: 'Vulnerability 1',
severity: 'high', severity: 'high',
state: 'opened', state: 'opened',
reportType: 'sast', reportType: 'DEPENDENCY_SCANNING',
location: { location: {
file: 'src/main/java/com/gitlab/security_products/tests/App.java', file: 'src/main/java/com/gitlab/security_products/tests/App.java',
}, },
...@@ -26,6 +26,31 @@ export const generateVulnerabilities = () => [ ...@@ -26,6 +26,31 @@ export const generateVulnerabilities = () => [
nameWithNamespace: 'Administrator / Vulnerability reports', nameWithNamespace: 'Administrator / Vulnerability reports',
}, },
}, },
{
id: 'id_2',
title: 'Vulnerability 2',
severity: 'high',
state: 'opened',
reportType: 'CUSTOM_SCANNER_WITHOUT_TRANSLATION',
location: {
file: 'yarn.lock',
},
project: {
nameWithNamespace: 'Mixed Vulnerabilities / Dependency List Test 01',
},
},
{
id: 'id_3',
title: 'Vulnerability 3',
severity: 'high',
state: 'opened',
location: {
file: 'yarn.lock',
},
project: {
nameWithNamespace: 'Mixed Vulnerabilities / Dependency List Test 01',
},
},
]; ];
export const vulnerabilities = generateVulnerabilities(); export const vulnerabilities = generateVulnerabilities();
...@@ -29,6 +29,7 @@ describe('Vulnerability list component', () => { ...@@ -29,6 +29,7 @@ describe('Vulnerability list component', () => {
}; };
const findCell = label => wrapper.find(`.js-${label}`); const findCell = label => wrapper.find(`.js-${label}`);
const findCells = label => wrapper.findAll(`.js-${label}`);
const findRow = (index = 0) => wrapper.findAll('tbody tr').at(index); const findRow = (index = 0) => wrapper.findAll('tbody tr').at(index);
const findSelectionSummary = () => wrapper.find(SelectionSummary); const findSelectionSummary = () => wrapper.find(SelectionSummary);
const findCheckAllCheckboxCell = () => wrapper.find('thead tr th'); const findCheckAllCheckboxCell = () => wrapper.find('thead tr th');
...@@ -64,8 +65,11 @@ describe('Vulnerability list component', () => { ...@@ -64,8 +65,11 @@ describe('Vulnerability list component', () => {
}); });
it('should correctly render the scanner type', () => { it('should correctly render the scanner type', () => {
const cell = findCell('reportType'); const cells = findCells('reportType');
expect(cell.text().toLowerCase()).toBe(newVulnerabilities[0].reportType); expect(cells.wrappers[0].text()).toBe('SAST');
expect(cells.wrappers[1].text()).toBe('Dependency Scanning');
expect(cells.wrappers[2].text()).toBe('custom scanner without translation');
expect(cells.wrappers[3].text()).toBe('');
}); });
it('should correctly render the description', () => { it('should correctly render the description', () => {
......
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