mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
support for defined schema dialect property on validate transaction
This commit is contained in:
@@ -30,11 +30,22 @@ function getLocalDraft(schema) {
|
||||
/**
|
||||
* Gets the correct validator according to the draft
|
||||
*
|
||||
* @param {string} draft - the draft identifier
|
||||
* @returns {string} the id
|
||||
* @param {string} draftToUse - the draft to use in validation
|
||||
* @returns {string} the draft identifier
|
||||
*/
|
||||
function getAjvValidator(draft) {
|
||||
return draft === specialDraft ? validateSchemaAJVDraft04 : validateSchemaAJV;
|
||||
function getAjvValidator(draftToUse) {
|
||||
return draftToUse === specialDraft ? validateSchemaAJVDraft04 : validateSchemaAJV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the draft to use in validation
|
||||
*
|
||||
* @param {string} localDraft - the draft from the schema object
|
||||
* @param {string} jsonSchemaDialect - the draft from the OAS object
|
||||
* @returns {string} the draft to use
|
||||
*/
|
||||
function getDraftToUse(localDraft, jsonSchemaDialect) {
|
||||
return localDraft ? localDraft : jsonSchemaDialect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,13 +55,15 @@ function getAjvValidator(draft) {
|
||||
* @param {*} schema - schema to validate
|
||||
* @param {*} valueToUse - value to validate schema against
|
||||
* @param {*} options - a standard list of options that's globally passed around. Check options.js for more.
|
||||
* @param {string} jsonSchemaDialect - the defined schema in the OAS object
|
||||
* @returns {*} - Found Validation Errors
|
||||
*/
|
||||
function validateSchema (schema, valueToUse, options = {}) {
|
||||
function validateSchema (schema, valueToUse, options = {}, jsonSchemaDialect) {
|
||||
let validate,
|
||||
compoundResult,
|
||||
filteredValidationError,
|
||||
draftToUse = getLocalDraft(schema);
|
||||
localDraft = getLocalDraft(schema),
|
||||
draftToUse = getDraftToUse(localDraft, jsonSchemaDialect);
|
||||
const validator = getAjvValidator(draftToUse);
|
||||
compoundResult = validator(schema, valueToUse, draftToUse);
|
||||
if (compoundResult.filteredValidationError) {
|
||||
@@ -96,5 +109,6 @@ function validateSchema (schema, valueToUse, options = {}) {
|
||||
module.exports = {
|
||||
validateSchema,
|
||||
getLocalDraft,
|
||||
getAjvValidator
|
||||
getAjvValidator,
|
||||
getDraftToUse
|
||||
};
|
||||
|
||||
@@ -3037,11 +3037,12 @@ module.exports = {
|
||||
* @param {Object} components - Components in the spec that the schema might refer to
|
||||
* @param {Object} options - Global options
|
||||
* @param {Object} schemaCache object storing schemaFaker and schmeResolution caches
|
||||
* @param {string} jsonSchemaDialect The schema dialect defined in the OAS object
|
||||
* @param {Function} callback - For return
|
||||
* @returns {Array} array of mismatches
|
||||
*/
|
||||
checkValueAgainstSchema: function (property, jsonPathPrefix, txnParamName, value, schemaPathPrefix, openApiSchemaObj,
|
||||
parameterSourceOption, components, options, schemaCache, callback) {
|
||||
parameterSourceOption, components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||
|
||||
let mismatches = [],
|
||||
jsonValue,
|
||||
@@ -3075,7 +3076,7 @@ module.exports = {
|
||||
setTimeout(() => {
|
||||
this.checkValueAgainstSchema(property, jsonPathPrefix, txnParamName, value,
|
||||
`${schemaPathPrefix}.${schema.oneOf ? 'oneOf' : 'anyOf'}[${_.findIndex(compositeSchema, elementSchema)}]`,
|
||||
elementSchema, parameterSourceOption, components, options, schemaCache, cb);
|
||||
elementSchema, parameterSourceOption, components, options, schemaCache, jsonSchemaDialect, cb);
|
||||
}, 0);
|
||||
}, (err, results) => {
|
||||
let sortedResults;
|
||||
@@ -3167,7 +3168,7 @@ module.exports = {
|
||||
// only do AJV if type is array or object
|
||||
// simpler cases are handled by a type check
|
||||
if (isCorrectType && needJsonMatching) {
|
||||
let filteredValidationError = validateSchema(schema, valueToUse, options);
|
||||
let filteredValidationError = validateSchema(schema, valueToUse, options, jsonSchemaDialect);
|
||||
|
||||
if (!_.isEmpty(filteredValidationError)) {
|
||||
let mismatchObj,
|
||||
@@ -3312,6 +3313,7 @@ module.exports = {
|
||||
* @param {*} components the components + paths from the OAS spec that need to be used to resolve $refs
|
||||
* @param {*} options OAS options
|
||||
* @param {*} schemaCache object storing schemaFaker and schmeResolution caches
|
||||
* @param {string} jsonSchemaDialect Defined schema dialect at the OAS object
|
||||
* @param {*} callback Callback
|
||||
* @returns {array} mismatches (in the callback)
|
||||
*/
|
||||
@@ -3322,6 +3324,7 @@ module.exports = {
|
||||
components,
|
||||
options,
|
||||
schemaCache,
|
||||
jsonSchemaDialect,
|
||||
callback) {
|
||||
|
||||
// schema path should have all parameters needed
|
||||
@@ -3390,7 +3393,7 @@ module.exports = {
|
||||
schemaPathVar.pathPrefix + '[?(@.name==\'' + schemaPathVar.name + '\')]',
|
||||
schemaPathVar.schema,
|
||||
PARAMETER_SOURCE.REQUEST,
|
||||
components, options, schemaCache, cb);
|
||||
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||
}, 0);
|
||||
}, (err, res) => {
|
||||
let mismatches = [],
|
||||
@@ -3540,7 +3543,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
checkQueryParams(requestUrl, transactionPathPrefix, schemaPath, components, options,
|
||||
schemaCache, callback) {
|
||||
schemaCache, jsonSchemaDialect, callback) {
|
||||
let parsedUrl = require('url').parse(requestUrl),
|
||||
schemaParams = _.filter(schemaPath.parameters, (param) => { return param.in === 'query'; }),
|
||||
requestQueryArray = [],
|
||||
@@ -3682,7 +3685,7 @@ module.exports = {
|
||||
schemaParam.pathPrefix + '[?(@.name==\'' + schemaParam.name + '\')]',
|
||||
schemaParam.schema,
|
||||
PARAMETER_SOURCE.REQUEST,
|
||||
components, options, schemaCache, cb
|
||||
components, options, schemaCache, jsonSchemaDialect, cb
|
||||
);
|
||||
}, 0);
|
||||
}, (err, res) => {
|
||||
@@ -3846,7 +3849,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
checkRequestHeaders: function (headers, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||
components, options, schemaCache, callback) {
|
||||
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||
let schemaHeaders = _.filter(schemaPath.parameters, (param) => { return param.in === 'header'; }),
|
||||
// key name of headers which are added by security schemes
|
||||
securityHeaders = _.map(this.getSecurityParams(_.get(components, 'components'), 'header'), 'name'),
|
||||
@@ -3904,7 +3907,7 @@ module.exports = {
|
||||
schemaHeader.pathPrefix + '[?(@.name==\'' + schemaHeader.name + '\')]',
|
||||
schemaHeader.schema,
|
||||
PARAMETER_SOURCE.REQUEST,
|
||||
components, options, schemaCache, cb
|
||||
components, options, schemaCache, jsonSchemaDialect, cb
|
||||
);
|
||||
}, 0);
|
||||
}, (err, res) => {
|
||||
@@ -3962,7 +3965,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
checkResponseHeaders: function (schemaResponse, headers, transactionPathPrefix, schemaPathPrefix,
|
||||
components, options, schemaCache, callback) {
|
||||
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||
// 0. Need to find relevant response from schemaPath.responses
|
||||
let schemaHeaders,
|
||||
// filter out headers which need explicit handling according to schema (other than parameters object)
|
||||
@@ -4018,7 +4021,7 @@ module.exports = {
|
||||
schemaPathPrefix + '.headers[' + pHeader.key + ']',
|
||||
schemaHeader.schema,
|
||||
PARAMETER_SOURCE.RESPONSE,
|
||||
components, options, schemaCache, cb
|
||||
components, options, schemaCache, jsonSchemaDialect, cb
|
||||
);
|
||||
}, 0);
|
||||
}, (err, res) => {
|
||||
@@ -4071,7 +4074,7 @@ module.exports = {
|
||||
|
||||
// Only application/json and application/x-www-form-urlencoded is validated for now
|
||||
checkRequestBody: function (requestBody, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||
components, options, schemaCache, callback) {
|
||||
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||
// check for body modes
|
||||
let jsonSchemaBody,
|
||||
jsonContentType,
|
||||
@@ -4102,6 +4105,7 @@ module.exports = {
|
||||
components,
|
||||
_.extend({}, options, { shortValidationErrors: true }),
|
||||
schemaCache,
|
||||
jsonSchemaDialect,
|
||||
callback
|
||||
);
|
||||
}, 0);
|
||||
@@ -4220,7 +4224,7 @@ module.exports = {
|
||||
pathPrefix + '.properties[' + schemaParam.name + ']',
|
||||
schemaParam.schema,
|
||||
PARAMETER_SOURCE.REQUEST,
|
||||
components, options, schemaCache, cb
|
||||
components, options, schemaCache, jsonSchemaDialect, cb
|
||||
);
|
||||
}, 0);
|
||||
}, (err, res) => {
|
||||
@@ -4286,7 +4290,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
checkResponseBody: function (schemaResponse, body, transactionPathPrefix, schemaPathPrefix,
|
||||
components, options, schemaCache, callback) {
|
||||
components, options, schemaCache, jsonSchemaDialect, callback) {
|
||||
let schemaContent,
|
||||
jsonContentType,
|
||||
mismatchProperty = 'RESPONSE_BODY';
|
||||
@@ -4324,13 +4328,14 @@ module.exports = {
|
||||
components,
|
||||
_.extend({}, options, { shortValidationErrors: true }),
|
||||
schemaCache,
|
||||
jsonSchemaDialect,
|
||||
callback
|
||||
);
|
||||
}, 0);
|
||||
},
|
||||
|
||||
checkResponses: function (responses, transactionPathPrefix, schemaPathPrefix, schemaPath,
|
||||
components, options, schemaCache, cb) {
|
||||
components, options, schemaCache, jsonSchemaDialect, cb) {
|
||||
// responses is an array of repsonses recd. for one Postman request
|
||||
// we've already determined the schemaPath against which all responses need to be validated
|
||||
// loop through all responses
|
||||
@@ -4369,13 +4374,15 @@ module.exports = {
|
||||
headers: (cb) => {
|
||||
this.checkResponseHeaders(thisSchemaResponse, response.header,
|
||||
transactionPathPrefix + '[' + response.id + '].header',
|
||||
schemaPathPrefix + '.responses.' + responsePathPrefix, components, options, schemaCache, cb);
|
||||
schemaPathPrefix + '.responses.' + responsePathPrefix,
|
||||
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||
},
|
||||
body: (cb) => {
|
||||
// assume it's JSON at this point
|
||||
this.checkResponseBody(thisSchemaResponse, response.body,
|
||||
transactionPathPrefix + '[' + response.id + '].body',
|
||||
schemaPathPrefix + '.responses.' + responsePathPrefix, components, options, schemaCache, cb);
|
||||
schemaPathPrefix + '.responses.' + responsePathPrefix,
|
||||
components, options, schemaCache, jsonSchemaDialect, cb);
|
||||
}
|
||||
}, (err, result) => {
|
||||
return responseCallback(null, {
|
||||
|
||||
@@ -378,7 +378,8 @@ class SchemaPack {
|
||||
schemaResolutionCache: this.schemaResolutionCache,
|
||||
schemaFakerCache: this.schemaFakerCache
|
||||
},
|
||||
matchedEndpoints = [];
|
||||
matchedEndpoints = [],
|
||||
jsonSchemaDialect = schema.jsonSchemaDialect;
|
||||
|
||||
// Only change the stack limit if the optimizeConversion option is true
|
||||
if (options.optimizeConversion) {
|
||||
@@ -498,23 +499,23 @@ class SchemaPack {
|
||||
},
|
||||
path: function(cb) {
|
||||
schemaUtils.checkPathVariables(matchedPath.pathVariables, '$.request.url.variable', matchedPath.path,
|
||||
componentsAndPaths, options, schemaCache, cb);
|
||||
componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||
},
|
||||
queryparams: function(cb) {
|
||||
schemaUtils.checkQueryParams(requestUrl, '$.request.url.query', matchedPath.path,
|
||||
componentsAndPaths, options, schemaCache, cb);
|
||||
componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||
},
|
||||
headers: function(cb) {
|
||||
schemaUtils.checkRequestHeaders(transaction.request.header, '$.request.header', matchedPath.jsonPath,
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||
},
|
||||
requestBody: function(cb) {
|
||||
schemaUtils.checkRequestBody(transaction.request.body, '$.request.body', matchedPath.jsonPath,
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||
},
|
||||
responses: function (cb) {
|
||||
schemaUtils.checkResponses(transaction.response, '$.responses', matchedPath.jsonPath,
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, cb);
|
||||
matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
|
||||
}
|
||||
}, (err, result) => {
|
||||
let allMismatches = _.concat(result.metadata, result.queryparams, result.headers, result.path,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
const { getLocalDraft, getAjvValidator, validateSchema } = require('../../lib/ajValidation/ajvValidation'),
|
||||
const { getLocalDraft,
|
||||
getAjvValidator,
|
||||
validateSchema,
|
||||
getDraftToUse } = require('../../lib/ajValidation/ajvValidation'),
|
||||
{ validateSchemaAJVDraft04 } = require('../../lib/ajValidation/ajvValidatorDraft04'),
|
||||
expect = require('chai').expect;
|
||||
|
||||
@@ -300,3 +303,26 @@ describe('validateSchema', function () {
|
||||
expect(result.filteredValidationError).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDraftToUse', function() {
|
||||
it('should return the ajv draft 04 when $schema undefined and jsonSchemaDialect is the 04', function() {
|
||||
let draftToUse = getDraftToUse(undefined, 'http://json-schema.org/draft-04/schema#');
|
||||
expect(draftToUse).to.equal('http://json-schema.org/draft-04/schema#');
|
||||
});
|
||||
|
||||
it('should return the ajv draft 06 when $schema is 06 and jsonSchemaDialect is the 04', function() {
|
||||
let draftToUse = getDraftToUse('http://json-schema.org/draft-06/schema#',
|
||||
'http://json-schema.org/draft-04/schema#');
|
||||
expect(draftToUse).to.equal('http://json-schema.org/draft-06/schema#');
|
||||
});
|
||||
|
||||
it('should return the ajv draft 06 when $schema is 06 and jsonSchemaDialect is undefined', function() {
|
||||
let draftToUse = getDraftToUse('http://json-schema.org/draft-06/schema#', undefined);
|
||||
expect(draftToUse).to.equal('http://json-schema.org/draft-06/schema#');
|
||||
});
|
||||
|
||||
it('should return undefined when $schema and jsonSchemaDialect are undefined', function() {
|
||||
let draftToUse = getDraftToUse(undefined, undefined);
|
||||
expect(draftToUse).to.equal(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user