diff --git a/src/middleware/index.spec.ts b/src/middleware/index.spec.ts index 00bc8265..9f7dece7 100644 --- a/src/middleware/index.spec.ts +++ b/src/middleware/index.spec.ts @@ -161,4 +161,111 @@ describe('middleware', () => { expect(spy).toHaveBeenNthCalledWith(6, { foo: 'mw1', ctx: 'mw3' }) }) }) + + describe('both', () => { + beforeEach(() => { + mockRequest({ + method: 'post', + url: `${host}${path}`, + body: m.anything(), + headers: {}, + response: { + body: { ok: true }, + status: 200, + }, + }) + }) + + const createMiddleware = + ( + prepareRequestSpy: jest.Mock, + responseSpy: jest.Mock, + beforeParams: Record, + afterParams: Record + ): Middleware => + () => ({ + prepareRequest: async (next) => { + prepareRequestSpy(beforeParams) + const request = await next() + prepareRequestSpy(afterParams) + return request + }, + response: async (next) => { + responseSpy(beforeParams) + const response = await next() + responseSpy(afterParams) + return response + }, + }) + + it('invokes middleware and extends response context in given order', async () => { + const prepareRequestSpy = jest.fn() + const responseSpy = jest.fn() + const mw1 = createMiddleware(prepareRequestSpy, responseSpy, { foo: 'mw1' }, { bar: 'mw1' }) + const mw2 = createMiddleware(prepareRequestSpy, responseSpy, { ctx: 'mw2' }, { fizz: 'mw2' }) + const mw3 = createMiddleware(prepareRequestSpy, responseSpy, { ctx: 'mw3' }, { buzz: 'mw3' }) + const client = forge({ + clientId: 'testMw', + middleware: [mw1, mw2, mw3], + host, + resources: { Resource: { create: { method: 'post', path } } }, + }) + await client.Resource.create() + + // order of prepareRequest + expect(prepareRequestSpy).toHaveBeenCalledTimes(6) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(1, { ctx: 'mw3' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(2, { ctx: 'mw2' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(3, { foo: 'mw1' }) + + expect(prepareRequestSpy).toHaveBeenNthCalledWith(4, { bar: 'mw1' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(5, { fizz: 'mw2' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(6, { buzz: 'mw3' }) + + // order of response + expect(responseSpy).toHaveBeenCalledTimes(6) + expect(responseSpy).toHaveBeenNthCalledWith(1, { ctx: 'mw3' }) + expect(responseSpy).toHaveBeenNthCalledWith(2, { ctx: 'mw2' }) + expect(responseSpy).toHaveBeenNthCalledWith(3, { foo: 'mw1' }) + + expect(responseSpy).toHaveBeenNthCalledWith(4, { bar: 'mw1' }) + expect(responseSpy).toHaveBeenNthCalledWith(5, { fizz: 'mw2' }) + expect(responseSpy).toHaveBeenNthCalledWith(6, { buzz: 'mw3' }) + }) + + it('invokes resource specific middleware first', async () => { + const prepareRequestSpy = jest.fn() + const responseSpy = jest.fn() + const mw1 = createMiddleware(prepareRequestSpy, responseSpy, { foo: 'mw1' }, { bar: 'mw1' }) + const mw2 = createMiddleware(prepareRequestSpy, responseSpy, { ctx: 'mw2' }, { fizz: 'mw2' }) + const mw3 = createMiddleware(prepareRequestSpy, responseSpy, { ctx: 'mw3' }, { buzz: 'mw3' }) + const client = forge({ + clientId: 'testMw', + middleware: [mw1, mw3], + host, + resources: { Resource: { post: { method: 'post', path, middleware: [mw2] } } }, + }) + await client.Resource.post() + + // order of prepareRequest + expect(prepareRequestSpy).toHaveBeenCalledTimes(6) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(1, { ctx: 'mw3' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(2, { foo: 'mw1' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(3, { ctx: 'mw2' }) + + expect(prepareRequestSpy).toHaveBeenNthCalledWith(4, { fizz: 'mw2' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(5, { bar: 'mw1' }) + expect(prepareRequestSpy).toHaveBeenNthCalledWith(6, { buzz: 'mw3' }) + + // order of response + expect(responseSpy).toHaveBeenCalledTimes(6) + expect(responseSpy).toHaveBeenNthCalledWith(1, { ctx: 'mw3' }) + expect(responseSpy).toHaveBeenNthCalledWith(2, { foo: 'mw1' }) + expect(responseSpy).toHaveBeenNthCalledWith(3, { ctx: 'mw2' }) + + expect(responseSpy).toHaveBeenNthCalledWith(4, { fizz: 'mw2' }) + expect(responseSpy).toHaveBeenNthCalledWith(5, { bar: 'mw1' }) + expect(responseSpy).toHaveBeenNthCalledWith(6, { buzz: 'mw3' }) + }) + }) })