Skip to content

Commit

Permalink
feat: validate json body from compound schema, dereference $refs, & a…
Browse files Browse the repository at this point in the history
…llow specifying json pointer witin file

Previously, body validation according to a JSON schema in a file only supported a simple flat file. This change allows specifying any arbitrary node within a json schema (via json pointer). It also automatically de-references all remote or local external file $refs within the schema as needed.
  • Loading branch information
matmar10 committed Sep 19, 2021
1 parent 78fde73 commit de518ee
Show file tree
Hide file tree
Showing 3 changed files with 9,344 additions and 52 deletions.
24 changes: 17 additions & 7 deletions lib/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const format = require('string-template');
const validateObject = require('jsonschema').validate;
const jsonPath = require('jsonpath');
const Cookie = require('request-cookies').Cookie;
const $RefParser = require('@apidevtools/json-schema-ref-parser');

export default class Spec {
constructor(data, suite, type = 'test', dependencyOptions = {}) {
Expand Down Expand Up @@ -310,7 +311,7 @@ export default class Spec {

const jsonSchemaInfo = this.data.response.json_schema;
if (jsonSchemaInfo) {
this._validateJSONSchema(response, jsonSchemaInfo)
await this._validateJSONSchema(response, jsonSchemaInfo)
}

const jsonData = this.data.response.json_data;
Expand Down Expand Up @@ -778,7 +779,7 @@ export default class Spec {
return true;
}

_validateJSONSchema(response, jsonSchemaInfo) {
async _validateJSONSchema(response, jsonSchemaInfo) {
let InvalidSpecificationSchemaError = customError('InvalidSpecificationSchemaError');
let ResponseJSONSchemaValidationError = customError('ResponseJSONSchemaValidationError');
let expectedSchema;
Expand All @@ -793,13 +794,22 @@ export default class Spec {
}

} else if (jsonSchemaInfo.type === 'file') {
const schemaFile = dependencySuite.resolveFile(jsonSchemaInfo['$ref']);
const fileData = fs.readFileSync(schemaFile, 'utf8');

let filename;
let path;
if (jsonSchemaInfo['$ref'].match('#')) {
const parts = jsonSchemaInfo['$ref'].split(/(.+)#(.+)/);
filename = parts[1];
path = `#${parts[2]}`;
} else {
filename = jsonSchemaInfo['$ref'];
path = '#';
}
try {
expectedSchema = JSON.parse(fileData);
const $refs = await $RefParser.resolve(filename);
expectedSchema = $refs.get(path);
} catch (e) {
throw new ResponseJSONSchemaValidationError(`${e.name} occurred while parsing the input schema in '${schemaFile}' \n ${e.message} \n Input schema: \n ${fileData}`);
console.error(e);
throw new ResponseJSONSchemaValidationError(`${e.name} occurred while parsing the input schema in '${jsonSchemaInfo['$ref']}' \n ${e.message}`);
}
} else {
throw new InvalidSpecificationSchemaError(`Response json schema type should be inline or file`);
Expand Down
Loading

0 comments on commit de518ee

Please sign in to comment.