@contract-case/case-core-plugin-http
Version:
ContractCase core HTTP plugin, providing HTTP matchers and mocks
112 lines • 5.66 kB
JavaScript
;
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