From 555301409199a87e2cfb472a0e0f4f8d12290ef5 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 7 Feb 2020 15:35:13 -0500 Subject: [PATCH] Add router + tests --- src/router.test.ts | 88 ++++++++++++++++++++++++++++++++++++++++++++++ src/router.ts | 43 ++++++++++++++++++++-- 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/router.test.ts diff --git a/src/router.test.ts b/src/router.test.ts new file mode 100644 index 0000000000..94f1e35bb4 --- /dev/null +++ b/src/router.test.ts @@ -0,0 +1,88 @@ +import Vue from 'vue'; +import VueCompositionAPI from '@vue/composition-api'; +import VueRouter, { Route } from 'vue-router'; +import { onBeforeEach, useRouter } from './router'; +import { useProjectsStore } from '@/stores/projects'; + +const route: Route = { + name: undefined, + path: '', + query: {}, + hash: '', + params: {}, + fullPath: '', + matched: [] +}; + +describe('Router', () => { + beforeAll(() => { + Vue.config.productionTip = false; + Vue.config.devtools = false; + Vue.use(VueCompositionAPI); + }); + + it('Fetches the projects using projectsStore on first load', async () => { + const projectsStore = useProjectsStore({}); + projectsStore.getProjects = jest.fn(); + + const toRoute = route; + const fromRoute = { + ...route, + name: null + }; + const callback = jest.fn(); + + await onBeforeEach(toRoute, fromRoute as any, callback); + + expect(projectsStore.getProjects).toHaveBeenCalled(); + }); + + it('Redirects to /install if projectStore.needsInstall is true', async () => { + const projectsStore = useProjectsStore({}); + projectsStore.getProjects = jest.fn(); + + const toRoute = route; + const fromRoute = { + ...route, + name: null + }; + + const callback = jest.fn(); + + projectsStore.state.needsInstall = true; + + await onBeforeEach(toRoute, fromRoute as any, callback); + + expect(callback).toHaveBeenCalledWith('/install'); + }); + + it('Sets the project store currentProjectKey on route changes if project param exists', async () => { + const projectsStore = useProjectsStore({}); + + const toRoute = { + ...route, + params: { + project: 'my-project' + } + }; + + const fromRoute = { + ...route, + name: 'login' + }; + + const callback = jest.fn(); + + await onBeforeEach(toRoute, fromRoute as any, callback); + + expect(projectsStore.state.currentProjectKey).toBe('my-project'); + }); + + describe('useRouter', () => { + it('Returns the store instance', () => { + const router = useRouter(); + + expect(router instanceof VueRouter).toBe(true); + }); + }); +}); diff --git a/src/router.ts b/src/router.ts index e0311f96c8..b9818ea509 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,6 +1,45 @@ -import VueRouter from 'vue-router'; +import VueRouter, { NavigationGuard } from 'vue-router'; +import Debug from '@/routes/debug.vue'; +import { useProjectsStore } from '@/stores/projects'; -const router = new VueRouter(); +const router = new VueRouter({ + mode: 'hash', + routes: [ + { + path: '/:project/*', + component: Debug + }, + { + path: '/', + component: Debug + }, + { + path: '*', + component: Debug + } + ] +}); + +export const onBeforeEach: NavigationGuard = async (to, from, next) => { + const projectsStore = useProjectsStore(); + + // First load + if (from.name === null) { + await projectsStore.getProjects(); + + if (projectsStore.state.needsInstall === true) { + return next('/install'); + } + } + + if (to.params.project) { + projectsStore.state.currentProjectKey = to.params.project; + } + + return next(); +}; + +router.beforeEach(onBeforeEach); export function useRouter() { return router;