Commit 18544247 authored by Filipa Lacerda's avatar Filipa Lacerda

Adds dast and container scanning reports to summary widget in pipeline view

parent 6ae6fea5
......@@ -12,13 +12,19 @@ export default {
LoadingIcon,
},
computed: {
...mapState(['sast', 'dependencyScanning']),
...mapState(['sast', 'dependencyScanning', 'dast', 'sastContainer']),
sastLink() {
return this.link(this.sast.newIssues.length);
},
dependencyScanningLink() {
return this.link(this.dependencyScanning.newIssues.length);
},
dastLink() {
return this.link(this.dast.newIssues.length);
},
sastContainerLink() {
return this.link(this.sastContainer.newIssues.length);
},
sastIcon() {
return this.statusIcon(this.hasSastError, this.sast.newIssues.length);
},
......@@ -28,24 +34,48 @@ export default {
this.dependencyScanning.newIssues.length,
);
},
dastIcon() {
return this.statusIcon(this.hasDastError, this.dast.newIssues.length);
},
sastContainerIcon() {
return this.statusIcon(this.hasSastContainerError, this.sastContainer.newIssues.length);
},
hasSast() {
return this.sast.paths.head !== null;
},
hasDependencyScanning() {
return this.dependencyScanning.paths.head !== null;
},
hasDast() {
return this.dast.paths.head !== null;
},
hasSastContainer() {
return this.sastContainer.paths.head !== null;
},
isLoadingSast() {
return this.sast.isLoading;
},
isLoadingDependencyScanning() {
return this.dependencyScanning.isLoading;
},
isLoadingDast() {
return this.dast.isLoading;
},
isLoadingSastContainer() {
return this.sastContainer.isLoading;
},
hasSastError() {
return this.sast.hasError;
},
hasDependencyScanningError() {
return this.dependencyScanning.hasError;
},
hasDastError() {
return this.dast.hasError;
},
hasSastContainerError() {
return this.sastContainer.hasError;
},
},
methods: {
openTab() {
......@@ -117,7 +147,7 @@ export default {
v-if="hasDependencyScanning"
>
<loading-icon
v-if="dependencyScanning.isLoading"
v-if="isLoadingDependencyScanning"
/>
<ci-icon
v-else
......@@ -146,5 +176,73 @@ export default {
</template>
</span>
</div>
<div
class="well-segment flex js-sast-container-summary"
v-if="hasSastContainer"
>
<loading-icon
v-if="isLoadingSastContainer"
/>
<ci-icon
v-else
:status="sastContainerIcon"
class="flex flex-align-self-center"
/>
<span
class="prepend-left-10 flex flex-align-self-center"
>
<template v-if="hasSastContainerError">
{{ s__('ciReport|Container scanning resulted in error while loading results') }}
</template>
<template v-else-if="isLoadingSastContainer">
{{ s__('ciReport|Container scanning is loading') }}
</template>
<template v-else>
{{ s__('ciReport|Container scanning detected') }}
<button
type="button"
class="btn-link btn-blank prepend-left-5"
@click="openTab"
>
{{ sastContainerLink }}
</button>
</template>
</span>
</div>
<div
class="well-segment flex js-dast-summary"
v-if="hasDast"
>
<loading-icon
v-if="isLoadingDast"
/>
<ci-icon
v-else
:status="dastIcon"
class="flex flex-align-self-center"
/>
<span
class="prepend-left-10 flex flex-align-self-center"
>
<template v-if="hasDastError">
{{ s__('ciReport|DAST resulted in error while loading results') }}
</template>
<template v-else-if="isLoadingDast">
{{ s__('ciReport|DAST is loading') }}
</template>
<template v-else>
{{ s__('ciReport|DAST detected') }}
<button
type="button"
class="btn-link btn-blank prepend-left-5"
@click="openTab"
>
{{ dastLink }}
</button>
</template>
</span>
</div>
</div>
</template>
......@@ -170,7 +170,7 @@ export default {
state.dast.isLoading = false;
state.summaryCounts.added += newIssues.length;
state.summaryCounts.fixed += resolvedIssues.length;
} else if (reports.head && !reports.base) {
} else if (reports.head && reports.head.site && !reports.base) {
const newIssues = parseDastIssues(reports.head.site.alerts, reports.enrichData);
state.dast.newIssues = newIssues;
......
......@@ -3,7 +3,7 @@ import store from 'ee/vue_shared/security_reports/store';
import state from 'ee/vue_shared/security_reports/store/state';
import reportSummary from 'ee/pipelines/components/security_reports/report_summary_widget.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { sastIssues } from '../../vue_shared/security_reports/mock_data';
import { sastIssues, dast, dockerReport } from '../../vue_shared/security_reports/mock_data';
describe('Report summary widget', () => {
const Component = Vue.extend(reportSummary);
......@@ -30,9 +30,13 @@ describe('Report summary widget', () => {
beforeEach(() => {
vm.$store.dispatch('setSastHeadPath', 'head.json');
vm.$store.dispatch('setDependencyScanningHeadPath', 'head.json');
vm.$store.dispatch('setDastHeadPath', 'head.json');
vm.$store.dispatch('setSastContainerHeadPath', 'head.json');
vm.$store.dispatch('requestSastReports');
vm.$store.dispatch('requestDependencyScanningReports');
vm.$store.dispatch('requestDastReports');
vm.$store.dispatch('requestSastContainerReports');
});
it('renders loading icon and text for sast', done => {
......@@ -62,15 +66,47 @@ describe('Report summary widget', () => {
done();
});
});
it('renders loading icon and text for container scanning', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-sast-container-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('Container scanning is loading');
expect(vm.$el.querySelector('.js-sast-container-summary .fa-spinner')).not.toBeNull();
done();
});
});
it('renders loading icon and text for dast', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-dast-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('DAST is loading');
expect(vm.$el.querySelector('.js-dast-summary .fa-spinner')).not.toBeNull();
done();
});
});
});
describe('with error', () => {
beforeEach(() => {
vm.$store.dispatch('setSastHeadPath', 'head.json');
vm.$store.dispatch('setDependencyScanningHeadPath', 'head.json');
vm.$store.dispatch('setDastHeadPath', 'head.json');
vm.$store.dispatch('setSastContainerHeadPath', 'head.json');
vm.$store.dispatch('receiveSastError');
vm.$store.dispatch('receiveDependencyScanningError');
vm.$store.dispatch('receiveSastContainerError');
vm.$store.dispatch('receiveDastError');
});
it('renders warning icon and error text for sast', done => {
......@@ -102,12 +138,46 @@ describe('Report summary widget', () => {
.then(done)
.catch(done.fail);
});
it('renders warnin icon and error text for container scanning', done => {
vm.$nextTick()
.then(() => {
expect(
vm.$el
.querySelector('.js-sast-container-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('Container scanning resulted in error while loading results');
expect(vm.$el.querySelector('.js-sast-container-summary .js-ci-status-icon-warning')).not.toBeNull();
})
.then(done)
.catch(done.fail);
});
it('renders warnin icon and error text for DAST', done => {
vm.$nextTick()
.then(() => {
expect(
vm.$el
.querySelector('.js-dast-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('DAST resulted in error while loading results');
expect(vm.$el.querySelector('.js-dast-summary .js-ci-status-icon-warning')).not.toBeNull();
})
.then(done)
.catch(done.fail);
});
});
describe('with vulnerabilities', () => {
beforeEach(() => {
vm.$store.dispatch('setSastHeadPath', 'head.json');
vm.$store.dispatch('setDependencyScanningHeadPath', 'head.json');
vm.$store.dispatch('setDastHeadPath', 'head.json');
vm.$store.dispatch('setSastContainerHeadPath', 'head.json');
vm.$store.dispatch('receiveSastReports', {
head: sastIssues,
......@@ -115,6 +185,12 @@ describe('Report summary widget', () => {
vm.$store.dispatch('receiveDependencyScanningReports', {
head: sastIssues,
});
vm.$store.dispatch('receiveSastContainerReports', {
head: dockerReport,
});
vm.$store.dispatch('receiveDastReports', {
head: dast,
});
});
it('renders warning icon and vulnerabilities text for sast', done => {
......@@ -144,12 +220,42 @@ describe('Report summary widget', () => {
done();
});
});
it('renders warning icon and vulnerabilities text for container scanning', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-sast-container-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('Container scanning detected 2 vulnerabilities');
expect(vm.$el.querySelector('.js-sast-container-summary .js-ci-status-icon-warning')).not.toBeNull();
done();
});
});
it('renders warning icon and vulnerabilities text for dast', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-dast-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('DAST detected 2 vulnerabilities');
expect(vm.$el.querySelector('.js-dast-summary .js-ci-status-icon-warning')).not.toBeNull();
done();
});
});
});
describe('without vulnerabilities', () => {
beforeEach(() => {
vm.$store.dispatch('setSastHeadPath', 'head.json');
vm.$store.dispatch('setDependencyScanningHeadPath', 'head.json');
vm.$store.dispatch('setDastHeadPath', 'head.json');
vm.$store.dispatch('setSastContainerHeadPath', 'head.json');
vm.$store.dispatch('receiveSastReports', {
head: [],
......@@ -157,6 +263,12 @@ describe('Report summary widget', () => {
vm.$store.dispatch('receiveDependencyScanningReports', {
head: [],
});
vm.$store.dispatch('receiveSastContainerReports', {
head: [],
});
vm.$store.dispatch('receiveDastReports', {
head: [],
});
});
it('renders success icon and vulnerabilities text for sast', done => {
......@@ -186,5 +298,33 @@ describe('Report summary widget', () => {
done();
});
});
it('renders success icon and vulnerabilities text for container scanning', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-sast-container-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('Container scanning detected no vulnerabilities');
expect(vm.$el.querySelector('.js-sast-container-summary .js-ci-status-icon-success')).not.toBeNull();
done();
});
});
it('renders success icon and vulnerabilities text for dast', done => {
vm.$nextTick(() => {
expect(
vm.$el
.querySelector('.js-dast-summary')
.textContent.trim()
.replace(/\s\s+/g, ' '),
).toEqual('DAST detected no vulnerabilities');
expect(vm.$el.querySelector('.js-dast-summary .js-ci-status-icon-success')).not.toBeNull();
done();
});
});
});
});
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