Commit 807e8a90 authored by Savas Vedova's avatar Savas Vedova

Persist resolution alert dismissal

- Write tests
- Use a cookie based solution
parent e4e952d4
......@@ -148,6 +148,7 @@ export default {
<div>
<resolution-alert
v-if="showResolutionAlert"
:vulnerability-id="vulnerability.id"
:default-branch-name="vulnerability.project_default_branch"
/>
<div class="detail-page-header">
......
<script>
import Cookies from 'js-cookie';
import { GlAlert } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
export const COOKIE_NAME = 'dismissed_resolution_alerts';
export default {
name: 'ResolutionAlert',
components: {
GlAlert,
},
......@@ -13,10 +15,16 @@ export default {
required: false,
default: '',
},
vulnerabilityId: {
type: Number,
required: true,
},
},
data() {
return {
isVisible: this.isAlreadyDismissed() === false,
};
},
data: () => ({
isVisible: true,
}),
computed: {
resolutionTitle() {
return this.defaultBranchName
......@@ -25,10 +33,19 @@ export default {
},
},
methods: {
alreadyDismissedVulnerabilities() {
try {
return JSON.parse(Cookies.get(COOKIE_NAME));
} catch (e) {
return [];
}
},
isAlreadyDismissed() {
return this.alreadyDismissedVulnerabilities().some(id => id === this.vulnerabilityId);
},
dismiss() {
// This isn't the best way to handle the dismissal, but it is a borig solution.
// The next iteration of this is tracked in the below issue.
// https://gitlab.com/gitlab-org/gitlab/-/issues/212195
const dismissed = this.alreadyDismissedVulnerabilities().concat(this.vulnerabilityId);
Cookies.set(COOKIE_NAME, JSON.stringify(dismissed), { expires: 90 });
this.isVisible = false;
},
},
......
import Cookies from 'js-cookie';
import { shallowMount } from '@vue/test-utils';
import { GlAlert } from '@gitlab/ui';
import ResolutionAlert from 'ee/vulnerabilities/components/resolution_alert.vue';
import ResolutionAlert, { COOKIE_NAME } from 'ee/vulnerabilities/components/resolution_alert.vue';
describe('Vulnerability list component', () => {
let wrapper;
const DEFAULT_BRANCH_NAME = 'not-always-master';
const defaultBranchName = 'not-always-master';
const vulnerabilityId = 61;
const createWrapper = (options = {}) => {
wrapper = shallowMount(ResolutionAlert, options);
......@@ -12,19 +14,21 @@ describe('Vulnerability list component', () => {
const findAlert = () => wrapper.find(GlAlert);
afterEach(() => wrapper.destroy());
afterEach(() => {
wrapper.destroy();
wrapper = null;
Cookies.remove(COOKIE_NAME);
});
describe('with a default branch name passed to it', () => {
beforeEach(() => {
createWrapper({
propsData: { defaultBranchName: DEFAULT_BRANCH_NAME },
propsData: { defaultBranchName, vulnerabilityId },
});
});
it('should render the default branch name in the alert title', () => {
const alert = findAlert();
expect(alert.attributes().title).toMatch(DEFAULT_BRANCH_NAME);
expect(findAlert().attributes().title).toMatch(defaultBranchName);
});
it('should call the dismiss method when dismissed', () => {
......@@ -34,15 +38,26 @@ describe('Vulnerability list component', () => {
});
});
describe('when already dismissed', () => {
beforeEach(() => {
Cookies.set(COOKIE_NAME, JSON.stringify([vulnerabilityId]));
createWrapper({
propsData: { defaultBranchName, vulnerabilityId },
});
});
it('should not display the alert', () => {
expect(findAlert().exists()).toBe(false);
});
});
describe('with no default branch name', () => {
beforeEach(() => {
createWrapper();
createWrapper({ propsData: { vulnerabilityId } });
});
it('should render the fallback in the alert title', () => {
const alert = findAlert();
expect(alert.attributes().title).toMatch('in the default branch');
expect(findAlert().attributes('title')).toMatch('in the default branch');
});
});
});
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