Add input validation for Multifile APIs

Add input validation for Multifile APIs
This commit is contained in:
Luis Tejeda
2022-06-03 12:54:10 -05:00
parent c82d50ed8d
commit b7e2597cc1
5 changed files with 166 additions and 10 deletions

View File

@@ -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) {
const data = parsedRootFiles.map((root) => {
let relatedData = getRelatedFiles(root, inputData, origin),
@@ -4828,6 +4838,17 @@ module.exports = {
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, version) {
const data = parsedRootFiles.map((root) => {
let bundleData = getBundleContentAndComponents(root, inputData, origin, version);
@@ -4931,5 +4952,27 @@ module.exports = {
else {
return res;
}
},
/**
*
* @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');
}
}
};

View File

@@ -629,14 +629,11 @@ class SchemaPack {
*/
async detectRootFiles() {
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])) {
return schemaUtils.mapGetRootFilesOutputToDetectRootFilesOutput([], input.specificationVersion);
}
let files = {},
rootFiles,
res,
@@ -668,6 +665,8 @@ class SchemaPack {
*/
async detectRelatedFiles() {
const input = this.input;
schemaUtils.validateInputMultiFileAPI(input);
if (!input.rootFiles || input.rootFiles.length === 0) {
let rootFiles = await this.detectRootFiles(input);
if (rootFiles.output.data) {
@@ -698,6 +697,8 @@ class SchemaPack {
*/
async bundle() {
const input = this.input;
schemaUtils.validateInputMultiFileAPI(input);
if (!input.rootFiles || input.rootFiles.length === 0) {
let rootFiles = await this.detectRootFiles(input);
if (rootFiles.output.data) {

View File

@@ -792,6 +792,44 @@ describe('bundle files method - 3.0', function () {
expect(res.result).to.be.true;
expect(res.output.data.bundledContent).to.be.equal(expected);
});
it('should return error when "type" parameter is not sent', async function () {
let contentRootFile = fs.readFileSync(refExample + '/root.yaml', 'utf8'),
example = fs.readFileSync(refExample + '/examples.yaml', 'utf8'),
input = {
rootFiles: [
{
path: '/root.yaml',
content: contentRootFile
}
],
data: [
{
path: '/examples.yaml',
content: example
}
],
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');
}
});
});
describe('bundle files method - 2.0', function() {

View File

@@ -139,7 +139,9 @@ describe('detectRelatedFiles method', function () {
content: contentFileMissedRef
}
],
data: [
data: [{
}
]
},
res = await Converter.detectRelatedFiles(input);
@@ -243,6 +245,9 @@ describe('detectRelatedFiles method', function () {
}
],
data: [
{
}
]
};
const res = await Converter.detectRelatedFiles(input);
@@ -266,8 +271,9 @@ describe('detectRelatedFiles method', function () {
content: contentFileHop
}
],
data: [
]
data: [{
}]
};
const res = await Converter.detectRelatedFiles(input);
expect(res).to.not.be.empty;
@@ -286,8 +292,8 @@ describe('detectRelatedFiles method', function () {
content: contentFile
}
],
data: [
]
data: [{
}]
};
const res = await Converter.detectRelatedFiles(input);
expect(res).to.not.be.empty;
@@ -368,4 +374,41 @@ describe('detectRelatedFiles method', function () {
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');
}
});
});

View File

@@ -218,7 +218,7 @@ describe('detectRoot method', function() {
await Converter.detectRootFiles(input);
}
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,35 @@ 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');
}
});
});