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