Commit e465c7eb authored by Filipa Lacerda's avatar Filipa Lacerda

Parse docker issues and updates copy. [ci skip]

parent 2bdc092b
This diff is collapsed.
import { n__ } from '~/locale'; import { n__, s__ } from '~/locale';
import CEWidgetOptions from '~/vue_merge_request_widget/mr_widget_options'; import CEWidgetOptions from '~/vue_merge_request_widget/mr_widget_options';
import WidgetApprovals from './components/approvals/mr_widget_approvals'; import WidgetApprovals from './components/approvals/mr_widget_approvals';
import GeoSecondaryNode from './components/states/mr_widget_secondary_geo_node'; import GeoSecondaryNode from './components/states/mr_widget_secondary_geo_node';
...@@ -123,37 +123,36 @@ export default { ...@@ -123,37 +123,36 @@ export default {
dockerText() { dockerText() {
const { vulnerabilities, approved, unapproved } = this.mr.dockerReport; const { vulnerabilities, approved, unapproved } = this.mr.dockerReport;
const text = [];
if (vulnerabilities.length) { if (!vulnerabilities.length) {
text.push(n__( return s__('ciReport|No vulnerabilities were found');
'%d vulnerability.',
'%d vulnerabilities.',
vulnerabilities.length,
));
} }
if (approved.length) { if (!unapproved.length) {
text.push(n__( return n__(
'%d of those was approved.', 'Found %d approved vulnerability',
'%d of those were approved.', 'Found %d approved vulnerabilities',
approved.length, approved.length,
)); );
}
if (approved.length > 0 && unapproved.length > 0) {
text.push('and');
} }
if (unapproved.length) { if (unapproved.length && !approved.length) {
text.push(n__( return n__(
'%d of those was unapproved.', 'Found %d vulnerability',
'%d of those were unapproved.', 'Found %d vulnerabilities',
unapproved.length, unapproved.length,
)); );
} }
return text.join(' '); return `${n__(
'Found %d vulnerability,',
'Found %d vulnerabilities,',
unapproved.length,
)} ${n__(
'of which %d is approved',
'of which %d are approved',
approved.length,
)}`;
}, },
codequalityStatus() { codequalityStatus() {
...@@ -280,11 +279,13 @@ export default { ...@@ -280,11 +279,13 @@ export default {
<mr-widget-deployment <mr-widget-deployment
v-if="shouldRenderDeployments" v-if="shouldRenderDeployments"
:mr="mr" :mr="mr"
:service="service" /> :service="service"
/>
<mr-widget-approvals <mr-widget-approvals
v-if="shouldRenderApprovals" v-if="shouldRenderApprovals"
:mr="mr" :mr="mr"
:service="service" /> :service="service"
/>
<collapsible-section <collapsible-section
class="js-codequality-widget" class="js-codequality-widget"
v-if="shouldRenderCodeQuality" v-if="shouldRenderCodeQuality"
...@@ -320,7 +321,7 @@ export default { ...@@ -320,7 +321,7 @@ export default {
/> />
<collapsible-section <collapsible-section
class="js-docker-widget" class="js-docker-widget"
v-if="shouldRenderDockerReport"
type="codequality" type="codequality"
:status="dockerStatus" :status="dockerStatus"
loading-text="Loading clair report" loading-text="Loading clair report"
...@@ -336,7 +337,8 @@ export default { ...@@ -336,7 +337,8 @@ export default {
:service="service" /> :service="service" />
<mr-widget-related-links <mr-widget-related-links
v-if="shouldRenderRelatedLinks" v-if="shouldRenderRelatedLinks"
:related-links="mr.relatedLinks" /> :related-links="mr.relatedLinks"
/>
</div> </div>
<div class="mr-widget-footer" v-if="shouldRenderMergeHelp"> <div class="mr-widget-footer" v-if="shouldRenderMergeHelp">
<mr-widget-merge-help /> <mr-widget-merge-help />
......
...@@ -85,11 +85,28 @@ export default class MergeRequestStore extends CEMergeRequestStore { ...@@ -85,11 +85,28 @@ export default class MergeRequestStore extends CEMergeRequestStore {
this.securityReport = MergeRequestStore.parseIssues(issues, path); this.securityReport = MergeRequestStore.parseIssues(issues, path);
} }
setDockerReport(data) { setDockerReport(data = {}) {
// Set data - TODO parse the data const parsedVulnerabilities = MergeRequestStore
this.dockerReport.approved = data.approved || []; .parseDockerVulnerabilities(data.vulnerabilities);
this.dockerReport.unapproved = data.unapproved || [];
this.dockerReport.vulnerabilities = data.vulnerabilities || []; this.dockerReport.vulnerabilities = parsedVulnerabilities || [];
// Approved can be calculated by subtracting unapproved from vulnerabilities.
this.dockerReport.approved = parsedVulnerabilities
.filter(item => !data.unapproved.find(el => el === item.vulnerability)) || [];
this.dockerReport.unapproved = parsedVulnerabilities
.filter(item => data.unapproved.find(el => el === item.vulnerability)) || [];
}
// TODO: Add links
static parseDockerVulnerabilities(data) {
return data.map(el => ({
name: el.vulnerability,
priority: el.severity,
path: el.namespace,
...el,
}));
} }
compareCodeclimateMetrics(headIssues, baseIssues, headBlobPath, baseBlobPath) { compareCodeclimateMetrics(headIssues, baseIssues, headBlobPath, baseBlobPath) {
......
...@@ -436,6 +436,28 @@ describe('ee merge request widget options', () => { ...@@ -436,6 +436,28 @@ describe('ee merge request widget options', () => {
}); });
}); });
describe('docker report', () => {
describe('when it is loading', () => {
it('should render loading indicator', () => {
vm = mountComponent(Component);
expect(
vm.$el.querySelector('.js-docker-widget').textContent.trim(),
).toContain('Loading clair report');
});
});
describe('with successful request', () => {
it('should render provided data', () => {
});
});
describe('with failed request', () => {
it('should render error indicator', () => {
});
});
});
describe('computed', () => { describe('computed', () => {
describe('shouldRenderApprovals', () => { describe('shouldRenderApprovals', () => {
it('should return false when no approvals', () => { it('should return false when no approvals', () => {
...@@ -474,5 +496,207 @@ describe('ee merge request widget options', () => { ...@@ -474,5 +496,207 @@ describe('ee merge request widget options', () => {
expect(vm.shouldRenderApprovals).toBeTruthy(); expect(vm.shouldRenderApprovals).toBeTruthy();
}); });
}); });
describe('shouldRenderDockerReport', () => {
it('returns undefined when clair is not set up', () => {
vm = mountComponent(Component, {
mrData: {
...mockData,
},
});
expect(vm.shouldRenderDockerReport).toEqual(undefined);
});
it('returns clair object when clair is set up', () => {
vm = mountComponent(Component, {
mrData: {
...mockData,
clair: {
path: 'foo',
},
},
});
expect(vm.shouldRenderDockerReport).toEqual({ path: 'foo' });
});
});
describe('dockerText', () => {
beforeEach(() => {
vm = mountComponent(Component, {
mrData: {
...mockData,
clair: {
path: 'foo',
},
},
});
});
describe('with no vulnerabilities', () => {
it('returns No vulnerabilities found', () => {
expect(vm.dockerText).toEqual('No vulnerabilities were found');
});
});
describe('without unapproved vulnerabilities', () => {
it('returns approved information - single', () => {
vm.mr.dockerReport = {
vulnerabilities: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
approved: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
unapproved: [],
};
expect(vm.dockerText).toEqual('Found 1 vulnerability');
});
it('returns approved information - plural', () => {
vm.mr.dockerReport = {
vulnerabilities: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
approved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
{
vulnerability: 'CVE-2017-13726',
namespace: 'debian:8',
severity: 'Medium',
},
],
unapproved: [],
};
expect(vm.dockerText).toEqual('Found 2 approved vulnerabilities');
});
});
describe('with only unapproved vulnerabilities', () => {
it('returns number of vulnerabilities - single', () => {
vm.mr.dockerReport = {
vulnerabilities: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
unapproved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
],
approved: [],
};
expect(vm.dockerText).toEqual('Found 1 vulnerability');
});
it('returns number of vulnerabilities - plural', () => {
vm.mr.dockerReport = {
vulnerabilities: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
unapproved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
],
approved: [],
};
expect(vm.dockerText).toEqual('Found 2 vulnerabilities');
});
});
describe('with approved and unapproved vulnerabilities', () => {
it('returns message with information about both - single', () => {
vm.mr.dockerReport = {
vulnerabilities: [{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
}],
unapproved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
],
approved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
],
};
expect(vm.dockerText).toEqual('Found 1 vulnerability, of which 1 is approved');
});
it('returns message with information about both - plural', () => {
vm.mr.dockerReport = {
vulnerabilities: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
],
unapproved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
{
vulnerability: 'CVE-2017-12923',
namespace: 'debian:8',
severity: 'Medium',
},
],
approved: [
{
vulnerability: 'CVE-2017-12944',
namespace: 'debian:8',
severity: 'Medium',
},
{
vulnerability: 'CVE-2017-13944',
namespace: 'debian:8',
severity: 'Medium',
},
],
};
expect(vm.dockerText).toEqual('Found 2 vulnerabilities, of which 2 are approved');
});
});
});
}); });
}); });
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