From 90d7f2997f4f370670c5d093cdccb14f6b7ef3c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Sat, 2 Apr 2022 02:34:33 -0300 Subject: [PATCH] test(response): added tests to missing coverage and better organization to test --- src/network/response.ts | 24 ++++++++++----- test/handlers/default.handler.spec.ts | 29 ++++++++++++++++++ test/network/response.spec.ts | 44 +++++++++++++++++++++++---- 3 files changed, 83 insertions(+), 14 deletions(-) diff --git a/src/network/response.ts b/src/network/response.ts index a5ee9b16..df7d1550 100644 --- a/src/network/response.ts +++ b/src/network/response.ts @@ -101,8 +101,7 @@ export class ServerlessResponse extends ServerResponse { } static headers(res: ServerlessResponse) { - const headers = - typeof res.getHeaders === 'function' ? res.getHeaders() : res._headers; + const headers = res.getHeaders(); return Object.assign(headers, res[HEADERS]); } @@ -136,12 +135,21 @@ export class ServerlessResponse extends ServerResponse { } } - // I use ignore here because in nodejs 12.x, statusMessage can be string | OutgoingHttpHeaders - // But in nodejs >=14.x, statusMessage can also be OutgoingHttpHeaders[] - // I take care of these cases above, but here I can't handle it well, so I give up - // nodejs 12.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v12/http.d.ts#L229 - // nodejs 14.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v14/http.d.ts#L263 - // @ts-ignore + return this.callNativeWriteHead(statusCode, statusMessage, obj); + } + + /** + * I use ignore here because in nodejs 12.x, statusMessage can be string | OutgoingHttpHeaders + * But in nodejs >=14.x, statusMessage can also be OutgoingHttpHeaders[] + * I take care of these cases above, but here I can't handle it well, so I give up + * nodejs 12.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v12/http.d.ts#L229 + * nodejs 14.x ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v14/http.d.ts#L263 + */ + protected callNativeWriteHead( + statusCode: number, + statusMessage?: string | any | any[], + obj?: any | any[], + ): this { return super.writeHead(statusCode, statusMessage, obj); } } diff --git a/test/handlers/default.handler.spec.ts b/test/handlers/default.handler.spec.ts index 53bdb39a..5116f514 100644 --- a/test/handlers/default.handler.spec.ts +++ b/test/handlers/default.handler.spec.ts @@ -116,4 +116,33 @@ describe('DefaultHandler', () => { Buffer.from(JSON.stringify(response)).toString('base64'), ); }); + + it('should forward and return the response from a request with empty body', async () => { + const framework = new FrameworkMock(200, response); + + const handler = defaultHandler.getHandler( + app, + framework, + adapters, + resolver, + { isBinary: () => true }, + respondWithErrors, + logger, + ); + + const event = createApiGatewayV2('GET', '/users', undefined, { + test: 'true', + }); + const context = { test: Symbol('unique') }; + + const result = await handler(event, context, NO_OP); + + expect(result).toHaveProperty('headers', {}); + expect(result).toHaveProperty('isBase64Encoded', true); + expect(result).toHaveProperty('statusCode', 200); + expect(result).toHaveProperty( + 'body', + Buffer.from(JSON.stringify(response)).toString('base64'), + ); + }); }); diff --git a/test/network/response.spec.ts b/test/network/response.spec.ts index 0fe76523..8945ecda 100644 --- a/test/network/response.spec.ts +++ b/test/network/response.spec.ts @@ -183,23 +183,41 @@ describe('ServerlessResponse', () => { }); it('should write headers correctly in object when call writeHead', () => { - const response = new ServerlessResponse({ + class MockServerlessResponse extends ServerlessResponse { + public callNativeWriteHead( + statusCode: number, + statusMessage?: string | any | any[], + obj?: any | any[], + ): this { + return super.callNativeWriteHead(statusCode, statusMessage, obj); + } + } + + const response = new MockServerlessResponse({ method: 'GET', }); + response.callNativeWriteHead = jest.fn(); response.setHeader = jest.fn(); - expect(() => response.writeHead(200, { test: 'true' })).not.toThrowError(); + expect(() => response.writeHead(200, { test1: 'true' })).not.toThrowError(); expect(() => - response.writeHead(200, 'test', { test: 'true' }), + response.writeHead(200, [{ test2: 'true' }, { test3: 'true' }]), + ).not.toThrowError(); + expect(() => + response.writeHead(200, 'test', { test4: 'true' }), ).not.toThrowError(); // eslint-disable-next-line @typescript-eslint/unbound-method - expect(response.setHeader).toHaveBeenCalledTimes(2); + expect(response.setHeader).toHaveBeenCalledTimes(4); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(response.setHeader).toHaveBeenNthCalledWith(1, 'test1', 'true'); + // eslint-disable-next-line @typescript-eslint/unbound-method + expect(response.setHeader).toHaveBeenNthCalledWith(2, 'test2', 'true'); // eslint-disable-next-line @typescript-eslint/unbound-method - expect(response.setHeader).toHaveBeenNthCalledWith(1, 'test', 'true'); + expect(response.setHeader).toHaveBeenNthCalledWith(3, 'test3', 'true'); // eslint-disable-next-line @typescript-eslint/unbound-method - expect(response.setHeader).toHaveBeenNthCalledWith(2, 'test', 'true'); + expect(response.setHeader).toHaveBeenNthCalledWith(4, 'test4', 'true'); }); it('should write headers correctly in object when call setHeader', () => { @@ -218,4 +236,18 @@ describe('ServerlessResponse', () => { expect(response.getHeaders()).not.toHaveProperty('test2', 'value'); expect(response.headers).toHaveProperty('test2', 'value'); }); + + it('should received error when statusCode is falsy', () => { + const request = new ServerlessRequest({ + method: 'GET', + url: '/users', + headers: {}, + }); + + request.statusCode = undefined; + + expect(() => ServerlessResponse.from(request)).toThrowError( + 'Invalid status code', + ); + }); });