@onlineapps/conn-orch-validator 2.0.9 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/conn-orch-validator",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.11",
|
|
4
4
|
"description": "Validation orchestrator for OA Drive microservices - coordinates validation across all layers (base, infra, orch, business)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -62,9 +62,12 @@ class CookbookTestRunner {
|
|
|
62
62
|
this.logger.info(`Running cookbook: ${cookbookData.description || 'Unnamed'}`);
|
|
63
63
|
this.logger.info(`Mode: ${testConfig.mode || 'production'}, Test: ${isTestMode}`);
|
|
64
64
|
|
|
65
|
+
// Convert steps to array format (support both V1 array and V2 object formats)
|
|
66
|
+
const stepsArray = this.normalizeSteps(cookbookData.steps);
|
|
67
|
+
|
|
65
68
|
// Execute steps
|
|
66
69
|
const stepResults = [];
|
|
67
|
-
for (const step of
|
|
70
|
+
for (const step of stepsArray) {
|
|
68
71
|
const stepResult = await this.executeStep(step, testConfig);
|
|
69
72
|
stepResults.push(stepResult);
|
|
70
73
|
|
|
@@ -383,21 +386,51 @@ class CookbookTestRunner {
|
|
|
383
386
|
return JSON.parse(content);
|
|
384
387
|
}
|
|
385
388
|
|
|
389
|
+
/**
|
|
390
|
+
* Normalize steps to array format
|
|
391
|
+
* Supports V1 (steps as array) and V2 (steps as object keyed by step_id)
|
|
392
|
+
*/
|
|
393
|
+
normalizeSteps(steps) {
|
|
394
|
+
if (!steps) {
|
|
395
|
+
return [];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// V1 format: steps is already an array
|
|
399
|
+
if (Array.isArray(steps)) {
|
|
400
|
+
return steps;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// V2 format: steps is an object keyed by step_id
|
|
404
|
+
if (typeof steps === 'object') {
|
|
405
|
+
return Object.entries(steps).map(([stepId, step]) => ({
|
|
406
|
+
...step,
|
|
407
|
+
step_id: stepId,
|
|
408
|
+
id: stepId // Keep both for backward compatibility
|
|
409
|
+
}));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return [];
|
|
413
|
+
}
|
|
414
|
+
|
|
386
415
|
/**
|
|
387
416
|
* Validate cookbook format
|
|
417
|
+
* Supports both V1 (steps as array) and V2 (steps as object) formats
|
|
388
418
|
*/
|
|
389
419
|
validateCookbook(cookbook) {
|
|
390
|
-
if (!cookbook.steps || !Array.isArray(cookbook.steps)) {
|
|
391
|
-
throw new Error('Cookbook must have steps array');
|
|
420
|
+
if (!cookbook.steps || (typeof cookbook.steps !== 'object' && !Array.isArray(cookbook.steps))) {
|
|
421
|
+
throw new Error('Cookbook must have steps (array or object)');
|
|
392
422
|
}
|
|
393
423
|
|
|
394
|
-
|
|
424
|
+
// Normalize steps to array for validation
|
|
425
|
+
const stepsArray = this.normalizeSteps(cookbook.steps);
|
|
426
|
+
|
|
427
|
+
if (stepsArray.length === 0) {
|
|
395
428
|
throw new Error('Cookbook must have at least one step');
|
|
396
429
|
}
|
|
397
430
|
|
|
398
|
-
for (const step of
|
|
399
|
-
if (!step.service) throw new Error(
|
|
400
|
-
if (!step.operation) throw new Error(
|
|
431
|
+
for (const step of stepsArray) {
|
|
432
|
+
if (!step.service) throw new Error(`Step ${step.step_id || step.id || 'unknown'} must have service`);
|
|
433
|
+
if (!step.operation) throw new Error(`Step ${step.step_id || step.id || 'unknown'} must have operation`);
|
|
401
434
|
}
|
|
402
435
|
|
|
403
436
|
return true;
|
|
@@ -405,9 +438,11 @@ class CookbookTestRunner {
|
|
|
405
438
|
|
|
406
439
|
/**
|
|
407
440
|
* Check if cookbook has expect clauses
|
|
441
|
+
* Supports both V1 (array) and V2 (object) step formats
|
|
408
442
|
*/
|
|
409
443
|
hasExpectClauses(cookbook) {
|
|
410
|
-
|
|
444
|
+
const stepsArray = this.normalizeSteps(cookbook.steps);
|
|
445
|
+
return stepsArray.some(step => step.expect !== undefined);
|
|
411
446
|
}
|
|
412
447
|
|
|
413
448
|
/**
|
|
@@ -333,6 +333,7 @@ class ServiceReadinessValidator {
|
|
|
333
333
|
|
|
334
334
|
/**
|
|
335
335
|
* Generate test input based on operation input schema
|
|
336
|
+
* Supports Content Descriptor types (content, file) with proper test values
|
|
336
337
|
*/
|
|
337
338
|
generateTestInput(inputSchema) {
|
|
338
339
|
const testData = {};
|
|
@@ -356,6 +357,21 @@ class ServiceReadinessValidator {
|
|
|
356
357
|
case 'object':
|
|
357
358
|
testData[fieldName] = fieldSpec.default || {};
|
|
358
359
|
break;
|
|
360
|
+
// Content Descriptor types - generate valid test content
|
|
361
|
+
case 'content':
|
|
362
|
+
// Generate content based on field name hints
|
|
363
|
+
if (fieldName.toLowerCase().includes('html')) {
|
|
364
|
+
testData[fieldName] = fieldSpec.default || '<html><body><h1>Test Validation</h1><p>Auto-generated test content.</p></body></html>';
|
|
365
|
+
} else if (fieldName.toLowerCase().includes('markdown') || fieldName.toLowerCase().includes('md')) {
|
|
366
|
+
testData[fieldName] = fieldSpec.default || '# Test Validation\n\nAuto-generated test content.';
|
|
367
|
+
} else {
|
|
368
|
+
testData[fieldName] = fieldSpec.default || 'Test content for validation';
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
371
|
+
case 'file':
|
|
372
|
+
// For file types, generate a placeholder - actual file handling depends on implementation
|
|
373
|
+
testData[fieldName] = fieldSpec.default || 'minio://test/validation/placeholder.txt';
|
|
374
|
+
break;
|
|
359
375
|
default:
|
|
360
376
|
testData[fieldName] = null;
|
|
361
377
|
}
|