mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
Fix conversion process for openapi 3.1, adding schemaUtils31X and schemaUtils30X, adding unit tests
This commit is contained in:
63
lib/30XUtils/schemaUtils30X.js
Normal file
63
lib/30XUtils/schemaUtils30X.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
const inputValidation30X = require('./inputValidation'),
|
||||||
|
schemaUtilsCommon = require('../common/schemaUtilsCommon'),
|
||||||
|
_ = require('lodash');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an OAS string/object as a YAML or JSON
|
||||||
|
* @param {YAML/JSON} openApiSpec - The OAS 3.x specification specified in either YAML or JSON
|
||||||
|
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
||||||
|
* @no-unit-test
|
||||||
|
*/
|
||||||
|
parseSpec: function (openApiSpec) {
|
||||||
|
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation30X);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the required elements for conversion from spec parsed data
|
||||||
|
* @param {object} spec openapi parsed value
|
||||||
|
* @returns {object} required elements to convert
|
||||||
|
*/
|
||||||
|
getRequiredData(spec) {
|
||||||
|
return {
|
||||||
|
info: spec.info,
|
||||||
|
components: spec.components ? spec.components : [],
|
||||||
|
paths: spec.paths
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two types and return if they match or not
|
||||||
|
* @param {string} currentType the type in schema
|
||||||
|
* @param {string} typeToValidate the type to compare
|
||||||
|
* @returns {boolean} the result of the comparation
|
||||||
|
*/
|
||||||
|
compareTypes(currentType, typeToValidate) {
|
||||||
|
return currentType === typeToValidate;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to make this module matches with schemaUtilsXXX interface content
|
||||||
|
* It only returns the provided schema
|
||||||
|
* @param {object} schema a provided schema
|
||||||
|
* @returns {object} it returns the same schema
|
||||||
|
*/
|
||||||
|
fixExamplesByVersion(schema) {
|
||||||
|
return schema;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if request body type is binary type
|
||||||
|
* @param {string} bodyType the bodyType provided in a request body content
|
||||||
|
* @param {object} contentObj The request body content provided in spec
|
||||||
|
* @returns {boolean} Returns true if content is a binary type
|
||||||
|
*/
|
||||||
|
isBinaryContentType (bodyType, contentObj) {
|
||||||
|
return bodyType &&
|
||||||
|
!_.isEmpty(_.get(contentObj, [bodyType, 'schema'])) &&
|
||||||
|
contentObj[bodyType].schema.type === 'string' &&
|
||||||
|
contentObj[bodyType].schema.format === 'binary';
|
||||||
|
}
|
||||||
|
};
|
||||||
78
lib/31XUtils/schemaUtils31X.js
Normal file
78
lib/31XUtils/schemaUtils31X.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
const inputValidation31X = require('./inputValidation31X'),
|
||||||
|
schemaUtilsCommon = require('../common/schemaUtilsCommon'),
|
||||||
|
fileUploadTypes = [
|
||||||
|
'application/octet-stream'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an OAS 3.1.X string/object as a YAML or JSON
|
||||||
|
* @param {YAML/JSON} openApiSpec - The OAS 3.1.x specification specified in either YAML or JSON
|
||||||
|
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
||||||
|
* @no-unit-test
|
||||||
|
*/
|
||||||
|
parseSpec: function (openApiSpec) {
|
||||||
|
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation31X);
|
||||||
|
},
|
||||||
|
inputValidation31X,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the required elements for conversion from spec parsed data
|
||||||
|
* @param {object} spec openapi parsed value
|
||||||
|
* @returns {object} required elements to convert
|
||||||
|
*/
|
||||||
|
getRequiredData(spec) {
|
||||||
|
return {
|
||||||
|
info: spec.info,
|
||||||
|
paths: spec.paths ? spec.paths : [],
|
||||||
|
components: spec.components ? spec.components : [],
|
||||||
|
webhooks: spec.webhooks ? spec.webhooks : []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two types and return if they match or not.
|
||||||
|
* In case that the provided type is an array it checks of the typeToCompare exists in.
|
||||||
|
* @param {string | array} currentType the type in schema, it could be an array of types
|
||||||
|
* @param {string} typeToValidate the type to compare
|
||||||
|
* @returns {boolean} the result of the comparation
|
||||||
|
*/
|
||||||
|
compareTypes(currentType, typeToValidate) {
|
||||||
|
let isTypeMatching = currentType === typeToValidate;
|
||||||
|
if (Array.isArray(currentType)) {
|
||||||
|
isTypeMatching = currentType.includes(typeToValidate);
|
||||||
|
}
|
||||||
|
return isTypeMatching;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes the first element from 'examples' property in a schema and adds a new 'example' property.
|
||||||
|
* This method is used before faking the schema. (Schema faker uses the example property to fakle the schema)
|
||||||
|
* @param {object} schema a provided schema
|
||||||
|
* @returns {object} it returns the schema with a new example property
|
||||||
|
*/
|
||||||
|
fixExamplesByVersion(schema) {
|
||||||
|
if (schema.properties) {
|
||||||
|
const schemaProperties = Object.keys(schema.properties);
|
||||||
|
schemaProperties.forEach((property) => {
|
||||||
|
if (schema.properties[property].examples) {
|
||||||
|
schema.properties[property].example = schema.properties[property].examples[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return schema;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if request body type is binary type.
|
||||||
|
* Open api 3.1 does not need that a binary content has a schema within. It comes as an empty object
|
||||||
|
* @param {string} bodyType the bodyType provided in a request body content
|
||||||
|
* @param {object} contentObj The request body content provided in spec
|
||||||
|
* @returns {boolean} Returns true if content is a binary type
|
||||||
|
*/
|
||||||
|
isBinaryContentType (bodyType, contentObj) {
|
||||||
|
return Object.keys(contentObj[bodyType]).length === 0 && fileUploadTypes.includes(bodyType);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
const inputValidation31X = require('./inputValidation31X'),
|
|
||||||
schemaUtilsCommon = require('../common/schemaUtilsCommon');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses an OAS 3.1.X string/object as a YAML or JSON
|
|
||||||
* @param {YAML/JSON} openApiSpec - The OAS 3.1.x specification specified in either YAML or JSON
|
|
||||||
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
|
||||||
* @no-unit-test
|
|
||||||
*/
|
|
||||||
parseSpec: function (openApiSpec) {
|
|
||||||
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation31X);
|
|
||||||
},
|
|
||||||
inputValidation31X
|
|
||||||
};
|
|
||||||
@@ -40,6 +40,24 @@ function getSpecVersion({ type, data }) {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} specVersion - the OAS specification version
|
||||||
|
* @returns {NodeRequire} the schema utils according to version
|
||||||
|
*/
|
||||||
|
function getConcreteSchemaUtils({ type, data }) {
|
||||||
|
const specVersion = getSpecVersion({ type, data });
|
||||||
|
let concreteUtils = {};
|
||||||
|
if (specVersion === DEFAULT_SPEC_VERSION) {
|
||||||
|
concreteUtils = require('../30XUtils/schemaUtils30X');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
concreteUtils = require('../31XUtils/schemaUtils31X');
|
||||||
|
}
|
||||||
|
return concreteUtils;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getSpecVersion
|
getSpecVersion,
|
||||||
|
getConcreteSchemaUtils
|
||||||
};
|
};
|
||||||
|
|||||||
14
lib/deref.js
14
lib/deref.js
@@ -32,7 +32,8 @@ const _ = require('lodash'),
|
|||||||
'regex',
|
'regex',
|
||||||
'uuid',
|
'uuid',
|
||||||
'json-pointer'
|
'json-pointer'
|
||||||
];
|
],
|
||||||
|
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
@@ -130,7 +131,12 @@ module.exports = {
|
|||||||
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}, stackLimit = 10) {
|
resolveFor = 'CONVERSION', resolveTo = 'schema', stack = 0, seenRef = {}, stackLimit = 10) {
|
||||||
var resolvedSchema, prop, splitRef,
|
var resolvedSchema, prop, splitRef,
|
||||||
ERR_TOO_MANY_LEVELS = '<Error: Too many levels of nesting to fake this schema>';
|
ERR_TOO_MANY_LEVELS = '<Error: Too many levels of nesting to fake this schema>';
|
||||||
|
let concreteUtils = DEFAULT_SCHEMA_UTILS;
|
||||||
|
if (components) {
|
||||||
|
concreteUtils = components.hasOwnProperty('concreteUtils') ?
|
||||||
|
components.concreteUtils :
|
||||||
|
DEFAULT_SCHEMA_UTILS;
|
||||||
|
}
|
||||||
stack++;
|
stack++;
|
||||||
schemaResolutionCache = schemaResolutionCache || {};
|
schemaResolutionCache = schemaResolutionCache || {};
|
||||||
|
|
||||||
@@ -244,7 +250,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
return { value: 'reference ' + schema.$ref + ' not found in the OpenAPI spec' };
|
return { value: 'reference ' + schema.$ref + ' not found in the OpenAPI spec' };
|
||||||
}
|
}
|
||||||
if (schema.type === 'object' || schema.hasOwnProperty('properties')) {
|
if (concreteUtils.compareTypes(schema.type, 'objects') || schema.hasOwnProperty('properties')) {
|
||||||
// go through all props
|
// go through all props
|
||||||
schema.type = 'object';
|
schema.type = 'object';
|
||||||
if (schema.hasOwnProperty('properties')) {
|
if (schema.hasOwnProperty('properties')) {
|
||||||
@@ -281,7 +287,7 @@ module.exports = {
|
|||||||
schema.default = '<object>';
|
schema.default = '<object>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (schema.type === 'array' && schema.items) {
|
else if (concreteUtils.compareTypes(schema.type, 'array') && schema.items) {
|
||||||
/*
|
/*
|
||||||
For VALIDATION - keep minItems and maxItems properties defined by user in schema as is
|
For VALIDATION - keep minItems and maxItems properties defined by user in schema as is
|
||||||
FOR CONVERSION -
|
FOR CONVERSION -
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ const async = require('async'),
|
|||||||
defaultOptions = require('../lib/options.js').getOptions('use'),
|
defaultOptions = require('../lib/options.js').getOptions('use'),
|
||||||
{ Node, Trie } = require('./trie.js'),
|
{ Node, Trie } = require('./trie.js'),
|
||||||
{ validateSchema } = require('./ajvValidation'),
|
{ validateSchema } = require('./ajvValidation'),
|
||||||
inputValidation = require('./inputValidation'),
|
inputValidation = require('./30XUtils/inputValidation'),
|
||||||
schemaUtilsCommon = require('./common/schemaUtilsCommon'),
|
|
||||||
SCHEMA_FORMATS = {
|
SCHEMA_FORMATS = {
|
||||||
DEFAULT: 'default', // used for non-request-body data and json
|
DEFAULT: 'default', // used for non-request-body data and json
|
||||||
XML: 'xml' // used for request-body XMLs
|
XML: 'xml' // used for request-body XMLs
|
||||||
@@ -93,7 +92,8 @@ const async = require('async'),
|
|||||||
'array': (d) => Array.isArray(d),
|
'array': (d) => Array.isArray(d),
|
||||||
'object': (d) => typeof d === 'object' && !Array.isArray(d)
|
'object': (d) => typeof d === 'object' && !Array.isArray(d)
|
||||||
},
|
},
|
||||||
crypto = require('crypto');
|
crypto = require('crypto'),
|
||||||
|
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X');
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
// See https://github.com/json-schema-faker/json-schema-faker/tree/master/docs#available-options
|
// See https://github.com/json-schema-faker/json-schema-faker/tree/master/docs#available-options
|
||||||
@@ -137,9 +137,16 @@ function safeSchemaFaker(oldSchema, resolveTo, resolveFor, parameterSourceOption
|
|||||||
var prop, key, resolvedSchema, fakedSchema,
|
var prop, key, resolvedSchema, fakedSchema,
|
||||||
schemaResolutionCache = _.get(schemaCache, 'schemaResolutionCache', {}),
|
schemaResolutionCache = _.get(schemaCache, 'schemaResolutionCache', {}),
|
||||||
schemaFakerCache = _.get(schemaCache, 'schemaFakerCache', {});
|
schemaFakerCache = _.get(schemaCache, 'schemaFakerCache', {});
|
||||||
|
let concreteUtils = DEFAULT_SCHEMA_UTILS;
|
||||||
|
if (components) {
|
||||||
|
concreteUtils = components.hasOwnProperty('concreteUtils') ?
|
||||||
|
components.concreteUtils :
|
||||||
|
DEFAULT_SCHEMA_UTILS;
|
||||||
|
}
|
||||||
|
|
||||||
resolvedSchema = deref.resolveRefs(oldSchema, parameterSourceOption, components, schemaResolutionCache,
|
resolvedSchema = deref.resolveRefs(oldSchema, parameterSourceOption, components, schemaResolutionCache,
|
||||||
resolveFor, resolveTo, 0, {}, stackLimit);
|
resolveFor, resolveTo, 0, {}, stackLimit);
|
||||||
|
resolvedSchema = concreteUtils.fixExamplesByVersion(resolvedSchema);
|
||||||
key = JSON.stringify(resolvedSchema);
|
key = JSON.stringify(resolvedSchema);
|
||||||
|
|
||||||
if (resolveTo === 'schema') {
|
if (resolveTo === 'schema') {
|
||||||
@@ -441,16 +448,6 @@ module.exports = {
|
|||||||
return variables;
|
return variables;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses an OAS string/object as a YAML or JSON
|
|
||||||
* @param {YAML/JSON} openApiSpec - The OAS 3.x specification specified in either YAML or JSON
|
|
||||||
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
|
||||||
* @no-unit-test
|
|
||||||
*/
|
|
||||||
parseSpec: function (openApiSpec) {
|
|
||||||
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns params applied to specific operation with resolved references. Params from parent
|
* Returns params applied to specific operation with resolved references. Params from parent
|
||||||
* blocks (collection/folder) are merged, so that the request has a flattened list of params needed.
|
* blocks (collection/folder) are merged, so that the request has a flattened list of params needed.
|
||||||
@@ -1686,6 +1683,14 @@ module.exports = {
|
|||||||
enumValue,
|
enumValue,
|
||||||
formHeaders = [];
|
formHeaders = [];
|
||||||
|
|
||||||
|
let concreteUtils = DEFAULT_SCHEMA_UTILS;
|
||||||
|
|
||||||
|
if (components) {
|
||||||
|
concreteUtils = components.hasOwnProperty('concreteUtils') ?
|
||||||
|
components.concreteUtils :
|
||||||
|
DEFAULT_SCHEMA_UTILS;
|
||||||
|
}
|
||||||
|
|
||||||
// @TODO: how do we support multiple content types
|
// @TODO: how do we support multiple content types
|
||||||
contentObj = requestBody.content;
|
contentObj = requestBody.content;
|
||||||
|
|
||||||
@@ -1862,10 +1867,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
bodyType &&
|
concreteUtils.isBinaryContentType(bodyType, contentObj)
|
||||||
!_.isEmpty(_.get(contentObj, [bodyType, 'schema'])) &&
|
|
||||||
contentObj[bodyType].schema.type === 'string' &&
|
|
||||||
contentObj[bodyType].schema.format === 'binary'
|
|
||||||
) {
|
) {
|
||||||
updateOptions = {
|
updateOptions = {
|
||||||
mode: 'file'
|
mode: 'file'
|
||||||
@@ -2152,7 +2154,8 @@ module.exports = {
|
|||||||
* @returns {Object} postman request Item
|
* @returns {Object} postman request Item
|
||||||
* @no-unit-test
|
* @no-unit-test
|
||||||
*/
|
*/
|
||||||
convertRequestToItem: function(openapi, operationItem, components, options, schemaCache, variableStore) {
|
convertRequestToItem: function(openapi, operationItem, components,
|
||||||
|
options, schemaCache, variableStore) {
|
||||||
options = _.merge({}, defaultOptions, options);
|
options = _.merge({}, defaultOptions, options);
|
||||||
var reqName,
|
var reqName,
|
||||||
pathVariables = openapi.baseUrlVariables,
|
pathVariables = openapi.baseUrlVariables,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
// This is the default collection name if one can't be inferred from the OpenAPI spec
|
// This is the default collection name if one can't be inferred from the OpenAPI spec
|
||||||
const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
|
const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
|
||||||
|
{ getConcreteSchemaUtils } = require('./common/versionUtils.js'),
|
||||||
BROWSER = 'browser',
|
BROWSER = 'browser',
|
||||||
Ajv = require('ajv'),
|
Ajv = require('ajv'),
|
||||||
async = require('async'),
|
async = require('async'),
|
||||||
@@ -22,30 +23,27 @@ const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
|
|||||||
// This provides the base class for
|
// This provides the base class for
|
||||||
// errors with the input OpenAPI spec
|
// errors with the input OpenAPI spec
|
||||||
OpenApiErr = require('./error.js'),
|
OpenApiErr = require('./error.js'),
|
||||||
DEFAULT_SPEC_VERSION = '3.0',
|
schemaUtils = require('./schemaUtils');
|
||||||
{
|
|
||||||
getSpecVersion
|
|
||||||
} = require('./common/versionUtils.js');
|
|
||||||
|
|
||||||
let path = require('path'),
|
let path = require('path'),
|
||||||
schemaUtils,
|
concreteUtils,
|
||||||
pathBrowserify = require('path-browserify');
|
pathBrowserify = require('path-browserify');
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
*
|
// *
|
||||||
* @param {string} specVersion - the OAS specification version
|
// * @param {string} specVersion - the OAS specification version
|
||||||
* @returns {NodeRequire} the schema utils according to version
|
// * @returns {NodeRequire} the schema utils according to version
|
||||||
*/
|
// */
|
||||||
function getConcreteSchemaUtils(specVersion) {
|
// function getConcreteSchemaUtils(specVersion) {
|
||||||
let schemaUtils = {};
|
// let concreteUtils = {};
|
||||||
if (specVersion === DEFAULT_SPEC_VERSION) {
|
// if (specVersion === DEFAULT_SPEC_VERSION) {
|
||||||
schemaUtils = require('./schemaUtils');
|
// concreteUtils = require('./30XUtils/schemaUtils30X');
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
schemaUtils = require('./schemaUtils31X');
|
// concreteUtils = require('./31XUtils/schemaUtils31X');
|
||||||
}
|
// }
|
||||||
return schemaUtils;
|
// return concreteUtils;
|
||||||
}
|
// }
|
||||||
|
|
||||||
class SchemaPack {
|
class SchemaPack {
|
||||||
constructor (input, options = {}) {
|
constructor (input, options = {}) {
|
||||||
@@ -66,10 +64,9 @@ class SchemaPack {
|
|||||||
);
|
);
|
||||||
// hardcoding this option - not exposed to users yet
|
// hardcoding this option - not exposed to users yet
|
||||||
this.computedOptions.schemaFaker = true;
|
this.computedOptions.schemaFaker = true;
|
||||||
let indentCharacter = this.computedOptions.indentCharacter,
|
let indentCharacter = this.computedOptions.indentCharacter;
|
||||||
specVersion = getSpecVersion(input);
|
|
||||||
this.computedOptions.indentCharacter = indentCharacter === 'tab' ? '\t' : ' ';
|
this.computedOptions.indentCharacter = indentCharacter === 'tab' ? '\t' : ' ';
|
||||||
schemaUtils = getConcreteSchemaUtils(specVersion);
|
concreteUtils = getConcreteSchemaUtils(input);
|
||||||
this.validate();
|
this.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +122,7 @@ class SchemaPack {
|
|||||||
return this.validationResult;
|
return this.validationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
specParseResult = schemaUtils.parseSpec(json);
|
specParseResult = concreteUtils.parseSpec(json);
|
||||||
|
|
||||||
if (!specParseResult.result) {
|
if (!specParseResult.result) {
|
||||||
// validation failed
|
// validation failed
|
||||||
@@ -258,7 +255,7 @@ class SchemaPack {
|
|||||||
analysis,
|
analysis,
|
||||||
generatedStore = {},
|
generatedStore = {},
|
||||||
collectionJSON,
|
collectionJSON,
|
||||||
componentsAndPaths,
|
specComponentsAndUtils,
|
||||||
authHelper,
|
authHelper,
|
||||||
schemaCache = {
|
schemaCache = {
|
||||||
schemaResolutionCache: this.schemaResolutionCache,
|
schemaResolutionCache: this.schemaResolutionCache,
|
||||||
@@ -270,10 +267,12 @@ class SchemaPack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this cannot be attempted before validation
|
// this cannot be attempted before validation
|
||||||
componentsAndPaths = {
|
specComponentsAndUtils = { concreteUtils };
|
||||||
components: this.openapi.components,
|
Object.assign(specComponentsAndUtils, concreteUtils.getRequiredData(this.openapi));
|
||||||
paths: this.openapi.paths
|
// {
|
||||||
};
|
// components: this.openapi.components,
|
||||||
|
// paths: this.openapi.paths
|
||||||
|
// };
|
||||||
|
|
||||||
// create and sanitize basic spec
|
// create and sanitize basic spec
|
||||||
openapi = this.openapi;
|
openapi = this.openapi;
|
||||||
@@ -330,10 +329,24 @@ class SchemaPack {
|
|||||||
// For paths, All operations are grouped based on corresponding paths
|
// For paths, All operations are grouped based on corresponding paths
|
||||||
try {
|
try {
|
||||||
if (options.folderStrategy === 'tags') {
|
if (options.folderStrategy === 'tags') {
|
||||||
schemaUtils.addCollectionItemsUsingTags(openapi, generatedStore, componentsAndPaths, options, schemaCache);
|
schemaUtils.addCollectionItemsUsingTags(
|
||||||
|
openapi,
|
||||||
|
generatedStore,
|
||||||
|
specComponentsAndUtils,
|
||||||
|
options,
|
||||||
|
schemaCache,
|
||||||
|
concreteUtils
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
schemaUtils.addCollectionItemsUsingPaths(openapi, generatedStore, componentsAndPaths, options, schemaCache);
|
schemaUtils.addCollectionItemsUsingPaths(
|
||||||
|
openapi,
|
||||||
|
generatedStore,
|
||||||
|
specComponentsAndUtils,
|
||||||
|
options,
|
||||||
|
schemaCache,
|
||||||
|
concreteUtils
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
|||||||
31
test/data/valid_openapi31X/non-oauth.json
Normal file
31
test/data/valid_openapi31X/non-oauth.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"info": {
|
||||||
|
"title": "Non-oAuth Scopes example",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/users": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": [
|
||||||
|
"read:users",
|
||||||
|
"public"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"securitySchemes": {
|
||||||
|
"bearerAuth": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "bearer",
|
||||||
|
"bearerFormat": "jwt",
|
||||||
|
"description": "note: non-oauth scopes are not defined at the securityScheme level"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
247
test/data/valid_openapi31X/petstore.json
Normal file
247
test/data/valid_openapi31X/petstore.json
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"info": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "Swagger Petstore",
|
||||||
|
"license": {
|
||||||
|
"name": "MIT"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "http://petstore.swagger.io/v1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/pets": {
|
||||||
|
"get": {
|
||||||
|
"summary": "List all pets",
|
||||||
|
"operationId": "listPets",
|
||||||
|
"tags": [
|
||||||
|
"pets"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "limit",
|
||||||
|
"in": "header",
|
||||||
|
"description": "How many items to return at one time (max 100)",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "variable",
|
||||||
|
"in": "query",
|
||||||
|
"description": "random variable",
|
||||||
|
"style": "form",
|
||||||
|
"explode": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "variable2",
|
||||||
|
"in": "query",
|
||||||
|
"description": "another random variable",
|
||||||
|
"style": "spaceDelimited",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "An paged array of pets",
|
||||||
|
"headers": {
|
||||||
|
"x-next": {
|
||||||
|
"description": "A link to the next page of responses",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pets"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "unexpected error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"summary": "Create a pet",
|
||||||
|
"operationId": "createPets",
|
||||||
|
"tags": [
|
||||||
|
"pets"
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Null response"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "unexpected error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "limit_2",
|
||||||
|
"in": "headers",
|
||||||
|
"description": "How many items to return at one time (max 100)",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/pets/{petId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Info for a specific pet",
|
||||||
|
"operationId": "showPetById",
|
||||||
|
"tags": [
|
||||||
|
"pets"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"description": "The id of the pet to retrieve",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Expected response to a valid request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "unexpected error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pet/{petId}/uploadImage": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"pet",
|
||||||
|
"cat"
|
||||||
|
],
|
||||||
|
"summary": "uploads an image",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "uploadFile",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of pet to update",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/octet-stream": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Pet": {
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"examples": [
|
||||||
|
111111000111111
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"examples": [
|
||||||
|
"this is my fisrt example name in pet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tag": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Pets": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Pet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Error": {
|
||||||
|
"required": [
|
||||||
|
"code",
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"code": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
test/unit/30Xsupport/schemaUtils30X.test.js
Normal file
121
test/unit/30Xsupport/schemaUtils30X.test.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
const { expect } = require('chai'),
|
||||||
|
{
|
||||||
|
parseSpec, getRequiredData, compareTypes, fixExamplesByVersion, isBinaryContentType
|
||||||
|
} = require('../../../lib/30XUtils/schemaUtils30X'),
|
||||||
|
fs = require('fs'),
|
||||||
|
valid30xFolder = './test/data/valid_openapi',
|
||||||
|
invalid30xFolder = './test/data/invalid_openapi';
|
||||||
|
|
||||||
|
describe('parseSpec method', function () {
|
||||||
|
it('should return true and a parsed specification', function () {
|
||||||
|
let fileContent = fs.readFileSync(valid30xFolder + '/petstore.json', 'utf8');
|
||||||
|
const parsedSpec = parseSpec(fileContent);
|
||||||
|
expect(parsedSpec.result).to.be.true;
|
||||||
|
expect(parsedSpec.openapi.openapi).to.equal('3.0.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false and invalid format message when input content is sent', function () {
|
||||||
|
let fileContent = fs.readFileSync(invalid30xFolder + '/empty-spec.yaml', 'utf8');
|
||||||
|
const parsedSpec = parseSpec(fileContent);
|
||||||
|
expect(parsedSpec.result).to.be.false;
|
||||||
|
expect(parsedSpec.reason).to.equal('Invalid format. Input must be in YAML or JSON format.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false and Spec must contain info object', function () {
|
||||||
|
let fileContent = fs.readFileSync(invalid30xFolder + '/invalid-no-info.yaml', 'utf8');
|
||||||
|
const parsedSpec = parseSpec(fileContent);
|
||||||
|
expect(parsedSpec.result).to.be.false;
|
||||||
|
expect(parsedSpec.reason).to.equal('Specification must contain an Info Object for the meta-data of the API');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRequiredData method', function() {
|
||||||
|
it('Should return all required data from file', function() {
|
||||||
|
const fileContent = fs.readFileSync(valid30xFolder + '/petstore.json', 'utf8'),
|
||||||
|
requiredData = getRequiredData(JSON.parse(fileContent));
|
||||||
|
expect(requiredData).to.be.an('object')
|
||||||
|
.and.to.have.all.keys('info', 'paths', 'components');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('compareTypes method', function() {
|
||||||
|
it('Should match type in spec with type to compare when type in spec is a string when they are equal', function() {
|
||||||
|
const typeInSpec = 'string',
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not match typeInSpec with typeToCompare when ' +
|
||||||
|
'typeInSpec is an array that includes the typeInSpec value', function() {
|
||||||
|
const typeInSpec = ['string'],
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not match type in spec with type to compare when ' +
|
||||||
|
'type in spec is a string when they are different', function() {
|
||||||
|
const typeInSpec = 'integer',
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fixExamplesByVersion method', function() {
|
||||||
|
it('Should return the same schema than the provided', function() {
|
||||||
|
const providedSchema = {
|
||||||
|
required: [
|
||||||
|
'id',
|
||||||
|
'name'
|
||||||
|
],
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
example: 'this is my fisrt example name in pet'
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fixedSchemaWithExample = fixExamplesByVersion(providedSchema);
|
||||||
|
expect(JSON.stringify(fixedSchemaWithExample)).to.be.equal(JSON.stringify(providedSchema));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isBinaryContentType method', function() {
|
||||||
|
it('Should be true if content type is binary type without schema', function() {
|
||||||
|
const bodyType = 'application/octet-stream',
|
||||||
|
contentObject = {
|
||||||
|
'application/octet-stream': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'string',
|
||||||
|
'format': 'binary'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isBinary = isBinaryContentType(bodyType, contentObject);
|
||||||
|
expect(isBinary).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be false if content type is not binary type', function() {
|
||||||
|
const bodyType = 'application/json',
|
||||||
|
contentObject = {
|
||||||
|
'application/json': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'string',
|
||||||
|
'example': 'OK'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isBinary = isBinaryContentType(bodyType, contentObject);
|
||||||
|
expect(isBinary).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const { expect } = require('chai'),
|
const { expect } = require('chai'),
|
||||||
{
|
{
|
||||||
validateSpec
|
validateSpec
|
||||||
} = require('../../../lib/31Xsupport/inputValidation31X'),
|
} = require('../../../lib/31XUtils/inputValidation31X'),
|
||||||
correctMockedEntryWH = {
|
correctMockedEntryWH = {
|
||||||
openapi: '3.1.0',
|
openapi: '3.1.0',
|
||||||
info: {
|
info: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const { expect } = require('chai'),
|
const { expect } = require('chai'),
|
||||||
{
|
{
|
||||||
parseSpec
|
parseSpec, getRequiredData, compareTypes, fixExamplesByVersion, isBinaryContentType
|
||||||
} = require('../../../lib/31Xsupport/schemaUtils31X'),
|
} = require('../../../lib/31XUtils/schemaUtils31X'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
valid31xFolder = './test/data/valid_openapi31X',
|
valid31xFolder = './test/data/valid_openapi31X',
|
||||||
invalid31xFolder = './test/data/invalid_openapi31X';
|
invalid31xFolder = './test/data/invalid_openapi31X';
|
||||||
@@ -30,3 +30,130 @@ describe('parseSpec method', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getRequiredData method', function() {
|
||||||
|
it('Should return all required data from file', function() {
|
||||||
|
const fileContent = fs.readFileSync(valid31xFolder + '/petstore.json', 'utf8'),
|
||||||
|
requiredData = getRequiredData(JSON.parse(fileContent));
|
||||||
|
expect(requiredData).to.be.an('object')
|
||||||
|
.and.to.have.all.keys('info', 'paths', 'webhooks', 'components');
|
||||||
|
expect(requiredData.webhooks).to.be.an('array').with.length(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('compareTypes method', function() {
|
||||||
|
it('Should match type in spec with type to compare when type in spec is a string when they are equal', function() {
|
||||||
|
const typeInSpec = 'string',
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should match type in spec with type to compare when type in spec is an array when they are equal', function() {
|
||||||
|
const typeInSpec = ['string'],
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should match type in spec with type to compare when ' +
|
||||||
|
'type in spec is an array with multiple types when they are equal', function() {
|
||||||
|
const typeInSpec = ['string', 'null'],
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should match type in spec with type to compare when ' +
|
||||||
|
'type in spec is a string when they are different', function() {
|
||||||
|
const typeInSpec = 'integer',
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not match type in spec with type to compare when' +
|
||||||
|
'type in spec is an array when they are different', function() {
|
||||||
|
const typeInSpec = ['integer'],
|
||||||
|
typeToCompare = 'string',
|
||||||
|
matchTypes = compareTypes(typeInSpec, typeToCompare);
|
||||||
|
expect(matchTypes).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fixExamplesByVersion method', function() {
|
||||||
|
it('Should take the first element from examples and add it as example', function() {
|
||||||
|
const providedSchema = {
|
||||||
|
required: [
|
||||||
|
'id',
|
||||||
|
'name'
|
||||||
|
],
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
examples: [
|
||||||
|
'this is my fisrt example name in pet'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expectedSchemaAfterFix = {
|
||||||
|
required: [
|
||||||
|
'id',
|
||||||
|
'name'
|
||||||
|
],
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
examples: [
|
||||||
|
'this is my fisrt example name in pet'
|
||||||
|
],
|
||||||
|
example: 'this is my fisrt example name in pet'
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fixedSchemaWithExample = fixExamplesByVersion(providedSchema);
|
||||||
|
expect(JSON.stringify(fixedSchemaWithExample)).to.be.equal(JSON.stringify(expectedSchemaAfterFix));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isBinaryContentType method', function() {
|
||||||
|
it('Should be true if content type is binary type without schema', function() {
|
||||||
|
const bodyType = 'application/octet-stream',
|
||||||
|
contentObject = {
|
||||||
|
'application/octet-stream': {}
|
||||||
|
},
|
||||||
|
isBinary = isBinaryContentType(bodyType, contentObject);
|
||||||
|
expect(isBinary).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be false if content type is not binary type', function() {
|
||||||
|
const bodyType = 'application/json',
|
||||||
|
contentObject = {
|
||||||
|
'application/json': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'string',
|
||||||
|
'examples': [
|
||||||
|
'OK'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isBinary = isBinaryContentType(bodyType, contentObject);
|
||||||
|
expect(isBinary).to.be.false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
51
test/unit/31Xsupport/schemapack.test.js
Normal file
51
test/unit/31Xsupport/schemapack.test.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
const { SchemaPack } = require('../../..');
|
||||||
|
|
||||||
|
const expect = require('chai').expect,
|
||||||
|
fs = require('fs'),
|
||||||
|
path = require('path'),
|
||||||
|
OPENAPI_31_FOLDER = '../../data/valid_openapi31X',
|
||||||
|
OPENAPI_30_FOLDER = '../../data/valid_openapi';
|
||||||
|
|
||||||
|
describe('Testing openapi 3.1 schema pack convert', function() {
|
||||||
|
// it('Should convert from openapi 3.1 spec to postman collection', function() {
|
||||||
|
// const fileSource = path.join(__dirname, OPENAPI_30_FOLDER + '/petstore-detailed.yaml'),
|
||||||
|
// fileData = fs.readFileSync(fileSource, 'utf8'),
|
||||||
|
// input = {
|
||||||
|
// type: 'string',
|
||||||
|
// data: fileData
|
||||||
|
// },
|
||||||
|
// converter = new SchemaPack(input);
|
||||||
|
|
||||||
|
// converter.convert((err, result) => {
|
||||||
|
// expect(err).to.be.null;
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
it('Should convert from openapi 3.1 spec to postman collection -- petstore modifyed', function() {
|
||||||
|
const fileSource = path.join(__dirname, OPENAPI_31_FOLDER + '/petstore.json'),
|
||||||
|
fileData = fs.readFileSync(fileSource, 'utf8'),
|
||||||
|
input = {
|
||||||
|
type: 'string',
|
||||||
|
data: fileData
|
||||||
|
},
|
||||||
|
converter = new SchemaPack(input);
|
||||||
|
|
||||||
|
converter.convert((err, result) => {
|
||||||
|
expect(err).to.be.null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// it('Should convert from openapi 3.0 spec to postman collection', function() {
|
||||||
|
// const fileSource = path.join(__dirname, OPENAPI_30_FOLDER + '/petstore.json'),
|
||||||
|
// fileData = fs.readFileSync(fileSource, 'utf8'),
|
||||||
|
// input = {
|
||||||
|
// type: 'json',
|
||||||
|
// data: fileData
|
||||||
|
// },
|
||||||
|
// converter = new SchemaPack(input);
|
||||||
|
|
||||||
|
// converter.convert((err, result) => {
|
||||||
|
// expect(err).to.be.null;
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
});
|
||||||
@@ -13,6 +13,7 @@ describe('CONVERT FUNCTION TESTS ', function() {
|
|||||||
|
|
||||||
var testSpec = path.join(__dirname, VALID_OPENAPI_PATH + '/test.json'),
|
var testSpec = path.join(__dirname, VALID_OPENAPI_PATH + '/test.json'),
|
||||||
testSpec1 = path.join(__dirname, VALID_OPENAPI_PATH + '/test1.json'),
|
testSpec1 = path.join(__dirname, VALID_OPENAPI_PATH + '/test1.json'),
|
||||||
|
test31SpecDir = path.join(__dirname, '../data/valid_openapi31X/'),
|
||||||
issue133 = path.join(__dirname, VALID_OPENAPI_PATH + '/issue#133.json'),
|
issue133 = path.join(__dirname, VALID_OPENAPI_PATH + '/issue#133.json'),
|
||||||
issue160 = path.join(__dirname, VALID_OPENAPI_PATH, '/issue#160.json'),
|
issue160 = path.join(__dirname, VALID_OPENAPI_PATH, '/issue#160.json'),
|
||||||
unique_items_schema = path.join(__dirname, VALID_OPENAPI_PATH + '/unique_items_schema.json'),
|
unique_items_schema = path.join(__dirname, VALID_OPENAPI_PATH + '/unique_items_schema.json'),
|
||||||
@@ -640,6 +641,27 @@ describe('CONVERT FUNCTION TESTS ', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should return meta data from a valid 3.1 file', function(done) {
|
||||||
|
var openapi = fs.readFileSync(test31SpecDir + 'non-oauth.json', 'utf8');
|
||||||
|
Converter.getMetaData({ type: 'json', data: openapi }, (err, status) => {
|
||||||
|
if (err) {
|
||||||
|
expect.fail(null, null, err);
|
||||||
|
}
|
||||||
|
if (status.result) {
|
||||||
|
expect(status.result).to.be.eq(true);
|
||||||
|
expect(status.name).to.be.equal('Non-oAuth Scopes example');
|
||||||
|
expect(status.output[0].name).to.be.equal('Non-oAuth Scopes example');
|
||||||
|
expect(status.output[0].type).to.be.equal('collection');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expect.fail(null, null, status.reason);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Should return validation result for an invalid file', function(done) {
|
it('Should return validation result for an invalid file', function(done) {
|
||||||
var invalidNoInfo = path.join(__dirname, INVALID_OPENAPI_PATH + '/invalid-no-info.yaml'),
|
var invalidNoInfo = path.join(__dirname, INVALID_OPENAPI_PATH + '/invalid-no-info.yaml'),
|
||||||
openapi = fs.readFileSync(invalidNoInfo, 'utf8');
|
openapi = fs.readFileSync(invalidNoInfo, 'utf8');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var expect = require('chai').expect,
|
var expect = require('chai').expect,
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
deref = require('../../lib/deref.js');
|
deref = require('../../lib/deref.js'),
|
||||||
|
schemaUtils30X = require('./../../lib/30XUtils/schemaUtils30X');
|
||||||
|
|
||||||
describe('DEREF FUNCTION TESTS ', function() {
|
describe('DEREF FUNCTION TESTS ', function() {
|
||||||
describe('resolveRefs Function', function () {
|
describe('resolveRefs Function', function () {
|
||||||
@@ -90,7 +91,8 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
type: 'object'
|
type: 'object'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
concreteUtils: schemaUtils30X
|
||||||
},
|
},
|
||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
// deref.resolveRefs modifies the input schema and components so cloning to keep tests independent of each other
|
// deref.resolveRefs modifies the input schema and components so cloning to keep tests independent of each other
|
||||||
@@ -170,7 +172,8 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
concreteUtils: schemaUtils30X
|
||||||
},
|
},
|
||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
schemaResolutionCache = {},
|
schemaResolutionCache = {},
|
||||||
@@ -213,7 +216,11 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
// check for supported formats
|
// check for supported formats
|
||||||
_.forEach(allSupportedFormats, (supportedFormat) => {
|
_.forEach(allSupportedFormats, (supportedFormat) => {
|
||||||
output = deref.resolveRefs(schema, parameterSource,
|
output = deref.resolveRefs(schema, parameterSource,
|
||||||
{ components: { schemas: { schemaWithFormat: { type: 'string', format: supportedFormat } } } });
|
{
|
||||||
|
components:
|
||||||
|
{ schemas: { schemaWithFormat: { type: 'string', format: supportedFormat } } },
|
||||||
|
concreteUtils: schemaUtils30X
|
||||||
|
});
|
||||||
|
|
||||||
expect(output.type).to.equal('string');
|
expect(output.type).to.equal('string');
|
||||||
expect(output.format).to.equal(supportedFormat);
|
expect(output.format).to.equal(supportedFormat);
|
||||||
@@ -222,7 +229,10 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
// check for not supported formats
|
// check for not supported formats
|
||||||
_.forEach(nonSupportedFormats, (nonSupportedFormat) => {
|
_.forEach(nonSupportedFormats, (nonSupportedFormat) => {
|
||||||
output = deref.resolveRefs(schema, parameterSource,
|
output = deref.resolveRefs(schema, parameterSource,
|
||||||
{ components: { schemas: { schemaWithFormat: nonSupportedFormat } } });
|
{
|
||||||
|
components: { schemas: { schemaWithFormat: nonSupportedFormat } },
|
||||||
|
concreteUtils: schemaUtils30X
|
||||||
|
});
|
||||||
|
|
||||||
expect(output.type).to.equal(nonSupportedFormat.type);
|
expect(output.type).to.equal(nonSupportedFormat.type);
|
||||||
expect(output.format).to.be.undefined;
|
expect(output.format).to.be.undefined;
|
||||||
@@ -240,7 +250,7 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
output;
|
output;
|
||||||
|
|
||||||
output = deref.resolveRefs(schema, parameterSource, {});
|
output = deref.resolveRefs(schema, parameterSource, { concreteUtils: schemaUtils30X });
|
||||||
expect(output.type).to.equal('string');
|
expect(output.type).to.equal('string');
|
||||||
expect(output.format).to.be.undefined;
|
expect(output.format).to.be.undefined;
|
||||||
expect(output.pattern).to.eql(schema.pattern);
|
expect(output.pattern).to.eql(schema.pattern);
|
||||||
@@ -299,7 +309,8 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
concreteUtils: schemaUtils30X
|
||||||
},
|
},
|
||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
schemaResoltionCache = {},
|
schemaResoltionCache = {},
|
||||||
@@ -359,7 +370,14 @@ describe('DEREF FUNCTION TESTS ', function() {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(deref.resolveAllOf(allOfschema, 'REQUEST', {}, {}, null, 'example')).to.deep.include({
|
expect(deref.resolveAllOf(
|
||||||
|
allOfschema,
|
||||||
|
'REQUEST',
|
||||||
|
{ concreteUtils: schemaUtils30X },
|
||||||
|
{},
|
||||||
|
null,
|
||||||
|
'example'
|
||||||
|
)).to.deep.include({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
source: {
|
source: {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const expect = require('chai').expect,
|
const expect = require('chai').expect,
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
inputValidation = require('../../lib/inputValidation'),
|
inputValidation = require('../../lib/30XUtils/inputValidation'),
|
||||||
parse = require('../../lib/parse.js');
|
parse = require('../../lib/parse.js');
|
||||||
|
|
||||||
describe('PARSE FUNCTION TESTS', function() {
|
describe('PARSE FUNCTION TESTS', function() {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ var expect = require('chai').expect,
|
|||||||
crypto = require('crypto'),
|
crypto = require('crypto'),
|
||||||
hash = (input) => {
|
hash = (input) => {
|
||||||
return crypto.createHash('sha1').update(input).digest('base64');
|
return crypto.createHash('sha1').update(input).digest('base64');
|
||||||
};
|
},
|
||||||
|
concreteUtils = require('./../../lib/30XUtils/schemaUtils30X');
|
||||||
|
|
||||||
/* Utility function Unit tests */
|
/* Utility function Unit tests */
|
||||||
describe('UTILITY FUNCTION TESTS', function() {
|
describe('UTILITY FUNCTION TESTS', function() {
|
||||||
@@ -69,7 +70,7 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
|
|||||||
resolveTo = 'schema',
|
resolveTo = 'schema',
|
||||||
resolveFor = 'CONVERSION';
|
resolveFor = 'CONVERSION';
|
||||||
|
|
||||||
expect(SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource, { components }))
|
expect(SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource, { components, concreteUtils }))
|
||||||
.to.equal('<string>');
|
.to.equal('<string>');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -100,7 +101,13 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
|
|||||||
resolveTo = 'schema',
|
resolveTo = 'schema',
|
||||||
resolveFor = 'CONVERSION',
|
resolveFor = 'CONVERSION',
|
||||||
|
|
||||||
result = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource, { components }),
|
result = SchemaUtils.safeSchemaFaker(
|
||||||
|
schema,
|
||||||
|
resolveTo,
|
||||||
|
resolveFor,
|
||||||
|
parameterSource,
|
||||||
|
{ components, concreteUtils }
|
||||||
|
),
|
||||||
tooManyLevelsString = result[0].c.value;
|
tooManyLevelsString = result[0].c.value;
|
||||||
|
|
||||||
expect(result).to.not.equal(null);
|
expect(result).to.not.equal(null);
|
||||||
@@ -139,7 +146,13 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
|
|||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
resolveTo = 'schema',
|
resolveTo = 'schema',
|
||||||
resolveFor = 'CONVERSION',
|
resolveFor = 'CONVERSION',
|
||||||
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource, { components });
|
fakedSchema = SchemaUtils.safeSchemaFaker(
|
||||||
|
schema,
|
||||||
|
resolveTo,
|
||||||
|
resolveFor,
|
||||||
|
parameterSource,
|
||||||
|
{ components, concreteUtils }
|
||||||
|
);
|
||||||
|
|
||||||
expect(fakedSchema.value).to.equal('reference #/components/schem2 not found in the OpenAPI spec');
|
expect(fakedSchema.value).to.equal('reference #/components/schem2 not found in the OpenAPI spec');
|
||||||
done();
|
done();
|
||||||
@@ -163,14 +176,20 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
|
|||||||
parameterSource = 'REQUEST',
|
parameterSource = 'REQUEST',
|
||||||
resolveTo = 'schema',
|
resolveTo = 'schema',
|
||||||
resolveFor = 'CONVERSION',
|
resolveFor = 'CONVERSION',
|
||||||
resolvedSchema = deref.resolveRefs(schema, parameterSource, { components }, {}, resolveFor, resolveTo),
|
resolvedSchema = deref.resolveRefs(schema,
|
||||||
|
parameterSource,
|
||||||
|
{ components, concreteUtils },
|
||||||
|
{},
|
||||||
|
resolveFor,
|
||||||
|
resolveTo
|
||||||
|
),
|
||||||
schemaCache = {
|
schemaCache = {
|
||||||
schemaFakerCache: {},
|
schemaFakerCache: {},
|
||||||
schemaResolutionCache: {}
|
schemaResolutionCache: {}
|
||||||
},
|
},
|
||||||
key = hash('resolveToSchema ' + JSON.stringify(resolvedSchema)),
|
key = hash('resolveToSchema ' + JSON.stringify(resolvedSchema)),
|
||||||
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource,
|
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource,
|
||||||
{ components }, 'default', ' ', schemaCache);
|
{ components, concreteUtils }, 'default', ' ', schemaCache);
|
||||||
|
|
||||||
expect(schemaCache.schemaFakerCache).to.have.property(key);
|
expect(schemaCache.schemaFakerCache).to.have.property(key);
|
||||||
expect(schemaCache.schemaFakerCache[key]).to.equal(fakedSchema);
|
expect(schemaCache.schemaFakerCache[key]).to.equal(fakedSchema);
|
||||||
@@ -204,11 +223,16 @@ describe('SCHEMA UTILITY FUNCTION TESTS ', function () {
|
|||||||
schemaFakerCache: {},
|
schemaFakerCache: {},
|
||||||
schemaResolutionCache: {}
|
schemaResolutionCache: {}
|
||||||
},
|
},
|
||||||
resolvedSchema = deref.resolveRefs(schema, parameterSource, { components }, schemaCache.schemaResolutionCache,
|
resolvedSchema = deref.resolveRefs(schema,
|
||||||
resolveFor, resolveTo),
|
parameterSource,
|
||||||
|
{ components, concreteUtils },
|
||||||
|
schemaCache.schemaResolutionCache,
|
||||||
|
resolveFor,
|
||||||
|
resolveTo
|
||||||
|
),
|
||||||
key = hash('resolveToExample ' + JSON.stringify(resolvedSchema)),
|
key = hash('resolveToExample ' + JSON.stringify(resolvedSchema)),
|
||||||
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource,
|
fakedSchema = SchemaUtils.safeSchemaFaker(schema, resolveTo, resolveFor, parameterSource,
|
||||||
{ components }, 'default', ' ', schemaCache);
|
{ components, concreteUtils }, 'default', ' ', schemaCache);
|
||||||
|
|
||||||
expect(schemaCache.schemaFakerCache).to.have.property(key);
|
expect(schemaCache.schemaFakerCache).to.have.property(key);
|
||||||
expect(schemaCache.schemaFakerCache[key]).to.equal(fakedSchema);
|
expect(schemaCache.schemaFakerCache[key]).to.equal(fakedSchema);
|
||||||
|
|||||||
Reference in New Issue
Block a user