@onlineapps/conn-orch-validator 3.3.2 → 4.0.1

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.
@@ -1,326 +0,0 @@
1
- /**
2
- * Create Pre-Validation (Tier 1) Process Tests
3
- *
4
- * Generic test suite that validates Tier 1 pre-validation process.
5
- * Works for ALL business services - no service-specific code needed.
6
- *
7
- * @module helpers/createPreValidationTests
8
- *
9
- * Purpose:
10
- * - Validates cookbook tests execution
11
- * - Validates ValidationProof generation
12
- * - Validates proof integrity
13
- * - Tests with MOCKED infrastructure (offline)
14
- *
15
- * Part of Two-Tier Validation System (Tier 1: Pre-Validation)
16
- * See: /docs/architecture/validator.md
17
- *
18
- * Usage:
19
- * const { createPreValidationTests } = require('@onlineapps/conn-orch-validator');
20
- * createPreValidationTests(__dirname); // Pass tests/integration directory
21
- *
22
- * Related:
23
- * - /docs/architecture/validator.md - Two-tier validation system
24
- * - /docs/standards/TESTING.md - Testing standards
25
- * - /tests/TESTING.md - SPOT principles
26
- */
27
-
28
- 'use strict';
29
-
30
- const path = require('path');
31
- const fs = require('fs');
32
- const { execSync } = require('child_process');
33
- const { ValidationProofCodec } = require('@onlineapps/service-validator-core');
34
- const { ServiceStructureValidator } = require('../validators/ServiceStructureValidator');
35
-
36
- /**
37
- * Create pre-validation (Tier 1) test suite
38
- *
39
- * @param {string} testsDir - Path to tests/integration directory (use __dirname)
40
- * @param {Object} [options] - Optional configuration
41
- * @param {number} [options.timeout=60000] - Test timeout in ms
42
- *
43
- * @example
44
- * // In services/my-service/tests/integration/pre-validation-process.test.js
45
- * const { createPreValidationTests } = require('@onlineapps/conn-orch-validator');
46
- *
47
- * createPreValidationTests(__dirname);
48
- */
49
- function createPreValidationTests(testsDir, options = {}) {
50
- // Calculate service root (2 levels up from tests/integration/)
51
- const serviceRoot = path.resolve(testsDir, '../..');
52
-
53
- const {
54
- timeout = 60000
55
- } = options;
56
-
57
- // Validate service structure FIRST
58
- console.log('\n🔍 Validating service structure for pre-validation...\n');
59
- const structureValidator = new ServiceStructureValidator(serviceRoot);
60
- const structureResult = structureValidator.validate();
61
-
62
- // Log validation result
63
- console.log(ServiceStructureValidator.formatResult(structureResult));
64
-
65
- // FAIL FAST if structure is invalid
66
- if (!structureResult.valid) {
67
- throw new Error(
68
- `Service structure validation failed. Fix errors above before running pre-validation tests.`
69
- );
70
- }
71
-
72
- // Load configuration — prefer config/service/, fall back to conn-config/
73
- const resolveConfig = (filename) => {
74
- const newPath = path.join(serviceRoot, 'config', 'service', filename);
75
- const legacyPath = path.join(serviceRoot, 'conn-config', filename);
76
- return fs.existsSync(newPath) ? newPath : legacyPath;
77
- };
78
- const configPath = resolveConfig('config.json');
79
- const operationsPath = resolveConfig('operations.json');
80
- const proofPath = path.join(serviceRoot, '.validation-proof.json');
81
-
82
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
83
- const operations = JSON.parse(fs.readFileSync(operationsPath, 'utf-8'));
84
-
85
- const serviceName = config.service.name;
86
-
87
- // Create test suite
88
- describe(`${serviceName} Pre-Validation (Tier 1) Process @integration`, () => {
89
- afterEach(() => {
90
- // Cleanup validation proof after each test
91
- if (fs.existsSync(proofPath)) {
92
- fs.unlinkSync(proofPath);
93
- }
94
- });
95
-
96
- describe('1. Pre-requisites Check', () => {
97
- test('service has tests/cookbooks directory', () => {
98
- const cookbooksDir = path.join(serviceRoot, 'tests/cookbooks');
99
- expect(fs.existsSync(cookbooksDir)).toBe(true);
100
-
101
- const cookbookFiles = fs.readdirSync(cookbooksDir).filter(f => f.endsWith('.json'));
102
- expect(cookbookFiles.length).toBeGreaterThan(0);
103
-
104
- console.log(`\n✓ Found ${cookbookFiles.length} cookbook test(s)\n`);
105
- });
106
-
107
- test('service has operations.json', () => {
108
- expect(fs.existsSync(operationsPath)).toBe(true);
109
-
110
- expect(operations.operations).toBeDefined();
111
- expect(Object.keys(operations.operations).length).toBeGreaterThan(0);
112
-
113
- console.log(`\n✓ Found ${Object.keys(operations.operations).length} operation(s)\n`);
114
- });
115
-
116
- test('service has pre-validation script', () => {
117
- const packageJson = JSON.parse(
118
- fs.readFileSync(path.join(serviceRoot, 'package.json'), 'utf-8')
119
- );
120
-
121
- const hasScript = packageJson.scripts['test:cookbooks'] ||
122
- fs.existsSync(path.join(serviceRoot, 'scripts/run-pre-validation.js'));
123
-
124
- expect(hasScript).toBeTruthy();
125
-
126
- console.log('\n✓ Pre-validation script configured\n');
127
- });
128
- });
129
-
130
- describe('2. Cookbook Test Execution', () => {
131
- test('runs cookbook tests successfully', () => {
132
- console.log('\n🧪 Running cookbook tests...\n');
133
-
134
- try {
135
- const output = execSync('npm run test:cookbooks', {
136
- cwd: serviceRoot,
137
- encoding: 'utf-8',
138
- stdio: 'pipe'
139
- });
140
-
141
- console.log(output);
142
-
143
- expect(output).toContain('Pre-Validation Started');
144
- expect(output).toContain('Passed:');
145
- expect(output).not.toContain('Failed: 1');
146
-
147
- console.log('\n✅ Cookbook tests PASSED\n');
148
- } catch (error) {
149
- console.error('\n❌ Cookbook tests FAILED:\n');
150
- console.error(error.stdout || error.message);
151
- throw error;
152
- }
153
- }, timeout);
154
-
155
- test('mocks infrastructure during tests', () => {
156
- const runPreValidationPath = path.join(serviceRoot, 'scripts/run-pre-validation.js');
157
-
158
- if (fs.existsSync(runPreValidationPath)) {
159
- const scriptContent = fs.readFileSync(runPreValidationPath, 'utf-8');
160
- expect(scriptContent).toContain('mockInfrastructure: true');
161
-
162
- console.log('\n✓ Infrastructure mocking confirmed\n');
163
- } else {
164
- console.log('\n⚠ No run-pre-validation.js script found (using npm script)\n');
165
- }
166
- });
167
- });
168
-
169
- describe('3. ValidationProof Generation', () => {
170
- beforeEach(() => {
171
- // Run pre-validation to generate proof
172
- console.log('\n🔐 Generating validation proof...\n');
173
- execSync('npm run test:cookbooks', {
174
- cwd: serviceRoot,
175
- stdio: 'pipe'
176
- });
177
- });
178
-
179
- test('creates .validation-proof.json file', () => {
180
- expect(fs.existsSync(proofPath)).toBe(true);
181
- console.log('\n✓ Validation proof file created\n');
182
- });
183
-
184
- test('proof has correct structure', () => {
185
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
186
-
187
- // Required fields
188
- expect(proof.validationProof).toBeDefined();
189
- expect(proof.validationData).toBeDefined();
190
-
191
- // ValidationData structure
192
- const { validationData } = proof;
193
- expect(validationData.serviceName).toBe(serviceName);
194
- expect(validationData.version).toBeDefined();
195
- expect(validationData.validator).toBe('@onlineapps/conn-orch-validator');
196
- expect(validationData.validatorVersion).toBeDefined();
197
- expect(validationData.validatedAt).toBeDefined();
198
- expect(validationData.durationMs).toBeGreaterThan(0);
199
- expect(validationData.testsRun).toBeGreaterThan(0);
200
- expect(validationData.testsPassed).toBe(validationData.testsRun);
201
- expect(validationData.testsFailed).toBe(0);
202
-
203
- console.log('\n📋 Validation Proof Details:');
204
- console.log(` Service: ${validationData.serviceName} v${validationData.version}`);
205
- console.log(` Validator: ${validationData.validator} v${validationData.validatorVersion}`);
206
- console.log(` Tests: ${validationData.testsPassed}/${validationData.testsRun} passed`);
207
- console.log(` Duration: ${validationData.durationMs}ms`);
208
- console.log(` Validated: ${validationData.validatedAt}`);
209
- console.log('');
210
- });
211
-
212
- test('proof hash is valid SHA256', () => {
213
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
214
-
215
- // SHA256 = 64 hex characters
216
- expect(proof.validationProof).toMatch(/^[a-f0-9]{64}$/);
217
-
218
- console.log(`\n✓ Valid SHA256 hash: ${proof.validationProof.substring(0, 16)}...\n`);
219
- });
220
-
221
- test('all tests passed', () => {
222
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
223
-
224
- expect(proof.validationData.testsFailed).toBe(0);
225
- expect(proof.validationData.testsPassed).toBeGreaterThan(0);
226
- expect(proof.validationData.testsPassed).toBe(proof.validationData.testsRun);
227
-
228
- console.log(`\n✅ All ${proof.validationData.testsPassed} tests PASSED\n`);
229
- });
230
- });
231
-
232
- describe('4. Proof Integrity Verification', () => {
233
- beforeEach(() => {
234
- // Generate proof
235
- execSync('npm run test:cookbooks', {
236
- cwd: serviceRoot,
237
- stdio: 'pipe'
238
- });
239
- });
240
-
241
- test('ValidationProofCodec can decode proof', () => {
242
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
243
-
244
- const result = ValidationProofCodec.decode(proof);
245
-
246
- expect(result.valid).toBe(true);
247
- expect(result.reason).toBe('VALID');
248
- expect(result.details.serviceName).toBe(serviceName);
249
-
250
- console.log('\n✓ Proof successfully decoded and verified\n');
251
- });
252
-
253
- test('proof hash matches data', () => {
254
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
255
-
256
- // Re-encode to verify hash
257
- const reEncoded = ValidationProofCodec.encode(proof.validationData);
258
-
259
- expect(reEncoded.validationProof).toBe(proof.validationProof);
260
-
261
- console.log('\n✓ Proof hash integrity verified\n');
262
- });
263
-
264
- test('proof age is recent (< 7 days)', () => {
265
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
266
-
267
- const validatedAt = new Date(proof.validationData.validatedAt);
268
- const now = new Date();
269
- const ageMs = now - validatedAt;
270
- const ageDays = ageMs / (24 * 60 * 60 * 1000);
271
-
272
- expect(ageDays).toBeLessThan(7);
273
-
274
- console.log(`\n✓ Proof age: ${Math.round(ageMs / 1000)}s (recent)\n`);
275
- });
276
-
277
- test('tampered proof fails verification', () => {
278
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
279
-
280
- // Tamper with data
281
- proof.validationData.testsPassed = 999;
282
-
283
- const result = ValidationProofCodec.decode(proof);
284
-
285
- expect(result.valid).toBe(false);
286
- expect(result.reason).toBe('HASH_MISMATCH');
287
-
288
- console.log('\n✓ Tamper detection working correctly\n');
289
- });
290
- });
291
-
292
- describe('5. Dependencies Tracking', () => {
293
- beforeEach(() => {
294
- execSync('npm run test:cookbooks', {
295
- cwd: serviceRoot,
296
- stdio: 'pipe'
297
- });
298
- });
299
-
300
- test('proof includes service dependencies', () => {
301
- const proof = JSON.parse(fs.readFileSync(proofPath, 'utf-8'));
302
-
303
- expect(proof.validationData.dependencies).toBeDefined();
304
- expect(typeof proof.validationData.dependencies).toBe('object');
305
-
306
- // Should include key connectors
307
- const deps = proof.validationData.dependencies;
308
- const hasConnector = deps['@onlineapps/service-wrapper'] ||
309
- deps['@onlineapps/conn-orch-registry'] ||
310
- deps['@onlineapps/conn-orch-validator'];
311
-
312
- expect(hasConnector).toBeDefined();
313
-
314
- console.log('\n📦 Tracked Dependencies:');
315
- for (const [name, version] of Object.entries(deps)) {
316
- if (name.startsWith('@onlineapps/')) {
317
- console.log(` ${name}: ${version}`);
318
- }
319
- }
320
- console.log('');
321
- });
322
- });
323
- });
324
- }
325
-
326
- module.exports = { createPreValidationTests };
package/test-mq-flow.js DELETED
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * Simple test script to verify MQ message flow
6
- * Usage: node test-mq-flow.js
7
- */
8
-
9
- const amqp = require('amqplib');
10
-
11
- async function sendTestMessage() {
12
- const rabbitUrl = 'amqp://guest:guest@localhost:33023';
13
- const queueName = 'hello-service.workflow';
14
-
15
- try {
16
- // Connect to RabbitMQ
17
- const connection = await amqp.connect(rabbitUrl);
18
- const channel = await connection.createChannel();
19
-
20
- // Ensure queue exists
21
- await channel.assertQueue(queueName, { durable: true });
22
-
23
- // Create test message with cookbook
24
- const testMessage = {
25
- workflow_id: `test-${Date.now()}`,
26
- cookbook: {
27
- name: 'test-workflow',
28
- version: '1.0.0',
29
- steps: [
30
- {
31
- id: 'goodDay', // ID se použije jako operation name
32
- type: 'task',
33
- service: 'hello-service',
34
- input: {
35
- name: 'E2E Test'
36
- }
37
- }
38
- ]
39
- },
40
- current_step: 'step1',
41
- step_index: 0,
42
- context: {}
43
- };
44
-
45
- console.log('Sending test message:', JSON.stringify(testMessage, null, 2));
46
-
47
- // Send message
48
- channel.sendToQueue(
49
- queueName,
50
- Buffer.from(JSON.stringify(testMessage)),
51
- { persistent: true }
52
- );
53
-
54
- console.log(`Message sent to queue: ${queueName}`);
55
-
56
- // Wait a bit to ensure message is sent
57
- await new Promise(resolve => setTimeout(resolve, 1000));
58
-
59
- // Clean up
60
- await channel.close();
61
- await connection.close();
62
-
63
- console.log('Test completed successfully');
64
-
65
- } catch (error) {
66
- console.error('Test failed:', error.message);
67
- process.exit(1);
68
- }
69
- }
70
-
71
- // Run the test
72
- sendTestMessage();
@@ -1,95 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * Quick test of ValidationOrchestrator
6
- *
7
- * Usage: node test-orchestrator.js <serviceRoot>
8
- * Example: node test-orchestrator.js ../../../services/hello-service
9
- *
10
- * Loads service configuration from conn-config/config.json
11
- */
12
-
13
- const fs = require('fs');
14
- const path = require('path');
15
- const ValidationOrchestrator = require('./src/ValidationOrchestrator');
16
-
17
- async function test() {
18
- // Get service root from CLI or default to hello-service
19
- const serviceRoot = process.argv[2] || path.resolve(__dirname, '../../../services/hello-service');
20
-
21
- if (!fs.existsSync(serviceRoot)) {
22
- console.error(`❌ Service root not found: ${serviceRoot}`);
23
- console.error('Usage: node test-orchestrator.js <serviceRoot>');
24
- process.exit(1);
25
- }
26
-
27
- // Load service configuration
28
- const configPath = path.join(serviceRoot, 'conn-config', 'config.json');
29
- if (!fs.existsSync(configPath)) {
30
- console.error(`❌ Config not found: ${configPath}`);
31
- console.error('Service must have conn-config/config.json');
32
- process.exit(1);
33
- }
34
-
35
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
36
- const serviceName = config.service?.name;
37
- const serviceVersion = config.service?.version;
38
-
39
- if (!serviceName || !serviceVersion) {
40
- console.error('❌ Config must contain service.name and service.version');
41
- process.exit(1);
42
- }
43
-
44
- console.log(`🧪 Testing ValidationOrchestrator`);
45
- console.log(` Service: ${serviceName} v${serviceVersion}`);
46
- console.log(` Root: ${serviceRoot}\n`);
47
-
48
- const orchestrator = new ValidationOrchestrator({
49
- serviceRoot,
50
- serviceName,
51
- serviceVersion,
52
- logger: console
53
- });
54
-
55
- try {
56
- const result = await orchestrator.validate();
57
-
58
- console.log('\n📊 Validation Results:');
59
- console.log('Success:', result.success);
60
- console.log('Duration:', result.durationMs, 'ms');
61
-
62
- if (result.skipped) {
63
- console.log('✓ Used existing proof (validation skipped)');
64
- console.log('Fingerprint:', result.proof?.fingerprint);
65
- } else {
66
- console.log('Tests run:', result.totalTests);
67
- console.log('Tests passed:', result.passedTests);
68
- console.log('Tests failed:', result.failedTests);
69
-
70
- if (result.errors && result.errors.length > 0) {
71
- console.log('\n❌ Errors:');
72
- result.errors.forEach(err => console.log(' -', err));
73
- }
74
-
75
- if (result.warnings && result.warnings.length > 0) {
76
- console.log('\n⚠️ Warnings:');
77
- result.warnings.forEach(warn => console.log(' -', warn));
78
- }
79
-
80
- if (result.proof) {
81
- console.log('\n✅ Proof generated:');
82
- console.log(' Fingerprint:', result.fingerprint);
83
- console.log(' Location: conn-runtime/validation-proof.json');
84
- }
85
- }
86
-
87
- process.exit(result.success ? 0 : 1);
88
- } catch (error) {
89
- console.error('\n❌ Test failed:', error.message);
90
- console.error(error.stack);
91
- process.exit(1);
92
- }
93
- }
94
-
95
- test();