From: Eduardo San Martin Morote Date: Tue, 11 Jun 2019 16:19:49 +0000 (+0200) Subject: test(errors): add tests for errors in history listener X-Git-Tag: v4.0.0-alpha.0~337 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d2020edc4b8d65b0dcf7c2bb4934c0fe09846f3;p=thirdparty%2Fvuejs%2Frouter.git test(errors): add tests for errors in history listener --- diff --git a/__tests__/errors.spec.js b/__tests__/errors.spec.js new file mode 100644 index 00000000..c4cdc900 --- /dev/null +++ b/__tests__/errors.spec.js @@ -0,0 +1,91 @@ +// @ts-check +require('./helper') +const expect = require('expect') +const fakePromise = require('faked-promise') +const { AbstractHistory } = require('../src/history/abstract') +const { Router } = require('../src/router') +const { + NavigationAborted, + NavigationCancelled, + NavigationGuardRedirect, +} = require('../src/errors') +const { components, tick } = require('./utils') + +/** @type {import('../src/types').RouteRecord[]} */ +const routes = [ + { path: '/', component: components.Home }, + { path: '/foo', component: components.Foo, name: 'Foo' }, + { path: '/to-foo', redirect: '/foo' }, + { path: '/to-foo-named', redirect: { name: 'Foo' } }, + { path: '/to-foo2', redirect: '/to-foo' }, + { path: '/p/:p', name: 'Param', component: components.Bar }, + { path: '/to-p/:p', redirect: to => `/p/${to.params.p}` }, + { + path: '/inc-query-hash', + redirect: to => ({ + name: 'Foo', + query: { n: to.query.n + '-2' }, + hash: to.hash + '-2', + }), + }, +] + +const onError = jest.fn() +function createRouter() { + const router = new Router({ + history: new AbstractHistory(), + routes, + }) + + router.onError(onError) + return router +} + +describe('Errors', () => { + beforeEach(() => { + onError.mockReset() + }) + + it('triggers onError when navigation is aborted', async () => { + const router = createRouter() + router.beforeEach((to, from, next) => { + next(false) + }) + + try { + await router.push('/foo') + } catch (err) { + expect(err).toBeInstanceOf(NavigationAborted) + } + expect(onError).toHaveBeenCalledWith(expect.any(NavigationAborted)) + }) + + it('triggers erros caused by new navigations of a next(redirect) trigered by history', async () => { + const router = createRouter() + await router.push('/p/0') + await router.push('/p/other') + + router.beforeEach((to, from, next) => { + const p = (Number(to.params.p) || 0) + 1 + if (p === 2) next(false) + else next({ name: 'Param', params: { p: '' + p } }) + }) + + // @ts-ignore + router.history.back() + await tick() + + expect(onError).toHaveBeenCalledTimes(2) + expect(onError).toHaveBeenNthCalledWith( + 1, + expect.any(NavigationGuardRedirect) + ) + expect(onError.mock.calls[0]).toMatchObject([ + { to: { params: { p: '1' } }, from: { fullPath: '/p/0' } }, + ]) + expect(onError).toHaveBeenNthCalledWith(2, expect.any(NavigationAborted)) + expect(onError.mock.calls[1]).toMatchObject([ + { to: { params: { p: '1' } }, from: { params: { p: 'other' } } }, + ]) + }) +}) diff --git a/src/router.ts b/src/router.ts index b8f6c7a8..daf6a37a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -84,11 +84,15 @@ export class Router { false ) } + this.triggerError(error, false) - // TODO: tests - this.push(error.to).catch(error => this.triggerError(error, false)) + // the error is already handled by router.push + // we just want to avoid logging the error + this.push(error.to).catch(() => {}) } else if (error instanceof NavigationAborted) { // TODO: test on different browsers ensure consistent behavior + // TODO: this doesn't work if the user directly calls window.history.go(-n) with n > 1 + // We can override the go method to retrieve the number but not sure if all browsers allow that if (info.direction === NavigationDirection.back) { this.history.forward(false) } else {