From 3d1c416fba06dc7c194767568dc9bc9e653154c1 Mon Sep 17 00:00:00 2001 From: Balazs Meszegeto Date: Thu, 19 Apr 2018 18:35:07 +0200 Subject: [PATCH] fix(app-router): await navigation result Navigation command (eg. redirect) in child route navigation strategy was not working, when parent route was also using a navigation strategy Fixes https://github.com/aurelia/router/issues/588 --- src/app-router.js | 6 ++++-- test/app-router.spec.js | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/app-router.js b/src/app-router.js index b7f6f86e..9b2339f4 100644 --- a/src/app-router.js +++ b/src/app-router.js @@ -197,8 +197,9 @@ function processResult(instruction, result, instructionCount, router) { } let finalResult = null; + let navigationCommandResult = null; if (isNavigationCommand(result.output)) { - result.output.navigate(router); + navigationCommandResult = result.output.navigate(router); } else { finalResult = result; @@ -211,7 +212,8 @@ function processResult(instruction, result, instructionCount, router) { } } - return router._dequeueInstruction(instructionCount + 1) + return Promise.resolve(navigationCommandResult) + .then(_ => router._dequeueInstruction(instructionCount + 1)) .then(innerResult => finalResult || innerResult || result); } diff --git a/test/app-router.spec.js b/test/app-router.spec.js index cb2bb70e..1933f8e1 100644 --- a/test/app-router.spec.js +++ b/test/app-router.spec.js @@ -23,6 +23,13 @@ class MockLoader extends RouteLoader { } } +class MockInstruction { + constructor(title: string) { + this.title = title; + } + resolve(): void {} +} + describe('app-router', () => { let router; let history; @@ -246,6 +253,41 @@ describe('app-router', () => { .then(done); }); }); + describe('instruction completes as navigation command', () => { + it('should complete instructions in order before terminating', done => { + const pipeline = new Pipeline() + .addStep({ run(inst, next) { return pipelineStep(inst, next); } }); + spyOn(pipeline, 'run').and.callThrough(); + + const plProvider = { + createPipeline: () => pipeline + }; + const router = new AppRouter(container, history, plProvider, ea); + const initialInstruction = new MockInstruction('initial resulting navigation (Promise)'); + const instructionAfterNav = new MockInstruction('instruction after navigation'); + + const navigationCommand = { + navigate: () => new Promise(resolve => { + setTimeout(() => { + router._queue.push(instructionAfterNav); + pipelineStep = (ctx, next) => next.complete({}); + resolve(); + }, 0); + }) + }; + + router._queue.push(initialInstruction); + pipelineStep = (ctx, next) => next.complete(navigationCommand); + + router._dequeueInstruction() + .then(_ => { + expect(pipeline.run).toHaveBeenCalledTimes(2); + expect(pipeline.run.calls.argsFor(0)).toEqual([initialInstruction]); + expect(pipeline.run.calls.argsFor(1)).toEqual([instructionAfterNav]); + done(); + }); + }); + }) }); function expectSuccess(result) {