Commit 9034941b authored by Mark Florian's avatar Mark Florian Committed by Fatih Acet

Remove router from Pipeline Security Dashboard

This reduces a bit the coupling of the security dashboard's router and
store, and [removes the router from the Pipeline Security Dashboard][1].

Now, to sync a security dashboard to its router (as is done for the
Group and Project Security Dashboards), the router must be explictly
created and bound to the store using the `syncWithRouter` store plugin
at store creation.

[1]: https://gitlab.com/gitlab-org/gitlab/issues/32749
parent f06ac15a
import Vue from 'vue';
import createRouter from 'ee/security_dashboard/store/router';
import syncWithRouter from 'ee/security_dashboard/store/plugins/sync_with_router';
import createStore from 'ee/security_dashboard/store';
import router from 'ee/security_dashboard/store/router';
import SecurityReportApp from 'ee/vue_shared/security_reports/card_security_reports_app.vue';
import { parseBoolean } from '~/lib/utils/common_utils';
......@@ -33,8 +34,6 @@ document.addEventListener('DOMContentLoaded', () => {
const parsedPipelineId = parseInt(pipelineId, 10);
const parsedHasPipelineData = parseBoolean(hasPipelineData);
const store = createStore();
let props = {
hasPipelineData: parsedHasPipelineData,
dashboardDocumentation,
......@@ -73,6 +72,9 @@ document.addEventListener('DOMContentLoaded', () => {
};
}
const router = createRouter();
const store = createStore({ plugins: [syncWithRouter(router)] });
return new Vue({
el: securityTab,
store,
......
......@@ -2,8 +2,9 @@ import Vue from 'vue';
import GroupSecurityDashboardApp from './components/group_security_dashboard.vue';
import UnavailableState from './components/unavailable_state.vue';
import createStore from './store';
import router from './store/router';
import createRouter from './store/router';
import projectsPlugin from './store/plugins/projects';
import syncWithRouter from './store/plugins/sync_with_router';
export default function() {
const el = document.getElementById('js-group-security-dashboard');
......@@ -23,7 +24,8 @@ export default function() {
});
}
const store = createStore({ plugins: [projectsPlugin] });
const router = createRouter();
const store = createStore({ plugins: [projectsPlugin, syncWithRouter(router)] });
return new Vue({
el,
store,
......
import Vue from 'vue';
import Vuex from 'vuex';
import router from './router';
import mediator from './plugins/mediator';
import syncWithRouter from './plugins/sync_with_router';
import filters from './modules/filters/index';
import vulnerabilities from './modules/vulnerabilities/index';
Vue.use(Vuex);
export default ({ plugins = [] } = {}) => {
const store = new Vuex.Store({
export default ({ plugins = [] } = {}) =>
new Vuex.Store({
modules: {
filters,
vulnerabilities,
},
plugins: [mediator, syncWithRouter(router), ...plugins],
plugins: [mediator, ...plugins],
});
store.$router = router;
return store;
};
......@@ -11,11 +11,13 @@ const EmptyRouterComponent = {
},
};
const routes = [{ path: '/', name: 'dashboard', component: EmptyRouterComponent }];
const router = new VueRouter({
mode: 'history',
base: window.location.pathname,
routes,
});
export default () => {
const routes = [{ path: '/', name: 'dashboard', component: EmptyRouterComponent }];
const router = new VueRouter({
mode: 'history',
base: window.location.pathname,
routes,
});
export default router;
return router;
};
---
title: Remove broken HTML5 routing behaviour from Pipeline Security Dashboard
merge_request: 17767
author:
type: changed
import createStore from 'ee/security_dashboard/store/index';
import syncWithRouter from 'ee/security_dashboard/store/plugins/sync_with_router';
import createRouter from 'ee/security_dashboard/store/router';
import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/constants';
describe('syncWithRouter', () => {
let router;
let store;
const noop = () => {};
beforeEach(() => {
store = createStore();
router = createRouter();
store = createStore({ plugins: [syncWithRouter(router)] });
});
it('updates store after URL changes', () => {
......@@ -16,12 +20,12 @@ describe('syncWithRouter', () => {
jest.spyOn(store, 'dispatch');
const routerPush = store.$router.push.bind(store.$router);
jest.spyOn(store.$router, 'push');
const routerPush = router.push.bind(router);
jest.spyOn(router, 'push');
routerPush({ name: 'dashboard', query });
// Assert no implicit synchronous recursive calls occurred
expect(store.$router.push).not.toHaveBeenCalled();
expect(router.push).not.toHaveBeenCalled();
expect(store.dispatch).toHaveBeenCalledWith(`filters/setAllFilters`, query);
expect(store.dispatch).toHaveBeenCalledWith(`vulnerabilities/setVulnerabilitiesPage`, page);
......@@ -38,8 +42,8 @@ describe('syncWithRouter', () => {
jest.spyOn(store, 'dispatch');
const routerPush = store.$router.push.bind(store.$router);
jest.spyOn(store.$router, 'push');
const routerPush = router.push.bind(router);
jest.spyOn(router, 'push');
routerPush({ name: 'dashboard', query });
expect(store.dispatch).toHaveBeenCalledWith(`vulnerabilities/setVulnerabilitiesPage`, 1);
});
......@@ -49,7 +53,7 @@ describe('syncWithRouter', () => {
jest.spyOn(store, 'commit').mockImplementation(noop);
store.$router.push({ name: 'dashboard', query, params: { updatedFromState: true } });
router.push({ name: 'dashboard', query, params: { updatedFromState: true } });
expect(store.commit).toHaveBeenCalledTimes(0);
});
......@@ -58,12 +62,12 @@ describe('syncWithRouter', () => {
const activeFilters = store.getters['filters/activeFilters'];
const page = 2;
jest.spyOn(store.$router, 'push').mockImplementation(noop);
jest.spyOn(router, 'push').mockImplementation(noop);
store.dispatch(`vulnerabilities/fetchVulnerabilities`, { page });
expect(store.$router.push).toHaveBeenCalledTimes(1);
expect(store.$router.push).toHaveBeenCalledWith(
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith(
expect.objectContaining({
name: 'dashboard',
query: expect.objectContaining({
......@@ -80,12 +84,12 @@ describe('syncWithRouter', () => {
const activeFilters = store.getters['filters/activeFilters'];
const days = DAYS.SIXTY;
jest.spyOn(store.$router, 'push').mockImplementation(noop);
jest.spyOn(router, 'push').mockImplementation(noop);
store.dispatch(`vulnerabilities/setVulnerabilitiesHistoryDayRange`, days);
expect(store.$router.push).toHaveBeenCalledTimes(1);
expect(store.$router.push).toHaveBeenCalledWith(
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith(
expect.objectContaining({
name: 'dashboard',
query: expect.objectContaining({
......
......@@ -6,7 +6,6 @@ import { TEST_HOST } from 'helpers/test_constants';
import CardSecurityDashboardApp from 'ee/vue_shared/security_reports/card_security_reports_app.vue';
import createStore from 'ee/security_dashboard/store';
import router from 'ee/security_dashboard/store/router';
import { trimText } from 'helpers/text_helper';
const localVue = createLocalVue();
......@@ -25,7 +24,6 @@ describe('Card security reports app', () => {
wrapper = mount(CardSecurityDashboardApp, {
localVue,
store: createStore(),
router,
sync: false,
stubs: ['security-dashboard-table'],
propsData: {
......
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