From e13b988b58617af85ab2e375cf949702b291dffc Mon Sep 17 00:00:00 2001 From: Ian Anderson Date: Thu, 16 Sep 2021 14:29:37 -0500 Subject: [PATCH] fix: create controllers in specified order Fixes typestack/routing-controllers#774 --- src/metadata-builder/MetadataArgsStorage.ts | 8 ++- test/functional/controller-order.spec.ts | 63 +++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 test/functional/controller-order.spec.ts diff --git a/src/metadata-builder/MetadataArgsStorage.ts b/src/metadata-builder/MetadataArgsStorage.ts index fc82a072..0859683c 100644 --- a/src/metadata-builder/MetadataArgsStorage.ts +++ b/src/metadata-builder/MetadataArgsStorage.ts @@ -79,9 +79,11 @@ export class MetadataArgsStorage { * Filters registered controllers by a given classes. */ filterControllerMetadatasForClasses(classes: Function[]): ControllerMetadataArgs[] { - return this.controllers.filter(ctrl => { - return classes.filter(cls => ctrl.target === cls).length > 0; - }); + return classes.reduce((ctrls, cls) => { + const ctrl = this.controllers.find(ctrl => ctrl.target === cls); + if (ctrl) ctrls.push(ctrl); + return ctrls; + }, []); } /** diff --git a/test/functional/controller-order.spec.ts b/test/functional/controller-order.spec.ts new file mode 100644 index 00000000..6ea2460c --- /dev/null +++ b/test/functional/controller-order.spec.ts @@ -0,0 +1,63 @@ +import { Server as HttpServer } from 'http'; +import HttpStatusCodes from 'http-status-codes'; +import { Controller } from '../../src/decorator/Controller'; +import { Get } from '../../src/decorator/Get'; +import { createExpressServer, getMetadataArgsStorage } from '../../src/index'; +import { axios } from '../utilities/axios'; +import DoneCallback = jest.DoneCallback; + +describe(``, () => { + let expressServer: HttpServer; + + describe('loaded direct from array', () => { + let controllerOrder: number[]; + + beforeEach(() => { + controllerOrder = []; + }); + + beforeAll((done: DoneCallback) => { + getMetadataArgsStorage().reset(); + + @Controller() + class ThirdController { + @Get('/*') + getAll() { + controllerOrder.push(3); + return 'OK'; + } + } + + @Controller() + class SecondController { + @Get('/second/*') + getAll() { + controllerOrder.push(2); + return 'OK'; + } + } + + @Controller() + class FirstController { + @Get('/second/first/*') + getAll() { + controllerOrder.push(1); + return 'OK'; + } + } + + expressServer = createExpressServer({ + controllers: [FirstController, SecondController, ThirdController], + }).listen(3001, done); + }); + + afterAll((done: DoneCallback) => expressServer.close(done)); + + it('should call controllers in order defined by items order', async () => { + await axios.get('/second/first/any'); + await axios.get('/second/any'); + await axios.get('/any'); + expect(controllerOrder).toEqual([1, 2, 3]); + }); + }); +});