UNPKG

@senacor/azure-function-middleware

Version:

Middleware for azure functions to handle authentication, authorization, error handling and logging

241 lines (240 loc) 13.9 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const functions_1 = require("@azure/functions"); const error_1 = require("./error"); const middleware_1 = require("./middleware"); describe('The middleware layer should', () => { const httpRequest = new functions_1.HttpRequest({ url: 'http://localhost:8080', method: 'GET', }); let context = new functions_1.InvocationContext(); beforeEach(() => { jest.restoreAllMocks(); context = new functions_1.InvocationContext(); jest.spyOn(context, 'error'); }); test('successfully call the passed functions without any middleware passed', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); yield (0, middleware_1.middleware)([], handlerMock, [])(httpRequest, new functions_1.InvocationContext()); expect(handlerMock).toHaveBeenCalledWith(httpRequest, new functions_1.InvocationContext()); })); test('successfully call the middleware and the passed functions', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); })); test('successfully call the pre middleware and post middleware and the passed functions', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); const middlewarePostMock = jest.fn(); yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [middlewarePostMock])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewarePostMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); })); test('return an error when one middleware is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); middlewareOneMock.mockRejectedValue(Error()); const res = yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $error: Error(), $failed: true, }); expect(handlerMock).not.toHaveBeenCalled(); expect(res).toEqual({ status: 500, jsonBody: { message: 'Internal server error', }, }); expect(context.error).toHaveBeenCalled(); })); test('return an error when second middleware is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); middlewareTwoMock.mockRejectedValue(Error()); const res = yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).not.toHaveBeenCalled(); expect(res).toEqual({ status: 500, jsonBody: { message: 'Internal server error', }, }); expect(context.error).toHaveBeenCalled(); })); test('return an error when the handler function is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); handlerMock.mockRejectedValue(Error()); const res = yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); expect(res).toEqual({ status: 500, jsonBody: { message: 'Internal server error', }, }); expect(context.error).toHaveBeenCalled(); })); test('return an error when the handler function is failing and a error with status is returned', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); handlerMock.mockRejectedValue(new error_1.ApplicationError('Validation Error', 401, 'test-body')); const res = yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); expect(res).toEqual({ status: 401, body: 'test-body', }); expect(context.error).toHaveBeenCalled(); })); test('return an error if the handler function is failing, but execute the post-execution-functions', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); handlerMock.mockRejectedValue(Error()); const res = yield (0, middleware_1.middleware)([middlewareOneMock], handlerMock, [middlewareTwoMock])(httpRequest, context); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); expect(res).toEqual({ status: 500, jsonBody: { message: 'Internal server error', }, }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $error: Error(), $failed: true, }); expect(context.error).toHaveBeenCalled(); })); test('use the provided error-handle to create a response', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); const middlewarePostFunction = jest.fn(); handlerMock.mockRejectedValue(Error()); const errorResponseHandler = () => { return { status: 1337, body: 'My custom error response', }; }; const res = yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [middlewarePostFunction], { errorResponseHandler, })(httpRequest, context); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); expect(res).toEqual({ status: 1337, body: 'My custom error response', }); expect(context.error).toHaveBeenCalled(); expect(middlewarePostFunction).toHaveBeenCalledWith(httpRequest, context, { $error: Error(), $failed: true, }); })); test('dynamically filter items, which resolve to false', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); const middlewarePostOneMock = jest.fn(); const middlewarePostTwoMock = jest.fn(); const excludeFunction = () => false; const includeFunction = () => true; yield (0, middleware_1.middleware)([excludeFunction() && middlewareOneMock, middlewareTwoMock], handlerMock, [ includeFunction() && middlewarePostOneMock, excludeFunction() && middlewarePostTwoMock, ])(httpRequest, context); expect(middlewareOneMock).not.toHaveBeenCalled(); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); expect(middlewarePostOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false, $result: undefined, }); expect(middlewarePostTwoMock).not.toHaveBeenCalled(); })); describe('fail if error-handling is disabled and', () => { test('the first middleware (beforeExecution) is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); middlewareOneMock.mockRejectedValue(new Error()); yield expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [], { disableErrorHandling: true })(httpRequest, context); })).rejects.toThrow(); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: true, $error: Error(), }); expect(handlerMock).not.toHaveBeenCalled(); })); test('the second middleware (beforeExecution) is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); middlewareTwoMock.mockRejectedValue(Error()); yield expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [], { disableErrorHandling: true })(httpRequest, context); })).rejects.toThrow(); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).not.toHaveBeenCalled(); })); test('the handler function is failing', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); handlerMock.mockRejectedValue(Error()); yield expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [], { disableErrorHandling: true })(httpRequest, context); })).rejects.toThrow(); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); })); test('the handler function is failing and a error with status is returned', () => __awaiter(void 0, void 0, void 0, function* () { const handlerMock = jest.fn(); const middlewareOneMock = jest.fn(); const middlewareTwoMock = jest.fn(); handlerMock.mockRejectedValue(new error_1.ApplicationError('Validation Error', 401, 'test-body')); yield expect(() => __awaiter(void 0, void 0, void 0, function* () { return yield (0, middleware_1.middleware)([middlewareOneMock, middlewareTwoMock], handlerMock, [], { disableErrorHandling: true })(httpRequest, context); })).rejects.toThrow(); expect(middlewareOneMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(middlewareTwoMock).toHaveBeenCalledWith(httpRequest, context, { $failed: false }); expect(handlerMock).toHaveBeenCalledWith(httpRequest, context); })); }); });