mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
Change validation input when version is 3.1.x
if the option includeWebhooks is false and there are no paths (only webhooks or componentes) throw error.
This commit is contained in:
@@ -6,10 +6,11 @@ module.exports = {
|
|||||||
* OpenAPI 3.1 only openapi and info are always required,
|
* OpenAPI 3.1 only openapi and info are always required,
|
||||||
* but the document must also contain at least one of paths or webhooks or components.
|
* but the document must also contain at least one of paths or webhooks or components.
|
||||||
* @param {Object} spec OpenAPI spec
|
* @param {Object} spec OpenAPI spec
|
||||||
|
* @param {Object} options computed process options
|
||||||
* @return {Object} Validation result
|
* @return {Object} Validation result
|
||||||
*/
|
*/
|
||||||
validateSpec: function (spec) {
|
validateSpec: function (spec, options) {
|
||||||
|
const includeWebhooksOption = options.includeWebhooks;
|
||||||
if (!spec.hasOwnProperty('openapi')) {
|
if (!spec.hasOwnProperty('openapi')) {
|
||||||
return {
|
return {
|
||||||
result: false,
|
result: false,
|
||||||
@@ -24,7 +25,15 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spec.hasOwnProperty('paths') && !spec.hasOwnProperty('webhooks') && !spec.hasOwnProperty('components')) {
|
if (!spec.hasOwnProperty('paths') && !includeWebhooksOption) {
|
||||||
|
return {
|
||||||
|
result: false,
|
||||||
|
reason: 'Specification must contain Paths Object for the available operational paths'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeWebhooksOption && !spec.hasOwnProperty('paths') &&
|
||||||
|
!spec.hasOwnProperty('webhooks') && !spec.hasOwnProperty('components')) {
|
||||||
return {
|
return {
|
||||||
result: false,
|
result: false,
|
||||||
reason: 'Specification must contain either Paths, Webhooks or Components sections'
|
reason: 'Specification must contain either Paths, Webhooks or Components sections'
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ module.exports = {
|
|||||||
/**
|
/**
|
||||||
* Parses an OAS 3.1.X string/object as a YAML or JSON
|
* 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
|
* @param {YAML/JSON} openApiSpec - The OAS 3.1.x specification specified in either YAML or JSON
|
||||||
|
* @param {Object} options computed process options
|
||||||
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
||||||
* @no-unit-test
|
* @no-unit-test
|
||||||
*/
|
*/
|
||||||
parseSpec: function (openApiSpec) {
|
parseSpec: function (openApiSpec, options) {
|
||||||
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation31X);
|
return schemaUtilsCommon.parseSpec(openApiSpec, inputValidation31X, options);
|
||||||
},
|
},
|
||||||
inputValidation: inputValidation31X,
|
inputValidation: inputValidation31X,
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ module.exports = {
|
|||||||
* Parses an OAS string/object as a YAML or JSON
|
* 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
|
* @param {YAML/JSON} openApiSpec - The OAS 3.x specification specified in either YAML or JSON
|
||||||
* @param {object} inputValidation - Concrete validator according to version
|
* @param {object} inputValidation - Concrete validator according to version
|
||||||
|
* @param {Object} options computed process options
|
||||||
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
* @returns {Object} - Contains the parsed JSON-version of the OAS spec, or an error
|
||||||
* @no-unit-test
|
* @no-unit-test
|
||||||
*/
|
*/
|
||||||
parseSpec: function (openApiSpec, inputValidation) {
|
parseSpec: function (openApiSpec, inputValidation, options) {
|
||||||
var openApiObj = openApiSpec,
|
var openApiObj = openApiSpec,
|
||||||
obj,
|
obj,
|
||||||
rootValidation;
|
rootValidation;
|
||||||
@@ -32,7 +33,7 @@ module.exports = {
|
|||||||
// spec is a valid JSON object at this point
|
// spec is a valid JSON object at this point
|
||||||
|
|
||||||
// Validate the root level object for semantics
|
// Validate the root level object for semantics
|
||||||
rootValidation = inputValidation.validateSpec(openApiObj);
|
rootValidation = inputValidation.validateSpec(openApiObj, options);
|
||||||
if (!rootValidation.result) {
|
if (!rootValidation.result) {
|
||||||
return {
|
return {
|
||||||
result: false,
|
result: false,
|
||||||
|
|||||||
57
lib/parse.js
57
lib/parse.js
@@ -34,58 +34,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate Spec to check if some of the required fields are present.
|
|
||||||
*
|
|
||||||
* @param {Object} spec OpenAPI spec
|
|
||||||
* @return {Object} Validation result
|
|
||||||
*/
|
|
||||||
validateSpec: function (spec) {
|
|
||||||
|
|
||||||
// Checking for the all the required properties in the specification
|
|
||||||
if (!spec.hasOwnProperty('openapi')) {
|
|
||||||
return {
|
|
||||||
result: false,
|
|
||||||
reason: 'Specification must contain a semantic version number of the OAS specification'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spec.hasOwnProperty('paths')) {
|
|
||||||
return {
|
|
||||||
result: false,
|
|
||||||
reason: 'Specification must contain Paths Object for the available operational paths'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spec.hasOwnProperty('info')) {
|
|
||||||
return {
|
|
||||||
result: false,
|
|
||||||
reason: 'Specification must contain an Info Object for the meta-data of the API'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!spec.info.hasOwnProperty('$ref')) {
|
|
||||||
if (!spec.info.hasOwnProperty('title')) {
|
|
||||||
return {
|
|
||||||
result: false,
|
|
||||||
reason: 'Specification must contain a title in order to generate a collection'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spec.info.hasOwnProperty('version')) {
|
|
||||||
return {
|
|
||||||
result: false,
|
|
||||||
reason: 'Specification must contain a semantic version number of the API in the Info Object'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid specification
|
|
||||||
return {
|
|
||||||
result: true,
|
|
||||||
openapi: spec
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Converts OpenAPI input to OpenAPI Object
|
/** Converts OpenAPI input to OpenAPI Object
|
||||||
* @param {String} openApiSpec OpenAPI input in string
|
* @param {String} openApiSpec OpenAPI input in string
|
||||||
* @returns {Object} oasObject
|
* @returns {Object} oasObject
|
||||||
@@ -129,10 +77,11 @@ module.exports = {
|
|||||||
*
|
*
|
||||||
* @param {Array} input input object that contains files array
|
* @param {Array} input input object that contains files array
|
||||||
* @param {Object} inputValidation Validator according to version
|
* @param {Object} inputValidation Validator according to version
|
||||||
|
* @param {Object} options computed process options
|
||||||
* @param {Object} files Files map
|
* @param {Object} files Files map
|
||||||
* @return {String} rootFile
|
* @return {String} rootFile
|
||||||
*/
|
*/
|
||||||
getRootFiles: function (input, inputValidation, files = {}) {
|
getRootFiles: function (input, inputValidation, options, files = {}) {
|
||||||
let rootFilesArray = [],
|
let rootFilesArray = [],
|
||||||
filesPathArray = input.data,
|
filesPathArray = input.data,
|
||||||
origin = input.origin || '';
|
origin = input.origin || '';
|
||||||
@@ -160,7 +109,7 @@ module.exports = {
|
|||||||
else {
|
else {
|
||||||
throw new Error(obj.reason);
|
throw new Error(obj.reason);
|
||||||
}
|
}
|
||||||
if (inputValidation.validateSpec(oasObject).result) {
|
if (inputValidation.validateSpec(oasObject, options).result) {
|
||||||
rootFilesArray.push(filePath.fileName);
|
rootFilesArray.push(filePath.fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class SchemaPack {
|
|||||||
return this.validationResult;
|
return this.validationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
specParseResult = concreteUtils.parseSpec(json);
|
specParseResult = concreteUtils.parseSpec(json, this.computedOptions);
|
||||||
|
|
||||||
if (!specParseResult.result) {
|
if (!specParseResult.result) {
|
||||||
// validation failed
|
// validation failed
|
||||||
@@ -190,7 +190,7 @@ class SchemaPack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rootFiles = parse.getRootFiles(input, concreteUtils.inputValidation, files);
|
rootFiles = parse.getRootFiles(input, concreteUtils.inputValidation, this.computedOptions, files);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
return cb(null, {
|
return cb(null, {
|
||||||
|
|||||||
@@ -69,44 +69,64 @@ const { expect } = require('chai'),
|
|||||||
|
|
||||||
describe('validateSpec method', function () {
|
describe('validateSpec method', function () {
|
||||||
it('should return true with a valid simple spec with webhooks', function () {
|
it('should return true with a valid simple spec with webhooks', function () {
|
||||||
const validationResult = validateSpec(correctMockedEntryWH);
|
const validationResult = validateSpec(correctMockedEntryWH, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.true;
|
expect(validationResult.result).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true with a valid simple spec with paths', function () {
|
it('should return true with a valid simple spec with paths', function () {
|
||||||
const validationResult = validateSpec(correctMockedEntryPath);
|
const validationResult = validateSpec(correctMockedEntryPath, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.true;
|
expect(validationResult.result).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true with a valid simple spec with components', function () {
|
it('should return true with a valid simple spec with components', function () {
|
||||||
const validationResult = validateSpec(correctMockedEntryComponent);
|
const validationResult = validateSpec(correctMockedEntryComponent, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.true;
|
expect(validationResult.result).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true with a valid simple spec with components webhooks y paths', function () {
|
it('should return true with a valid simple spec with components webhooks y paths', function () {
|
||||||
const validationResult = validateSpec(correctMockedEntry);
|
const validationResult = validateSpec(correctMockedEntry, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.true;
|
expect(validationResult.result).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false with an invalid input without openapi field', function () {
|
it('should return false with an invalid input without openapi field', function () {
|
||||||
const validationResult = validateSpec(incorrectMockedEntryNoOpenapi);
|
const validationResult = validateSpec(incorrectMockedEntryNoOpenapi, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.false;
|
expect(validationResult.result).to.be.false;
|
||||||
expect(validationResult.reason)
|
expect(validationResult.reason)
|
||||||
.to.equal('Specification must contain a semantic version number of the OAS specification');
|
.to.equal('Specification must contain a semantic version number of the OAS specification');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false with an invalid input without info field', function () {
|
it('should return false with an invalid input without info field', function () {
|
||||||
const validationResult = validateSpec(incorrectMockedEntryNoInfo);
|
const validationResult = validateSpec(incorrectMockedEntryNoInfo, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.false;
|
expect(validationResult.result).to.be.false;
|
||||||
expect(validationResult.reason)
|
expect(validationResult.reason)
|
||||||
.to.equal('Specification must contain an Info Object for the meta-data of the API');
|
.to.equal('Specification must contain an Info Object for the meta-data of the API');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false with an invalid input without path components and webhooks', function () {
|
it('should return false with an invalid input without path components and webhooks', function () {
|
||||||
const validationResult = validateSpec(incorrectMockedEntryNOPathsComponentsWebhooks);
|
const validationResult = validateSpec(incorrectMockedEntryNOPathsComponentsWebhooks, { includeWebhooks: true });
|
||||||
expect(validationResult.result).to.be.false;
|
expect(validationResult.result).to.be.false;
|
||||||
expect(validationResult.reason)
|
expect(validationResult.reason)
|
||||||
.to.equal('Specification must contain either Paths, Webhooks or Components sections');
|
.to.equal('Specification must contain either Paths, Webhooks or Components sections');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return false with a valid simple spec with only webhooks but include webhooks is false', function () {
|
||||||
|
const validationResult = validateSpec(correctMockedEntryWH, { includeWebhooks: false });
|
||||||
|
expect(validationResult.result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true with a valid simple spec with paths and webhooks include webhooks is false', function () {
|
||||||
|
const validationResult = validateSpec(correctMockedEntryPath, { includeWebhooks: false });
|
||||||
|
expect(validationResult.result).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false with a valid simple spec with only components and include webhooks is false', function () {
|
||||||
|
const validationResult = validateSpec(correctMockedEntryComponent, { includeWebhooks: false });
|
||||||
|
expect(validationResult.result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false with input without path components or webhooks include webhooks is false', function () {
|
||||||
|
const validationResult = validateSpec(incorrectMockedEntryNOPathsComponentsWebhooks, { includeWebhooks: false });
|
||||||
|
expect(validationResult.result).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const { expect } = require('chai'),
|
|||||||
describe('parseSpec method', function () {
|
describe('parseSpec method', function () {
|
||||||
it('should return true and a parsed specification', function () {
|
it('should return true and a parsed specification', function () {
|
||||||
let fileContent = fs.readFileSync(valid31xFolder + '/webhooks.json', 'utf8');
|
let fileContent = fs.readFileSync(valid31xFolder + '/webhooks.json', 'utf8');
|
||||||
const parsedSpec = concreteUtils.parseSpec(fileContent);
|
const parsedSpec = concreteUtils.parseSpec(fileContent, { includeWebhooks: true });
|
||||||
expect(parsedSpec.result).to.be.true;
|
expect(parsedSpec.result).to.be.true;
|
||||||
expect(parsedSpec.openapi.openapi).to.equal('3.1.0');
|
expect(parsedSpec.openapi.openapi).to.equal('3.1.0');
|
||||||
expect(parsedSpec.openapi.webhooks).to.not.be.undefined;
|
expect(parsedSpec.openapi.webhooks).to.not.be.undefined;
|
||||||
@@ -15,14 +15,14 @@ describe('parseSpec method', function () {
|
|||||||
|
|
||||||
it('should return false and invalid format message when input content is sent', function () {
|
it('should return false and invalid format message when input content is sent', function () {
|
||||||
let fileContent = fs.readFileSync(invalid31xFolder + '/empty-spec.yaml', 'utf8');
|
let fileContent = fs.readFileSync(invalid31xFolder + '/empty-spec.yaml', 'utf8');
|
||||||
const parsedSpec = concreteUtils.parseSpec(fileContent);
|
const parsedSpec = concreteUtils.parseSpec(fileContent, { includeWebhooks: false });
|
||||||
expect(parsedSpec.result).to.be.false;
|
expect(parsedSpec.result).to.be.false;
|
||||||
expect(parsedSpec.reason).to.equal('Invalid format. Input must be in YAML or JSON format.');
|
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 () {
|
it('should return false and Spec must contain info object', function () {
|
||||||
let fileContent = fs.readFileSync(invalid31xFolder + '/invalid-no-info.json', 'utf8');
|
let fileContent = fs.readFileSync(invalid31xFolder + '/invalid-no-info.json', 'utf8');
|
||||||
const parsedSpec = concreteUtils.parseSpec(fileContent);
|
const parsedSpec = concreteUtils.parseSpec(fileContent, { includeWebhooks: false });
|
||||||
expect(parsedSpec.result).to.be.false;
|
expect(parsedSpec.result).to.be.false;
|
||||||
expect(parsedSpec.reason).to.equal('Specification must contain an Info Object for the meta-data of the API');
|
expect(parsedSpec.reason).to.equal('Specification must contain an Info Object for the meta-data of the API');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -668,7 +668,7 @@ describe('Webhooks support', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should resolve a file with only webhooks but includeWebhooks is false', function() {
|
it('Should return the validation error with a file with only webhooks but includeWebhooks is false', function () {
|
||||||
const fileSource = path.join(__dirname, OPENAPI_31_FOLDER + '/webhooks/payments-webhooks.yaml'),
|
const fileSource = path.join(__dirname, OPENAPI_31_FOLDER + '/webhooks/payments-webhooks.yaml'),
|
||||||
fileData = fs.readFileSync(fileSource, 'utf8'),
|
fileData = fs.readFileSync(fileSource, 'utf8'),
|
||||||
input = {
|
input = {
|
||||||
@@ -676,12 +676,10 @@ describe('Webhooks support', function() {
|
|||||||
data: fileData
|
data: fileData
|
||||||
},
|
},
|
||||||
converter = new SchemaPack(input, { includeWebhooks: false });
|
converter = new SchemaPack(input, { includeWebhooks: false });
|
||||||
|
expect(converter.validated).to.be.false;
|
||||||
converter.convert((err, result) => {
|
expect(converter.validationResult.result).to.be.false;
|
||||||
expect(err).to.be.null;
|
expect(converter.validationResult.reason)
|
||||||
expect(result.result).to.be.true;
|
.to.equal('Specification must contain Paths Object for the available operational paths');
|
||||||
expect(result.output[0].data.item.length).to.eql(0);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should resolve correctly a file with only webhooks, folderStrategy as tag', function() {
|
it('Should resolve correctly a file with only webhooks, folderStrategy as tag', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user