@apistudio/apim-cli
Version:
CLI for API Management Products
135 lines (134 loc) • 5.63 kB
JavaScript
/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
import JSZip from 'jszip';
import yaml from 'js-yaml';
import { CollectionCreator } from '../newman/newman-collection.builder.js';
import { AssetParser } from '../parsers/asset.parser.js';
import { addErrorToResponse } from '../helpers/helper.js';
import { AppConstants } from '../constants/app.constants.js';
import { YamlValidator } from '../validator/yaml.validator.js';
import { NewmanRunner } from '../newman/newman-test.js';
import { GatewayAssetHandler } from '../converter/gateway-asset.handler.js';
import { LogWrapper } from '../service/log-wrapper.js';
export class TestManager {
async validateEndpoints(buffer) {
LogWrapper.logInfo('0204', 'endpoint');
const zipContent = await this.loadZipContent(buffer);
for (const [, file] of Object.entries(zipContent.files)) {
if (this.isYamlFile(file.name)) {
const parsedYamlDatas = await this.parseYamlFile(file);
const isValid = await this.validateYamlData(parsedYamlDatas, buffer);
if (!isValid) {
return false;
}
}
}
LogWrapper.logInfo('0206', 'Endpoint');
return true;
}
async loadZipContent(buffer) {
const zip = new JSZip();
return zip.loadAsync(buffer);
}
isYamlFile(fileName) {
return fileName.endsWith('.yaml') || fileName.endsWith('.yml');
}
async parseYamlFile(file) {
const data = await file.async('string');
return yaml.loadAll(data);
}
async validateYamlData(parsedYamlDatas, buffer) {
for (const parsedData of parsedYamlDatas) {
if (parsedData.kind?.toLowerCase() !== 'test' || !parsedData.kind) {
continue;
}
const apiReference = parsedData.spec.api?.$ref;
const endpointReference = parsedData.spec.api?.$endpoint;
if (apiReference) {
const isValid = await this.validateApiReference(apiReference, buffer);
if (!isValid) {
return false;
}
}
else if (!endpointReference) {
return false;
}
}
return true;
}
async validateApiReference(apiReference, buffer) {
const gatewayHandler = new GatewayAssetHandler(buffer);
const endpoint = await gatewayHandler.getApiEndpoints(apiReference);
if (endpoint[0].length === 0) {
addErrorToResponse(AppConstants.VALIDATION_ERROR_CODE, 'endpoint', `Invalid or Empty endpoint for reference ${apiReference}`);
LogWrapper.logError('0205', apiReference);
return false;
}
return true;
}
async validateReferences(buffer) {
LogWrapper.logInfo('0204', 'reference');
const obj = new AssetParser();
const refMap = await obj.createAssetReferenceMap(buffer);
await obj.updateMapWithGatewayEndpoints(buffer, refMap);
const allRefsValid = Array.from(refMap.entries()).every(([key, value]) => {
if (!value) {
addErrorToResponse(AppConstants.VALIDATION_ERROR_CODE, key, `Validation failed for Reference ${key}`);
LogWrapper.logError('0207', key);
}
return value;
});
if (!allRefsValid) {
LogWrapper.logError('0003', 'Validation failed: Some references are not valid.');
return false;
}
LogWrapper.logInfo('0206', 'Reference');
return true;
}
async validate(buffer) {
LogWrapper.logDebug('0003', 'Starting overall validation process.');
const validateObj = new YamlValidator();
if (!await validateObj.validateYamlFiles(buffer)) {
LogWrapper.logError('0004', 'YAML validation failed.');
return false;
}
if (!await this.validateEndpoints(buffer)) {
LogWrapper.logError('0004', 'Endpoint validation failed.');
return false;
}
if (!await this.validateReferences(buffer)) {
LogWrapper.logError('0004', 'Reference validation failed.');
return false;
}
LogWrapper.logInfo('0003', 'Overall validation process completed successfully.');
return true;
}
async processFile(buffer) {
LogWrapper.logInfo('0003', 'Starting file processing.');
if (!await this.validate(buffer)) {
LogWrapper.logError('0004', 'File processing aborted due to validation failure.');
return null;
}
const zipContent = await this.loadZipContent(buffer);
const summaries = [];
for (const [, file] of Object.entries(zipContent.files)) {
const data = await file.async('string');
const parsedYamlDatas = yaml.loadAll(data);
for (const parsedData of parsedYamlDatas) {
if (parsedData.kind?.toLowerCase() !== 'test') {
continue;
}
LogWrapper.logInfo('0208', file.name);
const collectionCreator = new CollectionCreator();
const collection = await collectionCreator.createCollection(parsedData, buffer);
const runner = new NewmanRunner(collection);
const summary = await runner.run();
summaries.push(summary);
LogWrapper.logInfo('0209', file.name);
}
}
LogWrapper.logInfo('0003', 'File processing completed.');
return summaries;
}
}