Merge branch 'develop' into feature/cache-fake-schema

This commit is contained in:
shreys7
2020-01-10 20:11:09 +05:30
7 changed files with 110 additions and 79 deletions

View File

@@ -1,5 +1,14 @@
# OpenAPI-Postman Changelog
#### v1.1.5 (Jan 10, 2020)
* Not throwing errors for invalid schema references
* Not throwing errors for invalid schema.path entries
* Not throwing errors for unknown schema types
#### v1.1.4 (Jan 07, 2020)
* More updated copy for mismatch reasons
* Added missing dependency for async.js
#### v1.1.2/v1.1.3 (Jan 03, 2020)
* Updated copy for mismatch reasons
* Returning errors instead of exceptions for invalid schemas

View File

@@ -1,5 +1,4 @@
const openApiErr = require('./error.js'),
_ = require('lodash'),
const _ = require('lodash'),
type = {
integer: {
int32: '<integer>',
@@ -134,12 +133,12 @@ module.exports = {
splitRef = refKey.split('/');
if (splitRef.length < 4) {
throw new openApiErr(`Invalid schema reference: ${refKey}`);
// not throwing an error. We didn't find the reference - generate a dummy value
return { value: 'reference ' + schema.$ref + ' not found in the OpenAPI spec' };
}
if (schemaResolutionCache[refKey]) {
return schemaResolutionCache[refKey];
}
// something like #/components/schemas/PaginationEnvelope/properties/page
// will be resolved - we don't care about anything after the components part
// splitRef.slice(1) will return ['components', 'schemas', 'PaginationEnvelope', 'properties', 'page']
@@ -151,7 +150,7 @@ module.exports = {
schemaResolutionCache[refKey] = refResolvedSchema;
return refResolvedSchema;
}
return { value: 'reference ' + refKey + ' not found in the api spec' };
return { value: 'reference ' + schema.$ref + ' not found in the OpenAPI spec' };
}
if (schema.type === 'object' || schema.hasOwnProperty('properties')) {
// go through all props

View File

@@ -1744,6 +1744,11 @@ module.exports = {
// of those that do, determine a score
// then just pick that key-value pair from schemaPathItems
_.forOwn(schemaPathItems, (pathItemObject, path) => {
if (!pathItemObject) {
// invalid schema. schema.paths had an invalid entry
return true;
}
if (!pathItemObject.hasOwnProperty(method.toLowerCase())) {
// the required method was not found at this path
return true;
@@ -1851,74 +1856,80 @@ module.exports = {
// When processing a reference, schema.type could also be undefined
if (schema && schema.type) {
if (!schemaTypeToJsValidator[schema.type](valueToUse)) {
// if type didn't match, no point checking for AJV
let reason = '';
if (property === 'RESPONSE_BODY' || property === 'BODY') {
// we don't have names for the body, but there's only one
reason = 'The ' + humanPropName;
}
else if (txnParamName) {
// for query params, req/res headers, path vars, we have a name. Praise the lord.
reason = `The ${humanPropName} "${txnParamName}"`;
}
else {
// for query params, req/res headers, path vars, we might not ALWAYS have a name.
reason = `A ${humanPropName}`;
}
reason += ` needs to be of type ${schema.type}, but we found `;
if (!options.shortValidationErrors) {
reason += `"${valueToUse}"`;
}
else if (invalidJson) {
reason += 'invalid JSON';
}
else if (Array.isArray(valueToUse)) {
reason += 'an array instead';
}
else if (typeof valueToUse === 'object') {
reason += 'an object instead';
}
else {
reason += `a ${typeof valueToUse} instead`;
}
if (typeof schemaTypeToJsValidator[schema.type] === 'function') {
if (!schemaTypeToJsValidator[schema.type](valueToUse)) {
// if type didn't match, no point checking for AJV
let reason = '';
if (property === 'RESPONSE_BODY' || property === 'BODY') {
// we don't have names for the body, but there's only one
reason = 'The ' + humanPropName;
}
else if (txnParamName) {
// for query params, req/res headers, path vars, we have a name. Praise the lord.
reason = `The ${humanPropName} "${txnParamName}"`;
}
else {
// for query params, req/res headers, path vars, we might not ALWAYS have a name.
reason = `A ${humanPropName}`;
}
reason += ` needs to be of type ${schema.type}, but we found `;
if (!options.shortValidationErrors) {
reason += `"${valueToUse}"`;
}
else if (invalidJson) {
reason += 'invalid JSON';
}
else if (Array.isArray(valueToUse)) {
reason += 'an array instead';
}
else if (typeof valueToUse === 'object') {
reason += 'an object instead';
}
else {
reason += `a ${typeof valueToUse} instead`;
}
return callback(null, [{
property,
transactionJsonPath: jsonPathPrefix,
schemaJsonPath: schemaPathPrefix,
reasonCode: 'INVALID_TYPE',
reason
}]);
}
// only do AJV if type is array or object
// simpler cases are handled by a type check
if (schema.type === 'array' || schema.type === 'object') {
try {
ajv = new Ajv({ unknownFormats: ['int32', 'int64'], allErrors: true });
validate = ajv.compile(schema);
res = validate(valueToUse);
}
catch (e) {
// something went wrong validating the schema
// input was invalid. Don't throw mismatch
}
if (!res) {
mismatches.push({
property: property,
return callback(null, [{
property,
transactionJsonPath: jsonPathPrefix,
schemaJsonPath: schemaPathPrefix,
reasonCode: 'INVALID_TYPE',
reason: 'The property didn\'t match the specified schema'
});
// only return AJV mismatches
return callback(null, mismatches);
reason
}]);
}
// result passed. No AJV mismatch
// only do AJV if type is array or object
// simpler cases are handled by a type check
if (schema.type === 'array' || schema.type === 'object') {
try {
ajv = new Ajv({ unknownFormats: ['int32', 'int64'], allErrors: true });
validate = ajv.compile(schema);
res = validate(valueToUse);
}
catch (e) {
// something went wrong validating the schema
// input was invalid. Don't throw mismatch
}
if (!res) {
mismatches.push({
property: property,
transactionJsonPath: jsonPathPrefix,
schemaJsonPath: schemaPathPrefix,
reasonCode: 'INVALID_TYPE',
reason: 'The property didn\'t match the specified schema'
});
// only return AJV mismatches
return callback(null, mismatches);
}
// result passed. No AJV mismatch
}
// Schema was not AJV or object
}
else {
// unknown schema.type found
// TODO: Decide how to handle. Log?
}
// Schema was not AJV or object
}
// Schema not defined
return callback(null, []);

15
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "openapi-to-postmanv2",
"version": "1.1.3",
"version": "1.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -115,10 +115,9 @@
"dev": true
},
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
"integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ=="
},
"balanced-match": {
"version": "1.0.0",
@@ -916,6 +915,12 @@
"wordwrap": "^1.0.0"
},
"dependencies": {
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "openapi-to-postmanv2",
"version": "1.1.3",
"version": "1.1.5",
"description": "Convert a given OpenAPI specification to Postman Collection v2.0",
"homepage": "https://github.com/postmanlabs/openapi-to-postman",
"bugs": "https://github.com/postmanlabs/openapi-to-postman/issues",
@@ -117,6 +117,7 @@
},
"dependencies": {
"ajv": "6.10.2",
"async": "3.1.0",
"commander": "2.3.0",
"js-yaml": "3.13.1",
"lodash": "4.17.13",

View File

@@ -4,6 +4,14 @@ var expect = require('chai').expect,
collection;
describe('openapi2postmanv2 ', function() {
const tempOutputFile = 'tempOutput.json';
after(function () {
if (fs.existsSync(tempOutputFile)) {
fs.unlinkSync(tempOutputFile);
}
});
it('should print to console', function(done) {
exec('./bin/openapi2postmanv2.js -s test/data/valid_openapi/petstore.json', function(err, stdout) {
expect(err).to.be.null;
@@ -15,7 +23,7 @@ describe('openapi2postmanv2 ', function() {
it('should print to file', function(done) {
exec('./bin/openapi2postmanv2.js -s test/data/valid_openapi/petstore.json -o tempOutput.json', function(err) {
expect(err).to.be.null;
fs.readFile('tempOutput.json', 'utf8', (err, data) => {
fs.readFile(tempOutputFile, 'utf8', (err, data) => {
collection = JSON.parse(data);
expect(collection.info.name).to.equal('Swagger Petstore');
expect(collection.item.length).to.equal(1);

View File

@@ -2,7 +2,6 @@ var expect = require('chai').expect,
_ = require('lodash'),
SchemaUtils = require('../../lib/schemaUtils.js'),
Utils = require('../../lib/utils.js'),
openApiErr = require('../../lib/error.js'),
deref = require('../../lib/deref.js');
/* Utility function Unit tests */
@@ -131,11 +130,10 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
}
},
parameterSource = 'REQUEST',
resolveTo = 'schema';
resolveTo = 'schema',
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, parameterSource, { components });
expect(function() {
SchemaUtils.safeSchemaFaker(schema, resolveTo, parameterSource, { components });
}).to.throw(openApiErr, 'Invalid schema reference: #/components/schem2');
expect(fakedSchema.value).to.equal('reference #/components/schem2 not found in the OpenAPI spec');
done();
});