@onlineapps/conn-orch-validator 2.0.14 → 2.0.16
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 +2 -1
- package/src/ServiceValidator.js +9 -1
- package/src/TestOrchestrator.js +7 -4
- package/src/ValidationOrchestrator.js +3 -1
- package/src/config.js +29 -0
- package/src/defaults.js +11 -0
- package/src/mocks/MockMQClient.js +30 -2
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.16",
|
|
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": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"license": "PROPRIETARY",
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@onlineapps/service-validator-core": "^1.0.4",
|
|
25
|
+
"@onlineapps/runtime-config": "1.0.2",
|
|
25
26
|
"ajv": "^8.12.0",
|
|
26
27
|
"ajv-formats": "^2.1.1",
|
|
27
28
|
"amqplib": "^0.10.9",
|
package/src/ServiceValidator.js
CHANGED
|
@@ -184,13 +184,21 @@ class ServiceValidator {
|
|
|
184
184
|
case 'object':
|
|
185
185
|
const obj = {};
|
|
186
186
|
if (schema.properties) {
|
|
187
|
-
Object.entries(schema.properties)
|
|
187
|
+
const entries = Object.entries(schema.properties);
|
|
188
|
+
entries.forEach(([key, prop]) => {
|
|
188
189
|
if (schema.required && schema.required.includes(key)) {
|
|
189
190
|
obj[key] = this.generateTestValue(prop);
|
|
190
191
|
} else if (Math.random() > 0.5) {
|
|
191
192
|
obj[key] = this.generateTestValue(prop);
|
|
192
193
|
}
|
|
193
194
|
});
|
|
195
|
+
|
|
196
|
+
// If schema has properties but nothing was picked (e.g., no required fields and randomness skipped),
|
|
197
|
+
// pick the first property to keep requests deterministic and non-empty.
|
|
198
|
+
if (Object.keys(obj).length === 0 && entries.length > 0) {
|
|
199
|
+
const [firstKey, firstSchema] = entries[0];
|
|
200
|
+
obj[firstKey] = this.generateTestValue(firstSchema);
|
|
201
|
+
}
|
|
194
202
|
}
|
|
195
203
|
return obj;
|
|
196
204
|
|
package/src/TestOrchestrator.js
CHANGED
|
@@ -4,6 +4,7 @@ const ServiceValidator = require('./ServiceValidator');
|
|
|
4
4
|
const WorkflowTestRunner = require('./WorkflowTestRunner');
|
|
5
5
|
const ServiceTestHarness = require('./ServiceTestHarness');
|
|
6
6
|
const ServiceReadinessValidator = require('./ServiceReadinessValidator');
|
|
7
|
+
const runtimeCfg = require('./config');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* TestOrchestrator - Three-tier testing strategy
|
|
@@ -17,6 +18,7 @@ class TestOrchestrator {
|
|
|
17
18
|
this.serviceName = options.serviceName;
|
|
18
19
|
this.openApiSpec = options.openApiSpec;
|
|
19
20
|
this.logger = options.logger || console;
|
|
21
|
+
this.integrationConfig = options.integrationConfig || {};
|
|
20
22
|
|
|
21
23
|
// Test configuration
|
|
22
24
|
this.testLevels = {
|
|
@@ -628,11 +630,12 @@ class TestOrchestrator {
|
|
|
628
630
|
|
|
629
631
|
getIntegrationTestConfig() {
|
|
630
632
|
// Get configuration for integration tests
|
|
633
|
+
const resolved = runtimeCfg.resolve(this.integrationConfig);
|
|
631
634
|
return {
|
|
632
|
-
serviceUrl:
|
|
633
|
-
mqUrl:
|
|
634
|
-
registryUrl:
|
|
635
|
-
storageUrl:
|
|
635
|
+
serviceUrl: resolved.serviceUrl,
|
|
636
|
+
mqUrl: resolved.mqUrl,
|
|
637
|
+
registryUrl: resolved.registryUrl,
|
|
638
|
+
storageUrl: resolved.storageUrl,
|
|
636
639
|
registry: null, // Would be real registry instance
|
|
637
640
|
mqClient: null // Would be real MQ client instance
|
|
638
641
|
};
|
|
@@ -117,7 +117,9 @@ class ValidationOrchestrator {
|
|
|
117
117
|
|
|
118
118
|
return true;
|
|
119
119
|
} catch (error) {
|
|
120
|
-
|
|
120
|
+
if (this.logger && typeof this.logger.error === 'function') {
|
|
121
|
+
this.logger.error(`[ValidationOrchestrator] Proof validation error: ${error.message}`);
|
|
122
|
+
}
|
|
121
123
|
return false;
|
|
122
124
|
}
|
|
123
125
|
}
|
package/src/config.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runtime configuration schema for @onlineapps/conn-orch-validator.
|
|
5
|
+
*
|
|
6
|
+
* Uses @onlineapps/runtime-config for unified priority:
|
|
7
|
+
* 1. Explicit config (passed to TestOrchestrator options)
|
|
8
|
+
* 2. Environment variable
|
|
9
|
+
* 3. Module-owned defaults (none for topology)
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT: Integration test topology is FAIL-FAST (no defaults).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const { createRuntimeConfig } = require('@onlineapps/runtime-config');
|
|
15
|
+
const DEFAULTS = require('./defaults');
|
|
16
|
+
|
|
17
|
+
const runtimeCfg = createRuntimeConfig({
|
|
18
|
+
defaults: DEFAULTS,
|
|
19
|
+
schema: {
|
|
20
|
+
serviceUrl: { env: 'TEST_SERVICE_URL', required: true },
|
|
21
|
+
mqUrl: { env: 'TEST_MQ_URL', required: true },
|
|
22
|
+
registryUrl: { env: 'TEST_REGISTRY_URL', required: true },
|
|
23
|
+
storageUrl: { env: 'TEST_STORAGE_URL', required: true },
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
module.exports = runtimeCfg;
|
|
28
|
+
|
|
29
|
+
|
package/src/defaults.js
ADDED
|
@@ -53,6 +53,33 @@ class MockMQClient {
|
|
|
53
53
|
this.queues[queue].push(messageWrapper);
|
|
54
54
|
this.publishedMessages.push({ queue, message, options, timestamp: Date.now() });
|
|
55
55
|
|
|
56
|
+
// Auto-reply simulation for workflow task requests:
|
|
57
|
+
// When a task is published to service.*.request, publish a deterministic response
|
|
58
|
+
// to workflow.<workflow_id>.response so WorkflowTestRunner unit tests can run
|
|
59
|
+
// end-to-end with mocked MQ.
|
|
60
|
+
if (
|
|
61
|
+
typeof queue === 'string' &&
|
|
62
|
+
queue.startsWith('service.') &&
|
|
63
|
+
queue.endsWith('.request') &&
|
|
64
|
+
message &&
|
|
65
|
+
typeof message === 'object' &&
|
|
66
|
+
message.workflow_id &&
|
|
67
|
+
message.step_id
|
|
68
|
+
) {
|
|
69
|
+
const responseQueue = `workflow.${message.workflow_id}.response`;
|
|
70
|
+
const response = {
|
|
71
|
+
step_id: message.step_id,
|
|
72
|
+
result: {
|
|
73
|
+
processed: true,
|
|
74
|
+
operation: message.operation,
|
|
75
|
+
input: message.input,
|
|
76
|
+
output: { mocked: true }
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Enqueue response (does not recurse into auto-reply because queue prefix differs)
|
|
80
|
+
await this.publish(responseQueue, response);
|
|
81
|
+
}
|
|
82
|
+
|
|
56
83
|
// Trigger consumers if any
|
|
57
84
|
if (this.consumers[queue]) {
|
|
58
85
|
const consumer = this.consumers[queue];
|
|
@@ -114,9 +141,10 @@ class MockMQClient {
|
|
|
114
141
|
|
|
115
142
|
if (requeue && message.fields) {
|
|
116
143
|
const queue = message.fields.routingKey;
|
|
117
|
-
if (this.queues[queue]) {
|
|
118
|
-
this.queues[queue]
|
|
144
|
+
if (!this.queues[queue]) {
|
|
145
|
+
this.queues[queue] = [];
|
|
119
146
|
}
|
|
147
|
+
this.queues[queue].push(message);
|
|
120
148
|
}
|
|
121
149
|
|
|
122
150
|
return Promise.resolve();
|