UNPKG

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

Version:

ContractCase core HTTP plugin, providing HTTP matchers and mocks

140 lines (139 loc) 7.04 kB
"use strict"; 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