Commit f52c9926 authored by Lukas Eipert's avatar Lukas Eipert

Persist Security Dashboard state in URL

With the help of Vue-Router we persist the URL as query parameters
every time we made a successful request. Every time the user updates the
URL by using the browser navigation, we update the filter state.

This is all tied together in the moderator and utilizes vue-router.
parent 6e634c99
...@@ -64,14 +64,18 @@ export default { ...@@ -64,14 +64,18 @@ export default {
this.setVulnerabilitiesEndpoint(this.vulnerabilitiesEndpoint); this.setVulnerabilitiesEndpoint(this.vulnerabilitiesEndpoint);
this.setVulnerabilitiesCountEndpoint(this.vulnerabilitiesCountEndpoint); this.setVulnerabilitiesCountEndpoint(this.vulnerabilitiesCountEndpoint);
this.setVulnerabilitiesHistoryEndpoint(this.vulnerabilitiesHistoryEndpoint); this.setVulnerabilitiesHistoryEndpoint(this.vulnerabilitiesHistoryEndpoint);
this.fetchVulnerabilitiesCount(); this.fetchVulnerabilities(this.activeFilters);
this.fetchVulnerabilitiesCount(this.activeFilters);
this.fetchVulnerabilitiesHistory(this.activeFilters);
this.fetchProjects(); this.fetchProjects();
}, },
methods: { methods: {
...mapActions('vulnerabilities', [ ...mapActions('vulnerabilities', [
'createIssue', 'createIssue',
'dismissVulnerability', 'dismissVulnerability',
'fetchVulnerabilities',
'fetchVulnerabilitiesCount', 'fetchVulnerabilitiesCount',
'fetchVulnerabilitiesHistory',
'revertDismissal', 'revertDismissal',
'setVulnerabilitiesCountEndpoint', 'setVulnerabilitiesCountEndpoint',
'setVulnerabilitiesEndpoint', 'setVulnerabilitiesEndpoint',
......
...@@ -43,9 +43,6 @@ export default { ...@@ -43,9 +43,6 @@ export default {
return this.pageInfo && this.pageInfo.total; return this.pageInfo && this.pageInfo.total;
}, },
}, },
created() {
this.fetchVulnerabilities(this.activeFilters);
},
methods: { methods: {
...mapActions('vulnerabilities', ['fetchVulnerabilities', 'openModal']), ...mapActions('vulnerabilities', ['fetchVulnerabilities', 'openModal']),
fetchPage(page) { fetchPage(page) {
......
<script> <script>
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import { mapState, mapActions } from 'vuex'; import { mapState } from 'vuex';
import { GlChart } from '@gitlab/ui/dist/charts'; import { GlChart } from '@gitlab/ui/dist/charts';
import ChartTooltip from './vulnerability_chart_tooltip.vue'; import ChartTooltip from './vulnerability_chart_tooltip.vue';
...@@ -142,11 +142,7 @@ export default { ...@@ -142,11 +142,7 @@ export default {
}; };
}, },
}, },
created() {
this.fetchVulnerabilitiesHistory();
},
methods: { methods: {
...mapActions('vulnerabilities', ['fetchVulnerabilitiesHistory']),
renderTooltip(params, ticket, callback) { renderTooltip(params, ticket, callback) {
this.tooltipTitle = dateFormat(params[0].axisValue, 'd mmmm'); this.tooltipTitle = dateFormat(params[0].axisValue, 'd mmmm');
this.tooltipEntries = params; this.tooltipEntries = params;
......
import Vue from 'vue'; import Vue from 'vue';
import GroupSecurityDashboardApp from './components/app.vue'; import GroupSecurityDashboardApp from './components/app.vue';
import createStore from './store'; import createStore from './store';
import router from './store/router';
export default () => { export default () => {
const el = document.getElementById('js-group-security-dashboard'); const el = document.getElementById('js-group-security-dashboard');
...@@ -10,6 +11,7 @@ export default () => { ...@@ -10,6 +11,7 @@ export default () => {
return new Vue({ return new Vue({
el, el,
store, store,
router,
components: { components: {
GroupSecurityDashboardApp, GroupSecurityDashboardApp,
}, },
......
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import router from './router';
import configureModerator from './moderator'; import configureModerator from './moderator';
import filters from './modules/filters/index'; import filters from './modules/filters/index';
import projects from './modules/projects/index'; import projects from './modules/projects/index';
...@@ -16,6 +17,8 @@ export default () => { ...@@ -16,6 +17,8 @@ export default () => {
}, },
}); });
store.$router = router;
configureModerator(store); configureModerator(store);
return store; return store;
......
import * as vulnerabilitiesMutationTypes from './modules/vulnerabilities/mutation_types';
import * as filtersMutationTypes from './modules/filters/mutation_types'; import * as filtersMutationTypes from './modules/filters/mutation_types';
import * as projectsMutationTypes from './modules/projects/mutation_types'; import * as projectsMutationTypes from './modules/projects/mutation_types';
export default function configureModerator(store) { export default function configureModerator(store) {
store.$router.beforeEach((to, from, next) => {
const updatedFromState = (to.params && to.params.updatedFromState) || false;
if (to.name === 'dashboard' && !updatedFromState) {
store.dispatch(`filters/setAllFilters`, to.query);
}
next();
});
store.subscribe(({ type, payload }) => { store.subscribe(({ type, payload }) => {
switch (type) { switch (type) {
case `projects/${projectsMutationTypes.RECEIVE_PROJECTS_SUCCESS}`: case `projects/${projectsMutationTypes.RECEIVE_PROJECTS_SUCCESS}`:
...@@ -19,6 +30,7 @@ export default function configureModerator(store) { ...@@ -19,6 +30,7 @@ export default function configureModerator(store) {
], ],
}); });
break; break;
case `filters/${filtersMutationTypes.SET_ALL_FILTERS}`:
case `filters/${filtersMutationTypes.SET_FILTER}`: { case `filters/${filtersMutationTypes.SET_FILTER}`: {
const activeFilters = store.getters['filters/activeFilters']; const activeFilters = store.getters['filters/activeFilters'];
store.dispatch('vulnerabilities/fetchVulnerabilities', activeFilters); store.dispatch('vulnerabilities/fetchVulnerabilities', activeFilters);
...@@ -26,6 +38,15 @@ export default function configureModerator(store) { ...@@ -26,6 +38,15 @@ export default function configureModerator(store) {
store.dispatch('vulnerabilities/fetchVulnerabilitiesHistory', activeFilters); store.dispatch('vulnerabilities/fetchVulnerabilitiesHistory', activeFilters);
break; break;
} }
case `vulnerabilities/${vulnerabilitiesMutationTypes.RECEIVE_VULNERABILITIES_SUCCESS}`: {
const activeFilters = store.getters['filters/activeFilters'];
store.$router.push({
name: 'dashboard',
query: activeFilters,
params: { updatedFromState: true },
});
break;
}
default: default:
} }
}); });
......
...@@ -14,6 +14,10 @@ export const setFilterOptions = ({ commit }, payload) => { ...@@ -14,6 +14,10 @@ export const setFilterOptions = ({ commit }, payload) => {
commit(types.SET_FILTER_OPTIONS, payload); commit(types.SET_FILTER_OPTIONS, payload);
}; };
export const setAllFilters = ({ commit }, payload) => {
commit(types.SET_ALL_FILTERS, payload);
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
// This is no longer needed after gitlab-ce#52179 is merged // This is no longer needed after gitlab-ce#52179 is merged
export default () => {}; export default () => {};
export const SET_FILTER = 'SET_FILTER'; export const SET_FILTER = 'SET_FILTER';
export const SET_FILTER_OPTIONS = 'SET_FILTER_OPTIONS'; export const SET_FILTER_OPTIONS = 'SET_FILTER_OPTIONS';
export const SET_ALL_FILTERS = 'SET_ALL_FILTERS';
import * as types from './mutation_types'; import * as types from './mutation_types';
export default { export default {
[types.SET_ALL_FILTERS](state, payload = {}) {
state.filters = state.filters.map(filter => {
// If the payload is empty, we fall back to an empty selection
const selectedOptions = (payload && payload[filter.id]) || [];
const selection = Array.isArray(selectedOptions)
? new Set(selectedOptions)
: new Set([selectedOptions]);
// This prevents us from selecting nothing at all
if (selection.size === 0) {
selection.add('all');
}
return { ...filter, selection };
});
},
[types.SET_FILTER](state, payload) { [types.SET_FILTER](state, payload) {
const { filterId, optionId } = payload; const { filterId, optionId } = payload;
const activeFilter = state.filters.find(filter => filter.id === filterId); const activeFilter = state.filters.find(filter => filter.id === filterId);
...@@ -21,7 +38,7 @@ export default { ...@@ -21,7 +38,7 @@ export default {
// This prevents us from selecting nothing at all // This prevents us from selecting nothing at all
if (selection.size === 0) { if (selection.size === 0) {
selection = new Set(['all']); selection.add('all');
} }
activeFilter.selection = selection; activeFilter.selection = selection;
} }
......
...@@ -14,6 +14,9 @@ export const setVulnerabilitiesCountEndpoint = ({ commit }, endpoint) => { ...@@ -14,6 +14,9 @@ export const setVulnerabilitiesCountEndpoint = ({ commit }, endpoint) => {
}; };
export const fetchVulnerabilitiesCount = ({ state, dispatch }, params = {}) => { export const fetchVulnerabilitiesCount = ({ state, dispatch }, params = {}) => {
if (!state.vulnerabilitiesCountEndpoint) {
return;
}
dispatch('requestVulnerabilitiesCount'); dispatch('requestVulnerabilitiesCount');
axios({ axios({
...@@ -43,6 +46,9 @@ export const receiveVulnerabilitiesCountError = ({ commit }) => { ...@@ -43,6 +46,9 @@ export const receiveVulnerabilitiesCountError = ({ commit }) => {
}; };
export const fetchVulnerabilities = ({ state, dispatch }, params = {}) => { export const fetchVulnerabilities = ({ state, dispatch }, params = {}) => {
if (!state.vulnerabilitiesEndpoint) {
return;
}
dispatch('requestVulnerabilities'); dispatch('requestVulnerabilities');
axios({ axios({
...@@ -208,6 +214,9 @@ export const setVulnerabilitiesHistoryEndpoint = ({ commit }, endpoint) => { ...@@ -208,6 +214,9 @@ export const setVulnerabilitiesHistoryEndpoint = ({ commit }, endpoint) => {
}; };
export const fetchVulnerabilitiesHistory = ({ state, dispatch }, params = {}) => { export const fetchVulnerabilitiesHistory = ({ state, dispatch }, params = {}) => {
if (!state.vulnerabilitiesHistoryEndpoint) {
return;
}
dispatch('requestVulnerabilitiesHistory'); dispatch('requestVulnerabilitiesHistory');
axios({ axios({
......
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
// Unfortunately Vue Router doesn't work without at least a fake component
// If you do only data handling
const EmptyRouterComponent = {
render(createElement) {
return createElement('div');
},
};
const routes = [{ path: '/', name: 'dashboard', component: EmptyRouterComponent }];
const router = new VueRouter({
mode: 'history',
base: window.location.pathname,
routes,
});
export default router;
---
title: Persist Group Level Security Dashboard state in URL
merge_request: 9108
author:
type: added
import Vue from 'vue'; import Vue from 'vue';
import MockAdapater from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import component from 'ee/security_dashboard/components/security_dashboard_table.vue'; import component from 'ee/security_dashboard/components/security_dashboard_table.vue';
import createStore from 'ee/security_dashboard/store'; import createStore from 'ee/security_dashboard/store';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import waitForPromises from 'spec/helpers/wait_for_promises';
import {
RECEIVE_VULNERABILITIES_ERROR,
RECEIVE_VULNERABILITIES_SUCCESS,
REQUEST_VULNERABILITIES,
} from 'ee/security_dashboard/store/modules/vulnerabilities/mutation_types';
import { resetStore } from '../helpers'; import { resetStore } from '../helpers';
import mockDataVulnerabilities from '../store/vulnerabilities/data/mock_data_vulnerabilities.json'; import mockDataVulnerabilities from '../store/vulnerabilities/data/mock_data_vulnerabilities.json';
...@@ -19,11 +22,9 @@ describe('Security Dashboard Table', () => { ...@@ -19,11 +22,9 @@ describe('Security Dashboard Table', () => {
emptyStateSvgPath: TEST_HOST, emptyStateSvgPath: TEST_HOST,
}; };
let store; let store;
let mock;
let vm; let vm;
beforeEach(() => { beforeEach(() => {
mock = new MockAdapater(axios);
store = createStore(); store = createStore();
store.state.vulnerabilities.vulnerabilitiesEndpoint = vulnerabilitiesEndpoint; store.state.vulnerabilities.vulnerabilitiesEndpoint = vulnerabilitiesEndpoint;
}); });
...@@ -31,12 +32,11 @@ describe('Security Dashboard Table', () => { ...@@ -31,12 +32,11 @@ describe('Security Dashboard Table', () => {
afterEach(() => { afterEach(() => {
resetStore(store); resetStore(store);
vm.$destroy(); vm.$destroy();
mock.restore();
}); });
describe('while loading', () => { describe('while loading', () => {
beforeEach(() => { beforeEach(() => {
store.dispatch('vulnerabilities/requestVulnerabilities'); store.commit(`vulnerabilities/${REQUEST_VULNERABILITIES}`);
vm = mountComponentWithStore(Component, { store, props }); vm = mountComponentWithStore(Component, { store, props });
}); });
...@@ -47,60 +47,42 @@ describe('Security Dashboard Table', () => { ...@@ -47,60 +47,42 @@ describe('Security Dashboard Table', () => {
describe('with a list of vulnerabilities', () => { describe('with a list of vulnerabilities', () => {
beforeEach(() => { beforeEach(() => {
mock.onGet(vulnerabilitiesEndpoint).replyOnce(200, mockDataVulnerabilities); store.commit(`vulnerabilities/${RECEIVE_VULNERABILITIES_SUCCESS}`, {
vulnerabilities: mockDataVulnerabilities,
});
vm = mountComponentWithStore(Component, { store, props }); vm = mountComponentWithStore(Component, { store, props });
}); });
it('should render a row for each vulnerability', done => { it('should render a row for each vulnerability', () => {
waitForPromises() expect(vm.$el.querySelectorAll('.vulnerabilities-row')).toHaveLength(
.then(() => { mockDataVulnerabilities.length,
expect(vm.$el.querySelectorAll('.vulnerabilities-row')).toHaveLength( );
mockDataVulnerabilities.length,
);
done();
})
.catch(done.fail);
}); });
}); });
describe('with no vulnerabilties', () => { describe('with no vulnerabilties', () => {
beforeEach(() => { beforeEach(() => {
mock.onGet(vulnerabilitiesEndpoint).replyOnce(200, []); store.commit(`vulnerabilities/${RECEIVE_VULNERABILITIES_SUCCESS}`, { vulnerabilities: [] });
vm = mountComponentWithStore(Component, { store, props }); vm = mountComponentWithStore(Component, { store, props });
}); });
it('should render the empty state', done => { it('should render the empty state', () => {
waitForPromises() expect(vm.$el.querySelector('.empty-state')).not.toBeNull();
.then(() => {
expect(vm.$el.querySelector('.empty-state')).not.toBeNull();
done();
})
.catch(done.fail);
}); });
}); });
describe('on error', () => { describe('on error', () => {
beforeEach(() => { beforeEach(() => {
mock.onGet(vulnerabilitiesEndpoint).replyOnce(404, []); store.commit(`vulnerabilities/${RECEIVE_VULNERABILITIES_ERROR}`);
vm = mountComponentWithStore(Component, { store, props }); vm = mountComponentWithStore(Component, { store, props });
}); });
it('should not render the empty state', done => { it('should not render the empty state', () => {
waitForPromises() expect(vm.$el.querySelector('.empty-state')).toBeNull();
.then(() => {
expect(vm.$el.querySelector('.empty-state')).toBeNull();
done();
})
.catch(done.fail);
}); });
it('should render the error alert', done => { it('should render the error alert', () => {
waitForPromises() expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
.then(() => {
expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
done();
})
.catch(done.fail);
}); });
}); });
}); });
...@@ -46,4 +46,25 @@ describe('filters actions', () => { ...@@ -46,4 +46,25 @@ describe('filters actions', () => {
); );
}); });
}); });
describe('setAllFilters', () => {
it('should commit the SET_ALL_FILTERS mutuation', done => {
const state = createState();
const payload = { project_id: ['12', '15'] };
testAction(
actions.setAllFilters,
payload,
state,
[
{
type: types.SET_ALL_FILTERS,
payload,
},
],
[],
done,
);
});
});
}); });
...@@ -47,6 +47,46 @@ describe('filters module mutations', () => { ...@@ -47,6 +47,46 @@ describe('filters module mutations', () => {
}); });
}); });
describe('SET_ALL_FILTERS', () => {
it('should set options if they are a single string', () => {
mutations[types.SET_ALL_FILTERS](state, { [severityFilter.id]: criticalOption.id });
const expected = new Set([criticalOption.id]);
expect(state.filters[0].selection).toEqual(expected);
});
it('should set options if they are given as an array', () => {
mutations[types.SET_ALL_FILTERS](state, {
[severityFilter.id]: [criticalOption.id, highOption.id],
});
const expected = new Set([criticalOption.id, highOption.id]);
expect(state.filters[0].selection).toEqual(expected);
});
it('should set options to `all` if no payload is given', () => {
mutations[types.SET_ALL_FILTERS](state);
const expected = new Set(['all']);
state.filters.forEach(filter => {
expect(filter.selection).toEqual(expected);
});
});
it('should set options to `all` if payload contains an empty array', () => {
mutations[types.SET_ALL_FILTERS](state, {
[severityFilter.id]: [],
});
const expected = new Set(['all']);
expect(state.filters[0].selection).toEqual(expected);
});
});
describe('SET_FILTER_OPTIONS', () => { describe('SET_FILTER_OPTIONS', () => {
const options = [{ id: 0, name: 'c' }, { id: 3, name: 'c' }]; const options = [{ id: 0, name: 'c' }, { id: 3, name: 'c' }];
......
import createStore from 'ee/security_dashboard/store/index'; import createStore from 'ee/security_dashboard/store/index';
import * as projectsMutationTypes from 'ee/security_dashboard/store/modules/projects/mutation_types'; import * as projectsMutationTypes from 'ee/security_dashboard/store/modules/projects/mutation_types';
import * as filtersMutationTypes from 'ee/security_dashboard/store/modules/filters/mutation_types'; import * as filtersMutationTypes from 'ee/security_dashboard/store/modules/filters/mutation_types';
import * as vulnerabilitiesMutationTypes from 'ee/security_dashboard/store/modules/vulnerabilities/mutation_types';
describe('moderator', () => { describe('moderator', () => {
let store; let store;
...@@ -10,7 +11,7 @@ describe('moderator', () => { ...@@ -10,7 +11,7 @@ describe('moderator', () => {
}); });
it('sets project filter options after projects have been received', () => { it('sets project filter options after projects have been received', () => {
spyOn(store, 'dispatch').and.returnValue(); spyOn(store, 'dispatch');
store.commit(`projects/${projectsMutationTypes.RECEIVE_PROJECTS_SUCCESS}`, { store.commit(`projects/${projectsMutationTypes.RECEIVE_PROJECTS_SUCCESS}`, {
projects: [{ name: 'foo', id: 1, otherProp: 'foobar' }], projects: [{ name: 'foo', id: 1, otherProp: 'foobar' }],
...@@ -26,8 +27,8 @@ describe('moderator', () => { ...@@ -26,8 +27,8 @@ describe('moderator', () => {
); );
}); });
it('triggers fetching vulnerabilities after filters change', () => { it('triggers fetching vulnerabilities after one filter changes', () => {
spyOn(store, 'dispatch').and.returnValue(); spyOn(store, 'dispatch');
const activeFilters = store.getters['filters/activeFilters']; const activeFilters = store.getters['filters/activeFilters'];
...@@ -38,13 +39,80 @@ describe('moderator', () => { ...@@ -38,13 +39,80 @@ describe('moderator', () => {
'vulnerabilities/fetchVulnerabilities', 'vulnerabilities/fetchVulnerabilities',
activeFilters, activeFilters,
); );
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilitiesCount', 'vulnerabilities/fetchVulnerabilitiesCount',
activeFilters, activeFilters,
); );
expect(store.dispatch).toHaveBeenCalledWith( expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilitiesHistory', 'vulnerabilities/fetchVulnerabilitiesHistory',
activeFilters, activeFilters,
); );
}); });
it('triggers fetching vulnerabilities after filters change', () => {
spyOn(store, 'dispatch');
const activeFilters = store.getters['filters/activeFilters'];
store.commit(`filters/${filtersMutationTypes.SET_ALL_FILTERS}`, {});
expect(store.dispatch).toHaveBeenCalledTimes(3);
expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilities',
activeFilters,
);
expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilitiesCount',
activeFilters,
);
expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilitiesHistory',
activeFilters,
);
});
describe('routing', () => {
it('updates store after URL changes', () => {
const query = { example: ['test'] };
spyOn(store, 'dispatch');
store.$router.push({ name: 'dashboard', query });
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith(`filters/setAllFilters`, query);
});
it("doesn't update the store if the URL update originated from the moderator", () => {
const query = { example: ['test'] };
spyOn(store, 'commit');
store.$router.push({ name: 'dashboard', query, params: { updatedFromState: true } });
expect(store.commit).toHaveBeenCalledTimes(0);
});
it('it updates the route after a successful vulnerability retrieval', () => {
const activeFilters = store.getters['filters/activeFilters'];
spyOn(store.$router, 'push');
store.commit(
`vulnerabilities/${vulnerabilitiesMutationTypes.RECEIVE_VULNERABILITIES_SUCCESS}`,
{},
);
expect(store.$router.push).toHaveBeenCalledTimes(1);
expect(store.$router.push).toHaveBeenCalledWith({
name: 'dashboard',
query: activeFilters,
params: { updatedFromState: true },
});
});
});
}); });
...@@ -11,7 +11,7 @@ import mockDataVulnerabilities from './data/mock_data_vulnerabilities.json'; ...@@ -11,7 +11,7 @@ import mockDataVulnerabilities from './data/mock_data_vulnerabilities.json';
import mockDataVulnerabilitiesCount from './data/mock_data_vulnerabilities_count.json'; import mockDataVulnerabilitiesCount from './data/mock_data_vulnerabilities_count.json';
import mockDataVulnerabilitiesHistory from './data/mock_data_vulnerabilities_history.json'; import mockDataVulnerabilitiesHistory from './data/mock_data_vulnerabilities_history.json';
describe('vulnerabiliites count actions', () => { describe('vulnerabilities count actions', () => {
const data = mockDataVulnerabilitiesCount; const data = mockDataVulnerabilitiesCount;
const params = { filters: { type: ['sast'] } }; const params = { filters: { type: ['sast'] } };
const filteredData = mockDataVulnerabilitiesCount.sast; const filteredData = mockDataVulnerabilitiesCount.sast;
...@@ -37,7 +37,7 @@ describe('vulnerabiliites count actions', () => { ...@@ -37,7 +37,7 @@ describe('vulnerabiliites count actions', () => {
}); });
}); });
describe('fetchVulnerabilitesCount', () => { describe('fetchVulnerabilitiesCount', () => {
let mock; let mock;
const state = initialState; const state = initialState;
...@@ -112,7 +112,7 @@ describe('vulnerabiliites count actions', () => { ...@@ -112,7 +112,7 @@ describe('vulnerabiliites count actions', () => {
}); });
}); });
describe('requestVulnerabilitesCount', () => { describe('requestVulnerabilitiesCount', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState; const state = initialState;
...@@ -127,7 +127,7 @@ describe('vulnerabiliites count actions', () => { ...@@ -127,7 +127,7 @@ describe('vulnerabiliites count actions', () => {
}); });
}); });
describe('receiveVulnerabilitesCountSuccess', () => { describe('receiveVulnerabilitiesCountSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState; const state = initialState;
...@@ -142,7 +142,7 @@ describe('vulnerabiliites count actions', () => { ...@@ -142,7 +142,7 @@ describe('vulnerabiliites count actions', () => {
}); });
}); });
describe('receivetVulnerabilitesCountError', () => { describe('receiveVulnerabilitiesCountError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState; const state = initialState;
...@@ -708,12 +708,12 @@ describe('vulnerabilities history actions', () => { ...@@ -708,12 +708,12 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('fetchVulnerabilitesTimeline', () => { describe('fetchVulnerabilitiesTimeline', () => {
let mock; let mock;
const state = initialState; const state = initialState;
beforeEach(() => { beforeEach(() => {
state.vulnerabilitiesCountEndpoint = `${TEST_HOST}/vulnerabilitIES_HISTORY.json`; state.vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilitIES_HISTORY.json`;
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
}); });
...@@ -786,7 +786,7 @@ describe('vulnerabilities history actions', () => { ...@@ -786,7 +786,7 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('requestVulnerabilitesTimeline', () => { describe('requestVulnerabilitiesTimeline', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState; const state = initialState;
...@@ -801,7 +801,7 @@ describe('vulnerabilities history actions', () => { ...@@ -801,7 +801,7 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('receiveVulnerabilitesTimelineSuccess', () => { describe('receiveVulnerabilitiesTimelineSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState; const state = initialState;
...@@ -816,7 +816,7 @@ describe('vulnerabilities history actions', () => { ...@@ -816,7 +816,7 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('receivetVulnerabilitesTimelineError', () => { describe('receiveVulnerabilitiesTimelineError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState; const state = initialState;
......
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