UNPKG

just-api

Version:

Specification based API test framework for HTTP APIs (REST, GraphQL)

850 lines (688 loc) 36.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _request = require('./request'); var _request2 = _interopRequireDefault(_request); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _utils = require('./utils'); var _errors = require('./errors'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const url = require('url'); const format = require('string-template'); const validateObject = require('jsonschema').validate; const jsonPath = require('jsonpath'); const Cookie = require('request-cookies').Cookie; class Spec { constructor(data, suite) { let type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'test'; let dependencyOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; this.suite = suite; this.data = data; this.assignName(); this.userContext = {}; this.setInitialContext(); this.type = type; this.dependencyOpts = dependencyOptions; this.requests = []; this.result = { suiteName: this.suite.name, name: this.data.name, status: null, file: this.suite.file, duration: 0, startTime: new Date(), endTime: null, steps: [], context: '', error: null }; } setInitialContext() { this.userContext.name = this.name; } assignName() { if (this.isLoopSpec()) { this.name = `${this.data.name} - loop iteration ${parseInt(this.data.loopData.index) + 1}`; } else { this.name = this.data.name; } } getLoopItem() { return this.data.loopData; } isLoopSpec() { return this.data.loopSpec; } async init() { return await this.run(); } setEndTime() { this.result.endTime = new Date(); } setDuration() { if (!this.result.endTime) { this.setEndTime(); } this.result.duration = this.result.endTime.getTime() - this.result.startTime.getTime(); this.duration = this.result.duration; } async run() { if (this.type === 'test') { return await this.runAsTest(); } else { return this.runAsDependency(); } } async runAsTest() { var startTime = new Date(); if (this.suite.hooks.before_each) { await this.runHook('before each', this.suite.hooks.before_each); } if (this.data.before_test) { await this.runHook('before test', this.data.before_test); } let testContext = Object.assign({}, this.userContext); delete testContext.method; let reqOptions = await this.buildRequestDetails(testContext); let response = await this.processRequest(reqOptions); try { await this.validateResponse(response); } catch (err) { if (this.data.retry) { let retriesResult = await this.processRetries(reqOptions); response = retriesResult.response; if (retriesResult.error === null) { this.result.status = 'pass'; } else { this.result.status = 'fail'; this.result.error = retriesResult.error; let error = retriesResult.error; error.message = `${error.message} \n request: ${response._req.method.toUpperCase()} ${response._req.href}`; throw error; } } else { this.result.status = 'fail'; this.result.error = err; err.message = `${err.message} \n request: ${response._req.method.toUpperCase()} ${response._req.href}`; throw err; } } if (this.data.after_test) { await this.runHook('after test', this.data.after_test, { response: response }); } if (this.suite.hooks.after_each) { await this.runHook('after each', this.suite.hooks.after_each, { response: response }); } this.setEndTime(); this.setDuration(); this.result.error = null; this.result.status = 'pass'; return this.result; } async processRetries(reqOptions) { const retryInfo = this.data.retry; let attempts = (0, _utils.isNumber)(retryInfo.count) ? parseInt(retryInfo.count) : 1; let waitTimeBeforeEachAttempt = (0, _utils.isNumber)(retryInfo.wait_before_each) ? parseInt(retryInfo.wait_before_each) : 100; let currentAttempts = 0; while (currentAttempts <= attempts) { await (0, _utils.wait)(waitTimeBeforeEachAttempt); currentAttempts += 1; let response; try { response = await this.processRequest(reqOptions); await this.validateResponse(response); return { error: null, response: response }; } catch (err) { if (currentAttempts >= attempts) { return { error: err, response: response }; } } } } async runAsDependency() { const dependencyOptions = this.dependencyOpts; delete dependencyOptions.method; let reqOptions = await this.buildRequestDetails(dependencyOptions); const response = await this.processRequest(reqOptions); if (dependencyOptions.validateResponse) { await this.validateResponse(response); return response._response; } else { return response._response; } } async buildRequestDetails(opts) { let _reqOptions = {}; try { _reqOptions.baseUrl = this.buildBaseURL(opts); let subPath = this.buildPath(opts); if (subPath) { _reqOptions.url = subPath; } else { _reqOptions.url = _reqOptions.baseUrl; delete _reqOptions.baseUrl; } _reqOptions.qs = this.buildQueryParams(opts); _reqOptions.headers = this.buildHeaders(opts); _reqOptions.cookiesData = this.buildCookies(opts); _reqOptions.timeout = this.getTimeout(opts); _reqOptions.method = this.data.request.method.toLowerCase(); } catch (err) { let RequestBuilderError = (0, _errors.customError)('RequestBuilderError'); throw new RequestBuilderError(` ${err.name} ${err.message}`); } if (['patch', 'post', 'put'].indexOf(_reqOptions.method) !== -1) { try { let bodyOptions = this.buildRequestBody(opts, _reqOptions.headers, _reqOptions.method); _reqOptions = Object.assign(_reqOptions, bodyOptions); } catch (err) { if (_errors.errorTypes.indexOf(err.name) !== -1) { throw err; } else { let RequestBodyBuilderError = (0, _errors.customError)('RequestBodyBuilderError'); throw new RequestBodyBuilderError(` ${err.name} ${err.message}`); } } } this.addAdditionalRequestOptions(_reqOptions); return _reqOptions; } async processRequest(opts) { let _req = new _request2.default(opts, this); return _req.send(); } getTimeout(opts) { return opts.read_timeout || this.data.request.read_timeout || this.suite.targetConfiguration.read_timeout; } async runHook(type, hookData, opts) { try { const data = hookData; const self = this; let _context = { suite: this.suite.userContext, runSpec: this.suite.runDependencySpec, test: this.userContext, _sctx: self.suite }; if (this.isLoopSpec()) _context.loopItem = this.getLoopItem().value; if (type === 'after test' || type === 'after each') { _context.response = opts.response._response; } if (typeof data !== 'object') { throw Error(`Invalid ${type} hook schema`); } let InvalidYAMLSuiteSchemaError = (0, _errors.customError)('InvalidYAMLSuiteSchemaError'); if (data.run_type === 'inline') { if (data.inline) { let inlineFunction = data.inline.function; await (0, _utils.runInlineFunction)(inlineFunction, _context); } else { throw new InvalidYAMLSuiteSchemaError(`Test ${type} hook inline function definition is not specified`); } } else if (data.run_type === 'module') { if (data.module) { let modulePath = this.suite.resolveFile(data.module.module_path); const module = (0, _utils.assertFileValidity)(modulePath, 'Test ${type} hook module'); const customModule = (0, _utils.loadModule)(module); await (0, _utils.runModuleFunction)(customModule, data.module.function_name, _context); } else { throw new InvalidYAMLSuiteSchemaError(`Test ${type} hook module function definition is not specified`); } } else { throw new InvalidYAMLSuiteSchemaError(`Test ${type} hook run type should be inline or module`); } } catch (err) { let errorType; if (type === 'before each') { errorType = (0, _errors.customError)('BeforeEachHookError'); } else if (type === 'after each') { errorType = (0, _errors.customError)('AfterEachHookError'); } else if (type === 'before test') { errorType = (0, _errors.customError)('BeforeTestHookError'); } else if (type === 'after test') { errorType = (0, _errors.customError)('AfterTestHookError'); } else { throw new Error(`Unknown hook ${type}`); } throw new errorType(`${err.name || 'Error'} - ${err.message || err}`); } } async validateResponse(response) { const code = this.data.response.status_code; if (code) { this._validateStatus(response, code); } const expectedHeaders = this.data.response.headers; if (expectedHeaders) { this._validateHeaders(response, expectedHeaders); } const cookies = this.data.response.cookies; if (cookies) { this._validateCookies(response, cookies); } const jsonSchemaInfo = this.data.response.json_schema; if (jsonSchemaInfo) { this._validateJSONSchema(response, jsonSchemaInfo); } const jsonData = this.data.response.json_data; if (jsonData) { this._validateJSONData(response, jsonData); } if (this.data.response.custom_validator) { await this.runCustomResponseValidator(response); } return true; } async runCustomResponseValidator(response) { const data = this.data.response.custom_validator; const dependencySuite = this.dependencyOpts.outerDependency ? this.dependencyOpts.outerDependencySuite : this.suite; let _context = { response: response._response }; if (this.isLoopSpec()) _context.loopItem = this.getLoopItem().value; let InvalidYAMLSuiteSchemaError = (0, _errors.customError)('InvalidYAMLSuiteSchemaError'); let CustomResponseValidationError = (0, _errors.customError)('CustomResponseValidationError'); try { if (data.run_type === 'inline') { if (data.inline) { let inlineFunction = data.inline.function; await (0, _utils.runInlineFunction)(inlineFunction, _context); } else { throw new InvalidYAMLSuiteSchemaError(`Custom validator inline function definition is not specified`); } } else if (data.run_type === 'module') { if (data.module) { let modulePath = dependencySuite.resolveFile(data.module.module_path); const module = (0, _utils.assertFileValidity)(modulePath, 'custom validation module'); const customModule = (0, _utils.loadModule)(module); await (0, _utils.runModuleFunction)(customModule, data.module.function_name, _context); } else { throw new InvalidYAMLSuiteSchemaError(`Custom validator module function definition is not specified`); } } else { throw new InvalidYAMLSuiteSchemaError(`Custom validator run type should be inline or module`); } } catch (err) { if (err.name === 'CustomResponseValidationError') { throw err; } else { throw new CustomResponseValidationError(`${err.name || 'Error'} occurred in custom response validation \n ${err.message || err}`); } } } buildBaseURL(additionalOptions) { let options; if (additionalOptions.outerDependency) { options = Object.assign({}, additionalOptions.outerDependencySuite.targetConfiguration, this.data.request, additionalOptions); } else { options = Object.assign({}, this.suite.targetConfiguration, this.data.request, additionalOptions); } return url.format({ protocol: options.scheme, hostname: options.host, port: options.port, pathname: options.base_path }); } buildPath(additionalOptions) { let path = additionalOptions.path || this.data.request.path || ''; if (path.length === 0) return ''; let defaultPathParams = {}; const specParams = this.data.request.path_params; if (specParams) { for (let item of specParams) { defaultPathParams[item['name']] = item['value']; } } let customPathParams = additionalOptions.path_params || {}; const params = Object.assign({}, defaultPathParams, customPathParams); return format(path, params); } buildQueryParams(additionalOptions) { let defaultParams = {}; const specParams = this.data.request.query_params; if (specParams) { for (let item of specParams) { defaultParams[item['name']] = item['value']; } } let customParams = additionalOptions.query_params || {}; return Object.assign({}, defaultParams, customParams); } buildHeaders(additionalOptions) { let defaultHeaders = {}; const specHeaders = this.data.request.headers; if (specHeaders) { for (let item of specHeaders) { defaultHeaders[item['name']] = item['value']; } } let customHeaders = additionalOptions.headers || {}; let commonSuiteHeaders = this.data.ignore_suite_headers ? {} : additionalOptions.outerDependency ? additionalOptions.outerDependencySuite.commonHeaders : this.suite.commonHeaders; return Object.assign({}, commonSuiteHeaders, defaultHeaders, customHeaders); } buildCookies(additionalOptions) { let defaultCookies = {}; const specCookies = this.data.request.cookies; if (specCookies) { for (let item of specCookies) { defaultCookies[item['name']] = item['value']; } } let customCookies = additionalOptions.cookies || {}; return Object.assign({}, defaultCookies, customCookies); } addAdditionalRequestOptions(reqOptions) { const supportedOptions = ['followRedirect', 'followAllRedirects', 'followOriginalHttpMethod', 'encoding', 'gzip']; const options = this.data.request.additional_options; if (options) { for (let _ref of Object.entries(options)) { var _ref2 = _slicedToArray(_ref, 2); let key = _ref2[0]; let value = _ref2[1]; if (supportedOptions.indexOf(key) !== -1) { reqOptions[key] = value; } } } } buildRequestBody(additionalOptions, headers, method) { let bodyData = {}; let requestContentType = headers['content-type']; let RequestBodyNotFoundError = (0, _errors.customError)('RequestBodyNotFoundError'); let InvalidRequestSpecificationError = (0, _errors.customError)('InvalidRequestSpecificationError'); let InvalidRequestHeaderError = (0, _errors.customError)('InvalidRequestHeaderError'); let RequestBodyBuilderError = (0, _errors.customError)('RequestBodyBuilderError'); const payload = additionalOptions.payload || this.data.request.payload; const dependencySuite = additionalOptions.outerDependency ? additionalOptions.outerDependencySuite : this.suite; if (requestContentType && requestContentType.length > 1) { let expectedBodyFields = ['body', 'form', 'form_data']; if (!payload) { throw new RequestBodyNotFoundError(`request content-type is ${requestContentType}, but request body is not found`); } if (typeof payload !== 'object') { throw new RequestBodyNotFoundError(`request content-type is ${requestContentType}, invalid specification for request body. \n Provide request body as one of ${expectedBodyFields} in payload `); } let reqKeys = Object.keys(payload); let providedFields = reqKeys.filter(key => expectedBodyFields.indexOf(key) !== -1); if (providedFields.length < 1) { throw new RequestBodyNotFoundError(`Request method is ${method}, but request specification does not have any expected body fields. \n Provide request body as one of ${expectedBodyFields}`); } if (providedFields.length > 1) { throw new InvalidRequestSpecificationError(`request method is ${method}, and request specification contains more than one of expected body fields. Provide one of ${expectedBodyFields}`); } let providedBodyField = providedFields[0]; if (providedBodyField === 'body') { let givenBody = payload.body; if (givenBody.type === 'binary') { let file = dependencySuite.resolveFile(payload.body.content); try { let fileExistsAndFile = _fs2.default.lstatSync(file).isFile(); if (fileExistsAndFile) { bodyData.body = _fs2.default.createReadStream(file); } else { throw new RequestBodyBuilderError(`${file} is not a file, Provide a valid file path to be sent as body content`); } } catch (e) { if (e.code == 'ENOENT') { throw new RequestBodyBuilderError(`ENOENT file at '${file}' does not exist, Provide a valid file path to be sent as body content`); } else { throw e; } } } else if (givenBody.type === 'text') { if (typeof givenBody.content === 'string' || typeof givenBody.content === 'number') { bodyData.body = givenBody.content.toString(); } else { throw new InvalidRequestSpecificationError(`Payload type is given as text, but content provided is not a string or number`); } } else if (givenBody.type === 'json') { if (typeof givenBody.content === 'string' || typeof givenBody.content === 'number') { bodyData.body = givenBody.content; } else if (typeof givenBody.content === 'object') { if (requestContentType === 'application/json') { bodyData.body = JSON.stringify(givenBody.content); } else { throw new InvalidRequestSpecificationError(`Request body is an object but content-type header value is not application/json`); } } else { try { bodyData.body = JSON.stringify(givenBody.content); } catch (error) { throw new RequestBodyBuilderError(`${error.name} Unable to dump the body content as json \n ${error.message}`); } } } else { throw new InvalidRequestSpecificationError(`body type should be one of binary, json or text`); } } if (providedBodyField === 'form') { if (requestContentType !== 'application/x-www-form-urlencoded') { throw new InvalidRequestHeaderError(`Request body is provided as form but request Content-Type is ${requestContentType}. It should be application/x-www-form-urlencoded`); } bodyData.form = payload.form; } if (providedBodyField === 'form_data') { let formData = {}; let giveFormData = payload.form_data; if (requestContentType !== 'multipart/form-data') { throw new InvalidRequestHeaderError(`Request body is provided as formData but request Content-Type is ${requestContentType}. It should be multipart/form-data`); } for (let formParam of giveFormData) { if (formParam.type === 'file') { let file = dependencySuite.resolveFile(formParam.content); try { let fileExistsAndFile = _fs2.default.lstatSync(file).isFile(); if (fileExistsAndFile) { let paramData = {}; paramData.value = _fs2.default.createReadStream(file); paramData.options = formParam.options; formData[formParam.name] = paramData; } else { throw new RequestBodyBuilderError(` '${file}' is not a file, Provide a valid path for content of form body`); } } catch (e) { if (e.code == 'ENOENT') { throw new RequestBodyBuilderError(`ENOENT file at '${file}' does not exist, Provide a valid path for content of form body`); } else { throw e; } } } else if (formParam.type === 'text') { let paramData = {}; if (typeof formParam.content === 'string' || typeof formParam.content === 'number') { paramData.value = formParam.content.toString(); paramData.options = formParam.options; formData[formParam.name] = paramData; } else { throw new InvalidRequestSpecificationError(`Multipart form field type is given as text, but content provided is not a string or number`); } } else if (formParam.type === 'json') { let paramData = {}; if (typeof formParam.content === 'string' || typeof formParam.content === 'number') { paramData.value = formParam.content; paramData.options = formParam.options; formData[formParam.name] = paramData; } else if (typeof formParam.content === 'object') { paramData.value = JSON.stringify(formParam.content); paramData.options = formParam.options; formData[formParam.name] = paramData; } else { try { paramData.value = JSON.stringify(formParam.content); } catch (error) { throw new RequestBodyBuilderError(`${error.name} Unable to dump the body content as json \n ${error.message}`); } paramData.options = formParam.options; formData[formParam.name] = paramData; } } else { throw new InvalidRequestSpecificationError(`body type should be one of binary, json or text`); } } bodyData.formData = formData; } } else if (payload && !requestContentType) { throw new InvalidRequestHeaderError(`Request method is ${method},request body is provided but Content-Type header is not provided`); } else { return bodyData; } return bodyData; } _validateStatus(response, code) { if (code !== response._response.statusCode) { let ResponseStatusCodeDidNotMatchError = (0, _errors.customError)('ResponseStatusCodeDidNotMatchError'); throw new ResponseStatusCodeDidNotMatchError(`Expected status code: ${code}, Actual status code: ${response._response.statusCode}`); } return true; } _validateHeaders(response, expectedHeaders) { let headers = {}; let ResponseHeaderValueDidNotMatchError = (0, _errors.customError)('ResponseHeaderValueDidNotMatchError'); for (let item of expectedHeaders) { headers[item['name'].toLowerCase()] = item['value']; } const actualHeaders = response._response.headers; for (let headerKey in headers) { let expectedHeaderValue = headers[headerKey]; let actualHeaderValue = actualHeaders[headerKey]; if (typeof actualHeaderValue === 'undefined') { throw new ResponseHeaderValueDidNotMatchError(`Expected value for header: ${headerKey} is ${expectedHeaderValue}, Actual value: [couldn't find it in response headers]`); } if (expectedHeaderValue.constructor.name === 'RegExp') { const result = expectedHeaderValue.test(actualHeaderValue.toString()); if (!result) { throw new ResponseHeaderValueDidNotMatchError(`Header value did not match with expected Regex. Expected value for header: ${headerKey} is to match RegExp ${expectedHeaderValue}, Actual value: ${actualHeaderValue}`); } } else { if (expectedHeaderValue.toString() !== actualHeaderValue.toString()) { throw new ResponseHeaderValueDidNotMatchError(`Expected value for header: ${headerKey} is ${expectedHeaderValue}, Actual value: ${actualHeaderValue}`); } } } return true; } _validateCookies(response, expectedCookies) { let cookies = {}; let ResponseCookieValueDidNotMatchError = (0, _errors.customError)('ResponseCookieValueDidNotMatchError'); for (let item of expectedCookies) { cookies[item['name']] = { value: item['value'] }; } let rawCookies = response._response.headers['set-cookie']; let actualCookies = {}; for (let idx in rawCookies) { let cookie = new Cookie(rawCookies[idx]); actualCookies[cookie.key] = { value: cookie.value, expires: cookie.expires }; } for (let item in cookies) { let expectedCookieDetails = cookies[item]; let actualCookieDetails = actualCookies[item]; if (typeof actualCookieDetails === 'undefined') { throw new ResponseCookieValueDidNotMatchError(`Expected value for Cookie: ${item} is ${expectedCookieDetails.value}, Actual value: [couldn't find it in response cookies]`); } if (expectedCookieDetails.value.constructor.name === 'RegExp') { const result = expectedCookieDetails.value.test(actualCookieDetails.value.toString()); if (!result) { throw new ResponseCookieValueDidNotMatchError(`Cookie value did not match with expected Regex. Expected value for cookie: ${item} is to match RegExp ${expectedCookieDetails.value}, Actual value: ${actualCookieDetails.value}`); } } else { if (expectedCookieDetails.value.toString() !== actualCookieDetails.value.toString()) { throw new ResponseCookieValueDidNotMatchError(`Expected value for cookie: ${item} is ${expectedCookieDetails.value}, Actual value: ${actualCookieDetails.value}`); } } } return true; } _validateJSONData(response, jsonData) { let jsonBody; let JSONBodyParseError = (0, _errors.customError)('JSONBodyParseError'); let ResponseJSONDataMismatchError = (0, _errors.customError)('ResponseJSONDataMismatchError'); try { jsonBody = JSON.parse(response._response.body); } catch (err) { throw new JSONBodyParseError(`${err.name} Error occurred while parsing the body as json \n ${err.message}`); } for (let eachJsonData of jsonData) { const values = jsonPath.query(jsonBody, eachJsonData.path); if (!values) { throw new ResponseJSONDataMismatchError(`JSON Path evaluation did not return any matching value, json path: ${eachJsonData.path}`); } if (eachJsonData.value === null) { if (values[0] !== eachJsonData.value) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match with expected value (null), json path: ${eachJsonData.path}, Actual value: ${values[0]}, Expected value: ${eachJsonData.value}`); } } else if ((0, _utils.isNumber)(eachJsonData.value) || eachJsonData.value.constructor.name === 'String') { if (values[0] !== eachJsonData.value) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match with expected value, json path: ${eachJsonData.path}, Actual value: ${values[0]}, Expected value: ${eachJsonData.value}`); } } else if (eachJsonData.value.constructor.name === 'RegExp') { const result = eachJsonData.value.test(values[0]); if (!result) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match the expected Regexp, json path: ${eachJsonData.path}, Regexp: ${eachJsonData.value}, Actual value: ${values[0]}`); } } else if (eachJsonData.value.constructor.name === 'Array') { if (!(0, _utils.equals)(values[0], eachJsonData.value)) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match with expected value, json path: ${eachJsonData.path}, Actual value: ${JSON.stringify(values[0])}, Expected value: ${JSON.stringify(eachJsonData.value)}`); } } else if (eachJsonData.value.constructor.name === 'Object') { if (!(0, _utils.equals)(values[0], eachJsonData.value)) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match with expected value, json path: ${eachJsonData.path}, Actual value: ${JSON.stringify(values[0])}, Expected value: ${JSON.stringify(eachJsonData.value)}`); } } else if (eachJsonData.value.constructor.name === 'Boolean') { if (values[0] !== eachJsonData.value) { throw new ResponseJSONDataMismatchError(`JSON path evaluated value did not match with expected Boolean value, json path: ${eachJsonData.path}, Actual value: ${values[0]}, Expected value: ${eachJsonData.value}`); } } else { throw new Error(`Unknown json data value type, only Array, Object, RegExp, Number, Boolean & String are allowed`); } } return true; } _validateJSONSchema(response, jsonSchemaInfo) { let InvalidSpecificationSchemaError = (0, _errors.customError)('InvalidSpecificationSchemaError'); let ResponseJSONSchemaValidationError = (0, _errors.customError)('ResponseJSONSchemaValidationError'); let expectedSchema; const dependencySuite = this.dependencyOpts.outerDependency ? this.dependencyOpts.outerDependencySuite : this.suite; try { if (jsonSchemaInfo.type === 'inline') { try { expectedSchema = JSON.parse(jsonSchemaInfo['$ref']); } catch (e) { throw new ResponseJSONSchemaValidationError(`${e.name} occurred while parsing the inline input schema \n ${e.message} \n Input schema \n ${jsonSchemaInfo['$ref']}`); } } else if (jsonSchemaInfo.type === 'file') { const schemaFile = dependencySuite.resolveFile(jsonSchemaInfo['$ref']); const fileData = _fs2.default.readFileSync(schemaFile, 'utf8'); try { expectedSchema = JSON.parse(fileData); } catch (e) { throw new ResponseJSONSchemaValidationError(`${e.name} occurred while parsing the input schema in '${schemaFile}' \n ${e.message} \n Input schema: \n ${fileData}`); } } else { throw new InvalidSpecificationSchemaError(`Response json schema type should be inline or file`); } const schemaValidation = validateObject(JSON.parse(response._response.body), expectedSchema); if (schemaValidation.errors.length >= 1) { let errors = []; for (let error of schemaValidation.errors) { errors.push(`Response json schema validation failed for property - ${error.property}, message: ${error.message}`); } throw new ResponseJSONSchemaValidationError(errors.join('\n')); } } catch (err) { if (err.name === 'ResponseJSONSchemaValidationError') { throw err; } else { throw new ResponseJSONSchemaValidationError(`${err.name} occurred during response json schema validation \n ${err.message}`); } } } } exports.default = Spec; module.exports = exports['default'];