UNPKG

@contract-case/case-core-plugin-http

Version:

ContractCase core HTTP plugin, providing HTTP matchers and mocks

112 lines 5.66 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupHttpResponseProducer = void 0; const express_1 = __importDefault(require("express")); const case_plugin_base_1 = require("@contract-case/case-plugin-base"); const case_core_plugin_http_dsl_1 = require("@contract-case/case-core-plugin-http-dsl"); const addressToString = (address) => { if (typeof address === 'string') return address; if (address === null || address === undefined) return `${address}`; /* // This is no longer required after bumping axios version if (address.family === 'IPv6') { return `[${address.address === '::' ? '::' : address.address}]:${ address.port }`; } */ return `${address.address === '::' ? 'localhost' : address.address}:${address.port}`; }; const validateHttpResponseData = (maybeHttpResponseData) => { if (maybeHttpResponseData === null || typeof maybeHttpResponseData !== 'object') { throw new case_plugin_base_1.CaseConfigurationError("Expected response description didn't resolve to a object"); } const data = maybeHttpResponseData; if (!('status' in data)) { throw new case_plugin_base_1.CaseConfigurationError("Expected response description didn't contain a 'status' key"); } if (typeof data.status === 'string') { data.status = Number.parseInt(data.status, 10); } return data; }; const setupHttpResponseProducer = ({ request: expectedRequest, response: responseMatcher, }, context) => { let requestData; let server; return Promise.resolve() .then(() => validateHttpResponseData(context.descendAndStrip(responseMatcher, (0, case_plugin_base_1.addLocation)('expectedRequest', context)))) .then((expectedResponse) => new Promise((resolve, reject) => { const app = (0, express_1.default)(); // TODO: Only do this if we need to app.use(express_1.default.json()); app.all('*', (req, res, next) => { requestData = { method: req.method, path: req.path, body: req.body, query: req.query, headers: req.headers, }; context.logger.debug(`Mock server at '${addressToString(server?.address())}' received`, requestData); res.status(expectedResponse.status); if (expectedResponse.body) { context.logger.debug(`Sending HTTP ${expectedResponse.status} response to '${addressToString(server?.address())}', with body:`, expectedResponse.body); res.send(expectedResponse.body); } else { context.logger.debug(`Sending empty HTTP ${expectedResponse.status} response to '${addressToString(server?.address())}'`); res.send(); } next(); }); server = app.listen(); server.keepAliveTimeout = 0; const address = server.address(); context.logger.maintainerDebug(`Mock server setup on address`, address); context.logger.debug(`Mock server now listening on ${addressToString(address)}`); if (address == null) { context.logger.error(`Server address was null or undefined. This shouldn't happen, and is a bug`); reject(new case_plugin_base_1.CaseCoreError('Server address was null after startup', context)); return; } const setup = { '_case:mock:type': case_core_plugin_http_dsl_1.MOCK_HTTP_SERVER, stateVariables: context['_case:currentRun:context:variables'], functions: {}, mock: { baseUrl: `http://${addressToString(address)}` }, }; context.logger.maintainerDebug(`Mock listening and ready to accept ${typeof address === 'object' ? address.family : 'no-family'} connections: `, setup); resolve({ config: setup, assertableData: () => new Promise((startVerify, closeReject) => { context.logger.maintainerDebug(`Closing server from ${setup.mock.baseUrl}, first politely:`, setup); server.close((err) => { if (err) { context.logger.error(`There was an error shutting down the mock server. This shouldn't happen - errors here means that the server probably isn't started. Almost certainly there's a bug.`); closeReject(new case_plugin_base_1.CaseCoreError(`The server at ${setup.mock.baseUrl} was not running when it was asserted: ${err}`)); } else { context.logger.maintainerDebug(`Server at ${setup.mock.baseUrl} closed`, setup); startVerify(); } }); context.logger.maintainerDebug(`And also forcefully closing server from ${setup.mock.baseUrl}`, setup); server.closeAllConnections(); }).then(async () => { context.logger.maintainerDebug(`Asserting that the expected request for the mock at ${setup.mock.baseUrl} happened correctly`); return { actual: requestData, context: (0, case_plugin_base_1.addLocation)('request', context), expected: expectedRequest, }; }), }); })); }; exports.setupHttpResponseProducer = setupHttpResponseProducer; //# sourceMappingURL=mockHttpServer.js.map