diff --git a/src/App.spec.ts b/src/App.spec.ts index 6c9dcf06d..6ae73d5e0 100644 --- a/src/App.spec.ts +++ b/src/App.spec.ts @@ -502,7 +502,10 @@ describe('App', () => { authorize: sinon.fake.resolves(dummyAuthorizationResult), }); - app.use((_args) => { ackFn(); }); + app.use((_args) => { + ackFn(); + _args.next(); + }); app.action('block_action_id', ({ }) => { actionFn(); }); app.action({ callback_id: 'message_action_callback_id' }, ({ }) => { actionFn(); }); app.action( @@ -563,8 +566,9 @@ describe('App', () => { receiver: fakeReceiver, authorize: sinon.fake.resolves(dummyAuthorizationResult), }); - app.use(({ logger, body }) => { + app.use(({ logger, body, next }) => { logger.info(body); + next(); }); app.event('app_home_opened', ({ logger, event }) => { @@ -628,8 +632,9 @@ describe('App', () => { return Promise.resolve({ userToken: token, botId: 'B123' }); }, }); - app.use(async ({ client }) => { + app.use(async ({ client, next }) => { await client.auth.test(); + next(); }); const clients: WebClient[] = []; app.event('app_home_opened', async ({ client }) => { diff --git a/src/middleware/process.spec.ts b/src/middleware/process.spec.ts new file mode 100644 index 000000000..b4e385e68 --- /dev/null +++ b/src/middleware/process.spec.ts @@ -0,0 +1,44 @@ +// tslint:disable:no-implicit-dependencies +import { assert } from 'chai'; +import { processMiddleware } from './process'; +import { Context } from 'mocha'; +import { AnyMiddlewareArgs, Middleware } from '../types'; + +describe('processMiddleware()', () => { + const middlewareOne: Middleware = ({ next, context }) => { + const fn = () => { + context.one = true; + next(); + }; + setTimeout(fn, 10); + }; + const middlewareTwo: Middleware = ({ next, context }) => { + const fn = () => { + context.two = true; + next(); + }; + setTimeout(fn, 10); + }; + it('processes all middleware before processing listener', (done) => { + processMiddleware( + // @ts-ignore + {}, + [middlewareOne, middlewareTwo], + (context: Context) => { + // ensure that the last middleware ran to completion (i.e., called `next`) before afterMiddleware is called + assert.isTrue(context.one); + assert.isTrue(context.two); + done(); + }, + (error?: Error) => { + if (error) { + console.error(`after post process: ${error && error.message}`); + } + assert(false); + }, + {}, + null, + null, + ); + }); +}); diff --git a/src/middleware/process.ts b/src/middleware/process.ts index 916a61dea..ec25cf2f9 100644 --- a/src/middleware/process.ts +++ b/src/middleware/process.ts @@ -33,15 +33,13 @@ export function processMiddleware( // Continue processing if (thisMiddleware !== undefined && !(errorOrPostProcess instanceof Error)) { const isLastMiddleware = middlewareIndex === (middleware.length - 1); - const nextWhenNotLast = isLastMiddleware ? noop : next; // In this condition, errorOrPostProcess will be a postProcess function or undefined postProcessFns[middlewareIndex - 1] = errorOrPostProcess === undefined ? noopPostProcess : errorOrPostProcess; - thisMiddleware({ context, logger, client, next: nextWhenNotLast, ...initialArguments }); + thisMiddleware({ context, logger, client, next, ...initialArguments }); if (isLastMiddleware) { postProcessFns[middlewareIndex] = noopPostProcess; - process.nextTick(next); } return; } @@ -82,5 +80,4 @@ export function processMiddleware( firstMiddleware({ context, logger, client, next, ...initialArguments }); } -function noop(): void { } // tslint:disable-line:no-empty const noopPostProcess: PostProcessFn = (error, done) => { done(error); };