Commit c751aa2a authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '32767-display-cancel-for-fixed-vulnerabilities' into 'master'

Never hide vulnerability modal footer

See merge request gitlab-org/gitlab!20867
parents cd38b047 ccbea94c
......@@ -57,14 +57,27 @@ export default {
dismissalCommentErrorMessage: '',
}),
computed: {
canDownloadPatch() {
canCreateIssueForThisVulnerability() {
return Boolean(!this.isResolved && !this.vulnerability.hasIssue && this.canCreateIssue);
},
canCreateMergeRequestForThisVulnerability() {
return Boolean(!this.isResolved && !this.vulnerability.hasMergeRequest && this.remediation);
},
canDismissThisVulnerability() {
return Boolean(!this.isResolved && this.canDismissVulnerability);
},
canDownloadPatchForThisVulnerability() {
const remediationDiff = this.remediation && this.remediation.diff;
return Boolean(
remediationDiff &&
!this.isResolved &&
remediationDiff &&
remediationDiff.length > 0 &&
(!this.vulnerability.hasMergeRequest && this.remediation),
);
},
isResolved() {
return Boolean(this.modal.isResolved);
},
hasRemediation() {
return Boolean(this.remediation);
},
......@@ -87,12 +100,6 @@ export default {
this.vulnerability && this.vulnerability.remediations && this.vulnerability.remediations[0]
);
},
renderSolutionCard() {
return this.solution || this.remediation;
},
shouldRenderFooterSection() {
return !this.modal.isResolved && (this.canCreateIssue || this.canDismissVulnerability);
},
vulnerability() {
return this.modal.vulnerability;
},
......@@ -194,7 +201,6 @@ export default {
<modal
id="modal-mrwidget-security-issue"
:header-title-text="modal.title"
:class="{ 'modal-hide-footer': !shouldRenderFooterSection }"
data-qa-selector="vulnerability_modal_content"
class="modal-security-report-dast"
>
......@@ -206,7 +212,7 @@ export default {
:remediation="remediation"
:has-mr="vulnerability.hasMergeRequest"
:has-remediation="hasRemediation"
:has-download="canDownloadPatch"
:has-download="canDownloadPatchForThisVulnerability"
:vulnerability-feedback-help-path="vulnerabilityFeedbackHelpPath"
/>
......@@ -269,14 +275,15 @@ export default {
@cancel="$emit('closeDismissalCommentBox')"
/>
<modal-footer
v-else-if="shouldRenderFooterSection"
v-else
ref="footer"
:modal="modal"
:vulnerability="vulnerability"
:disabled="modal.isShowingDeleteButtons"
:can-create-issue="Boolean(!vulnerability.hasIssue && canCreateIssue)"
:can-create-merge-request="Boolean(!vulnerability.hasMergeRequest && remediation)"
:can-download-patch="canDownloadPatch"
:can-dismiss-vulnerability="canDismissVulnerability"
:can-create-issue="canCreateIssueForThisVulnerability"
:can-create-merge-request="canCreateMergeRequestForThisVulnerability"
:can-download-patch="canDownloadPatchForThisVulnerability"
:can-dismiss-vulnerability="canDismissThisVulnerability"
:is-dismissed="vulnerability.isDismissed"
@createMergeRequest="$emit('createMergeRequest')"
@createNewIssue="$emit('createNewIssue')"
......
......@@ -67,7 +67,7 @@ export default {
};
</script>
<template>
<div class="card js-solution-card my-4">
<div class="card my-4">
<div v-if="solutionText" class="card-body d-flex align-items-center">
<div class="col-2 d-flex align-items-center pl-0">
<div class="circle-icon-container" aria-hidden="true"><icon name="bulb" /></div>
......
---
title: Show actions area for fixed vulnerabilities in merge requests
merge_request: 20867
author:
type: fixed
import Vue from 'vue';
import component from 'ee/vue_shared/security_reports/components/modal.vue';
import createState from 'ee/vue_shared/security_reports/store/state';
import SolutionCard from 'ee/vue_shared/security_reports/components/solution_card.vue';
import { mount, shallowMount } from '@vue/test-utils';
describe('Security Reports modal', () => {
......@@ -66,8 +67,8 @@ describe('Security Reports modal', () => {
mountComponent({ propsData }, mount);
});
it('renders the footer', () => {
expect(wrapper.classes('modal-hide-footer')).toBe(false);
it('allows the vulnerability to be dismissed', () => {
expect(wrapper.find({ ref: 'footer' }).props('canDismissVulnerability')).toBe(true);
});
});
......@@ -137,6 +138,29 @@ describe('Security Reports modal', () => {
);
});
});
describe('with a resolved issue', () => {
beforeEach(() => {
const propsData = {
modal: createState().modal,
canCreateIssue: true,
canCreateMergeRequest: true,
canDismissVulnerability: true,
};
propsData.modal.vulnerability.remediations = [{ diff: '123' }];
propsData.modal.isResolved = true;
mountComponent({ propsData });
});
it('disallows any actions in the footer', () => {
expect(wrapper.find({ ref: 'footer' }).props()).toMatchObject({
canCreateIssue: false,
canCreateMergeRequest: false,
canDownloadPatch: false,
canDismissVulnerability: false,
});
});
});
});
describe('without permissions', () => {
......@@ -147,8 +171,13 @@ describe('Security Reports modal', () => {
mountComponent({ propsData });
});
it('does not display the footer', () => {
expect(wrapper.classes('modal-hide-footer')).toBe(true);
it('disallows any actions in the footer', () => {
expect(wrapper.find({ ref: 'footer' }).props()).toMatchObject({
canCreateIssue: false,
canCreateMergeRequest: false,
canDownloadPatch: false,
canDismissVulnerability: false,
});
});
});
......@@ -237,8 +266,13 @@ describe('Security Reports modal', () => {
mountComponent({ propsData });
});
it('does not display the footer', () => {
expect(wrapper.classes('modal-hide-footer')).toBe(true);
it('disallows any actions in the footer', () => {
expect(wrapper.find({ ref: 'footer' }).props()).toMatchObject({
canCreateIssue: false,
canCreateMergeRequest: false,
canDownloadPatch: false,
canDismissVulnerability: false,
});
});
});
......@@ -291,7 +325,7 @@ describe('Security Reports modal', () => {
propsData.modal.vulnerability.solution = solution;
mountComponent({ propsData }, mount);
const solutionCard = wrapper.find('.js-solution-card');
const solutionCard = wrapper.find(SolutionCard);
expect(solutionCard.exists()).toBe(true);
expect(solutionCard.text()).toContain(solution);
......@@ -303,13 +337,15 @@ describe('Security Reports modal', () => {
modal: createState().modal,
};
const summary = 'Upgrade to 123';
propsData.modal.vulnerability.remediations = [{ summary }];
const diff = 'foo';
propsData.modal.vulnerability.remediations = [{ summary, diff }];
mountComponent({ propsData }, mount);
const solutionCard = wrapper.find('.js-solution-card');
const solutionCard = wrapper.find(SolutionCard);
expect(solutionCard.exists()).toBe(true);
expect(solutionCard.text()).toContain(summary);
expect(solutionCard.props('hasDownload')).toBe(true);
expect(wrapper.contains('hr')).toBe(false);
});
......@@ -319,7 +355,7 @@ describe('Security Reports modal', () => {
};
mountComponent({ propsData }, mount);
const solutionCard = wrapper.find('.js-solution-card');
const solutionCard = wrapper.find(SolutionCard);
expect(solutionCard.exists()).toBe(true);
expect(wrapper.contains('hr')).toBe(false);
......
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