]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
test(errors): add tests for errors in history listener
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 11 Jun 2019 16:19:49 +0000 (18:19 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 11 Jun 2019 16:19:49 +0000 (18:19 +0200)
__tests__/errors.spec.js [new file with mode: 0644]
src/router.ts

diff --git a/__tests__/errors.spec.js b/__tests__/errors.spec.js
new file mode 100644 (file)
index 0000000..c4cdc90
--- /dev/null
@@ -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' } } },
+    ])
+  })
+})
index b8f6c7a8c987b0543a084668e1fab27192da001b..daf6a37a311e7197616f667bb632786c69c5bf06 100644 (file)
@@ -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 {