@contract-case/case-core-plugin-http
Version:
ContractCase core HTTP plugin, providing HTTP matchers and mocks
140 lines (139 loc) • 7.04 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupHttpResponseConsumer = void 0;
const axios_1 = __importDefault(require("axios"));
const http = __importStar(require("node:http"));
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 assert_1 = require("./assert/assert");
const description_1 = require("../description");
const isHasBaseUrl = (context) => '_case:currentRun:context:baseUrlUnderTest' in context &&
context['_case:currentRun:context:baseUrlUnderTest'] !== undefined &&
typeof context['_case:currentRun:context:baseUrlUnderTest'] === 'string';
const validatePluginConfig = (context, pluginConfig) => {
if (!('baseUrlUnderTest' in pluginConfig)) {
throw new case_plugin_base_1.CaseConfigurationError(`Must provide baseUrlUnderTest in order to validate HTTP response providers.
Please ensure that config.mockConfig[${description_1.description.shortName}].baseUrlUnderTest
is set appropriately.`, context);
}
if (typeof pluginConfig['baseUrlUnderTest'] !== 'string') {
throw new case_plugin_base_1.CaseConfigurationError(`baseUrlUnderTest was provided, but was not a string.
Please ensure that config.mockConfig[${description_1.description.shortName}].baseUrlUnderTest
is set appropriately.`, context);
}
// TODO: The next version of typescript should be smart enough to be able to
// remove this assertion
return pluginConfig;
};
const validateConfig = (context) => {
if (isHasBaseUrl(context)) {
context.logger.warn(`baseUrlUnderTest is deprecated and should be set via
mockConfig['http'].baseUrlUnderTest instead`);
return context;
}
const pluginConfig = (0, case_plugin_base_1.getPluginConfig)(context, description_1.description);
// This method will throw if the plugin config isn't valid
validatePluginConfig(context, pluginConfig);
return context;
};
const httpAgent = new http.Agent({
keepAlive: false,
});
const validateHttpRequestData = (maybeHttpRequestData) => {
const data = maybeHttpRequestData;
if (data === null || typeof data !== 'object') {
throw new case_plugin_base_1.CaseConfigurationError("Expected request description didn't resolve to a object");
}
const { assertFieldPresent, assertIfFieldPresent } = (0, assert_1.makeAssertionsOn)(data, 'Expected request description');
assertFieldPresent({ field: 'method', type: 'string' });
assertFieldPresent({ field: 'path', type: 'string' });
assertIfFieldPresent({ field: 'query', type: 'object' });
assertIfFieldPresent({ field: 'body', type: 'object' });
assertIfFieldPresent({ field: 'headers', type: 'object', notNull: true });
return data;
};
const getBaseUrlUnderTest = (context) => {
if (isHasBaseUrl(context)) {
return context['_case:currentRun:context:baseUrlUnderTest'];
}
return validatePluginConfig(context, (0, case_plugin_base_1.getPluginConfig)(context, description_1.description))
.baseUrlUnderTest;
};
const setupHttpResponseConsumer = ({ request: requestMatcher, response: expectedResponse, }, parentContext) => Promise.resolve().then(() => {
const expectedRequest = validateHttpRequestData(parentContext.descendAndStrip(requestMatcher, (0, case_plugin_base_1.addLocation)('expectedRequest', parentContext)));
const { body, method, path, headers, query } = expectedRequest;
return Promise.resolve(validateConfig(parentContext)).then((run) => ({
config: {
'_case:mock:type': case_core_plugin_http_dsl_1.MOCK_HTTP_CLIENT,
stateVariables: parentContext['_case:currentRun:context:variables'],
functions: {},
mock: {},
},
assertableData: () => axios_1.default
.request({
validateStatus: () => true, // This means that all status codes resolve the promise
method,
httpAgent,
url: `${getBaseUrlUnderTest(run)}${path}`,
...(body
? {
body,
}
: {}),
...(headers ? { headers } : {}),
...(query ? { params: query } : {}),
})
.then((response) => ({ body: response.data, status: response.status }), (err) => {
if (axios_1.default.isAxiosError(err)) {
if (err.request) {
return Promise.reject(new case_plugin_base_1.CaseConfigurationError(`[${err.code ? err.code : 'HTTP_FAIL'}]\n\nRequest was made to '${getBaseUrlUnderTest(run)}', but no response. \n\nConfirm that you have:\n 1) Started the real server\n 2) Provided the correct URL to the running server\n\nUnderlying Error: ${err.message}`, run));
}
throw new case_plugin_base_1.CaseConfigurationError(`Unable to send request to http server - did you start the server and provide the URL? (${err.message})`, run);
}
throw new case_plugin_base_1.CaseCoreError(`Something went wrong while creating the http request: ${err.message}`, run);
})
.then(async (result) => ({
actual: result,
context: (0, case_plugin_base_1.addLocation)('response', parentContext),
expected: expectedResponse,
})),
}));
});
exports.setupHttpResponseConsumer = setupHttpResponseConsumer;
//# sourceMappingURL=mockHttpClient.js.map