mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
Fix input validation in multi file APIs
This commit is contained in:
@@ -4815,6 +4815,16 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description Takes in a the root files obtains the related files and
|
||||||
|
* generates the result object
|
||||||
|
* @param {object} parsedRootFiles - found parsed root files
|
||||||
|
* @param {array} inputData - file data information [{path, content}]
|
||||||
|
* @param {Array} origin - process origin (BROWSER or node)
|
||||||
|
*
|
||||||
|
* @returns {object} process result { rootFile, relatedFiles, missingRelatedFiles }
|
||||||
|
*/
|
||||||
getRelatedFilesData(parsedRootFiles, inputData, origin) {
|
getRelatedFilesData(parsedRootFiles, inputData, origin) {
|
||||||
const data = parsedRootFiles.map((root) => {
|
const data = parsedRootFiles.map((root) => {
|
||||||
let relatedData = getRelatedFiles(root, inputData, origin),
|
let relatedData = getRelatedFiles(root, inputData, origin),
|
||||||
@@ -4828,6 +4838,17 @@ module.exports = {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* @description Takes in parsed root files and bundle it
|
||||||
|
* @param {object} parsedRootFiles - found parsed root files
|
||||||
|
* @param {array} inputData - file data information [{path, content}]
|
||||||
|
* @param {Array} origin - process origin (BROWSER or node)
|
||||||
|
* @param {string} format - output format could be either YAML or JSON
|
||||||
|
* @param {string} version - specification version specified in the input
|
||||||
|
*
|
||||||
|
* @returns {object} process result { rootFile, bundledContent }
|
||||||
|
*/
|
||||||
getBundledFileData(parsedRootFiles, inputData, origin, format) {
|
getBundledFileData(parsedRootFiles, inputData, origin, format) {
|
||||||
const data = parsedRootFiles.map((root) => {
|
const data = parsedRootFiles.map((root) => {
|
||||||
let bundleData = getBundleContentAndComponents(root, inputData, origin);
|
let bundleData = getBundleContentAndComponents(root, inputData, origin);
|
||||||
@@ -4923,6 +4944,28 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description Validates the input for multi file APIs
|
||||||
|
* @param {string} processInput - Process input data
|
||||||
|
*
|
||||||
|
* @returns {undefined} - nothing
|
||||||
|
*/
|
||||||
|
validateInputMultiFileAPI(processInput) {
|
||||||
|
if (_.isEmpty(processInput)) {
|
||||||
|
throw new Error('Input object must have "type" and "data" information');
|
||||||
|
}
|
||||||
|
if (!processInput.type) {
|
||||||
|
throw new Error('"Type" parameter should be provided');
|
||||||
|
}
|
||||||
|
if (!processInput.data || processInput.data.length === 0) {
|
||||||
|
throw new Error('"Data" parameter should be provided');
|
||||||
|
}
|
||||||
|
if (processInput.data[0].path === '') {
|
||||||
|
throw new Error('"Path" of the data element should be provided');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
parseFileOrThrow(fileContent) {
|
parseFileOrThrow(fileContent) {
|
||||||
const result = parse.getOasObject(fileContent);
|
const result = parse.getOasObject(fileContent);
|
||||||
if (result.result === false) {
|
if (result.result === false) {
|
||||||
|
|||||||
@@ -629,10 +629,8 @@ class SchemaPack {
|
|||||||
*/
|
*/
|
||||||
async detectRootFiles() {
|
async detectRootFiles() {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
if (input.data[0].path === '') {
|
|
||||||
throw new Error('undefined input');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
schemaUtils.validateInputMultiFileAPI(input);
|
||||||
if (!this.hasDefinedVersion && ('content' in input.data[0])) {
|
if (!this.hasDefinedVersion && ('content' in input.data[0])) {
|
||||||
return schemaUtils.mapGetRootFilesOutputToDetectRootFilesOutput([], input.specificationVersion);
|
return schemaUtils.mapGetRootFilesOutputToDetectRootFilesOutput([], input.specificationVersion);
|
||||||
}
|
}
|
||||||
@@ -668,6 +666,8 @@ class SchemaPack {
|
|||||||
*/
|
*/
|
||||||
async detectRelatedFiles() {
|
async detectRelatedFiles() {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
|
|
||||||
|
schemaUtils.validateInputMultiFileAPI(input);
|
||||||
if (!input.rootFiles || input.rootFiles.length === 0) {
|
if (!input.rootFiles || input.rootFiles.length === 0) {
|
||||||
let rootFiles = await this.detectRootFiles(input);
|
let rootFiles = await this.detectRootFiles(input);
|
||||||
if (rootFiles.output.data) {
|
if (rootFiles.output.data) {
|
||||||
@@ -698,6 +698,8 @@ class SchemaPack {
|
|||||||
*/
|
*/
|
||||||
async bundle() {
|
async bundle() {
|
||||||
const input = this.input;
|
const input = this.input;
|
||||||
|
|
||||||
|
schemaUtils.validateInputMultiFileAPI(input);
|
||||||
if (!input.rootFiles || input.rootFiles.length === 0) {
|
if (!input.rootFiles || input.rootFiles.length === 0) {
|
||||||
let rootFiles = await this.detectRootFiles(input);
|
let rootFiles = await this.detectRootFiles(input);
|
||||||
if (rootFiles.output.data) {
|
if (rootFiles.output.data) {
|
||||||
|
|||||||
@@ -806,4 +806,50 @@ describe('getReferences method when node does not have any reference', function(
|
|||||||
expect(result.referencesInNode[0].path).to.equal('./user.yaml');
|
expect(result.referencesInNode[0].path).to.equal('./user.yaml');
|
||||||
expect(result.referencesInNode[0].newValue.$ref).to.equal('the/parent/user.yaml');
|
expect(result.referencesInNode[0].newValue.$ref).to.equal('the/parent/user.yaml');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return error when "type" parameter is not sent', async function () {
|
||||||
|
let input = {
|
||||||
|
rootFiles: [
|
||||||
|
{
|
||||||
|
path: '/root.yaml',
|
||||||
|
content: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
path: '/examples.yaml',
|
||||||
|
content: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
options: {},
|
||||||
|
bundleFormat: 'JSON'
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
await Converter.bundle(input);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Type" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input is an empty object', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.bundle({});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('Input object must have "type" and "data" information');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input data is an empty array', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.bundle({ type: 'folder', data: [] });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Data" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -139,8 +139,7 @@ describe('detectRelatedFiles method', function () {
|
|||||||
content: contentFileMissedRef
|
content: contentFileMissedRef
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [
|
data: [{}]
|
||||||
]
|
|
||||||
},
|
},
|
||||||
res = await Converter.detectRelatedFiles(input);
|
res = await Converter.detectRelatedFiles(input);
|
||||||
expect(res).to.not.be.empty;
|
expect(res).to.not.be.empty;
|
||||||
@@ -242,8 +241,7 @@ describe('detectRelatedFiles method', function () {
|
|||||||
content: contentFileHop
|
content: contentFileHop
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [
|
data: [{}]
|
||||||
]
|
|
||||||
};
|
};
|
||||||
const res = await Converter.detectRelatedFiles(input);
|
const res = await Converter.detectRelatedFiles(input);
|
||||||
expect(res).to.not.be.empty;
|
expect(res).to.not.be.empty;
|
||||||
@@ -266,8 +264,7 @@ describe('detectRelatedFiles method', function () {
|
|||||||
content: contentFileHop
|
content: contentFileHop
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [
|
data: [{}]
|
||||||
]
|
|
||||||
};
|
};
|
||||||
const res = await Converter.detectRelatedFiles(input);
|
const res = await Converter.detectRelatedFiles(input);
|
||||||
expect(res).to.not.be.empty;
|
expect(res).to.not.be.empty;
|
||||||
@@ -286,8 +283,7 @@ describe('detectRelatedFiles method', function () {
|
|||||||
content: contentFile
|
content: contentFile
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
data: [
|
data: [{}]
|
||||||
]
|
|
||||||
};
|
};
|
||||||
const res = await Converter.detectRelatedFiles(input);
|
const res = await Converter.detectRelatedFiles(input);
|
||||||
expect(res).to.not.be.empty;
|
expect(res).to.not.be.empty;
|
||||||
@@ -368,4 +364,50 @@ describe('detectRelatedFiles method', function () {
|
|||||||
expect(res.output.data[0].missingRelatedFiles.length).to.equal(6);
|
expect(res.output.data[0].missingRelatedFiles.length).to.equal(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return error when "type" parameter is not sent', async function () {
|
||||||
|
let contentRootFile = fs.readFileSync(petstoreMultipleFiles, 'utf8'),
|
||||||
|
contentFileResPets = fs.readFileSync(resourcesPets, 'utf8'),
|
||||||
|
input = {
|
||||||
|
rootFiles: [
|
||||||
|
{
|
||||||
|
path: '/openapi.yaml',
|
||||||
|
content: contentRootFile
|
||||||
|
}
|
||||||
|
],
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
path: '/resources/pets.yaml',
|
||||||
|
content: contentFileResPets
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Converter.detectRelatedFiles(input);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Type" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input is an empty object', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.detectRelatedFiles({});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('Input object must have "type" and "data" information');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input data is an empty array', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.detectRelatedFiles({ type: 'folder', data: [] });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Data" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ describe('detectRoot method', function() {
|
|||||||
await Converter.detectRootFiles(input);
|
await Converter.detectRootFiles(input);
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
expect(ex.message).to.equal('undefined input');
|
expect(ex.message).to.equal('"Path" of the data element should be provided');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -266,4 +266,45 @@ describe('detectRoot method', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return error when "type" parameter is not sent', async function () {
|
||||||
|
let input = {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
path: validPetstore
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: validHopService31x
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Converter.detectRootFiles(input);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Type" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input is an empty object', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.detectRootFiles({});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('Input object must have "type" and "data" information');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when input data is an empty array', async function () {
|
||||||
|
try {
|
||||||
|
await Converter.detectRootFiles({ type: 'folder', data: [] });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
expect(error).to.not.be.undefined;
|
||||||
|
expect(error.message).to.equal('"Data" parameter should be provided');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user