Page tracking (#242)

* Add trackPage action to userStore

* Track page in after each for router
This commit is contained in:
Rijk van Zanten
2020-03-23 20:53:16 -04:00
committed by GitHub
parent 519a9ea7f9
commit de26915d6b
4 changed files with 113 additions and 2 deletions

View File

@@ -1,11 +1,18 @@
import Vue from 'vue';
import VueCompositionAPI from '@vue/composition-api';
import { Route } from 'vue-router';
import { onBeforeEach, onBeforeEnterProjectChooser, replaceRoutes, defaultRoutes } from './router';
import {
onBeforeEach,
onAfterEach,
onBeforeEnterProjectChooser,
replaceRoutes,
defaultRoutes
} from './router';
import api from '@/api';
import * as auth from '@/auth';
import { useProjectsStore } from '@/stores/projects';
import { hydrate } from '@/hydrate';
import useUserStore from '@/stores/user';
jest.mock('@/auth');
jest.mock('@/hydrate');
@@ -257,4 +264,46 @@ describe('Router', () => {
expect(handler).toHaveBeenCalledWith(defaultRoutes);
});
});
describe('onAfterEach', () => {
it('Calls the userStore trackPage method after some time', () => {
jest.useFakeTimers();
const userStore = useUserStore({});
jest.spyOn(userStore, 'trackPage');
const to = {
fullPath: '/test',
meta: {
public: false
}
} as any;
onAfterEach(to);
jest.runAllTimers();
expect(userStore.trackPage).toHaveBeenCalledWith('/test');
});
it('Does not track the page for public pages', () => {
jest.useFakeTimers();
const userStore = useUserStore({});
jest.spyOn(userStore, 'trackPage');
const to = {
fullPath: '/test',
meta: {
public: true
}
} as any;
onAfterEach(to);
jest.runAllTimers();
expect(userStore.trackPage).not.toHaveBeenCalledWith('/test');
});
});
});

View File

@@ -1,4 +1,4 @@
import VueRouter, { NavigationGuard, RouteConfig } from 'vue-router';
import VueRouter, { NavigationGuard, RouteConfig, Route } from 'vue-router';
import Debug from '@/routes/debug.vue';
import { useProjectsStore } from '@/stores/projects';
import LoginRoute from '@/routes/login';
@@ -7,6 +7,7 @@ import ProjectChooserRoute from '@/routes/project-chooser';
import { checkAuth } from '@/auth';
import { hydrate, dehydrate } from '@/hydrate';
import useAppStore from '@/stores/app';
import useUserStore from '@/stores/user';
export const onBeforeEnterProjectChooser: NavigationGuard = (to, from, next) => {
const projectsStore = useProjectsStore();
@@ -133,7 +134,20 @@ export const onBeforeEach: NavigationGuard = async (to, from, next) => {
return next();
};
export const onAfterEach = (to: Route) => {
const userStore = useUserStore();
if (to.meta.public !== true) {
// The timeout gives the page some breathing room to load. No need to clog up the thread with
// this call while more important things are loading
setTimeout(() => {
userStore.trackPage(to.fullPath);
}, 2500);
}
};
router.beforeEach(onBeforeEach);
router.afterEach(onAfterEach);
export default router;

View File

@@ -54,4 +54,40 @@ describe('Stores / User', () => {
expect(userStore.reset).toHaveBeenCalled();
});
});
describe('Track Page', () => {
it('Calls the right endpoint on tracking', async () => {
const userStore = useUserStore(req);
const projectsStore = useProjectsStore(req);
userStore.state.currentUser = {
id: 5,
last_page: 'test'
} as any;
projectsStore.state.currentProjectKey = 'my-project';
await userStore.trackPage('/example');
expect(api.patch).toHaveBeenCalledWith('/my-project/users/me/tracking/page', {
last_page: '/example'
});
});
it('Updates the store with the new last page', async () => {
const userStore = useUserStore(req);
const projectsStore = useProjectsStore(req);
userStore.state.currentUser = {
id: 5,
last_page: 'test'
} as any;
projectsStore.state.currentProjectKey = 'my-project';
await userStore.trackPage('/example');
expect(userStore.state.currentUser!.last_page).toBe('/example');
});
});
});

View File

@@ -30,6 +30,18 @@ export const useUserStore = createStore({
},
async dehydrate() {
this.reset();
},
async trackPage(page: string) {
const projectsStore = useProjectsStore();
const currentProjectKey = projectsStore.state.currentProjectKey;
await api.patch(`/${currentProjectKey}/users/me/tracking/page`, {
last_page: page
});
if (this.state.currentUser) {
this.state.currentUser.last_page = page;
}
}
}
});