@onlineapps/conn-orch-validator 2.0.6 → 2.0.9

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.
Files changed (36) hide show
  1. package/README.md +30 -1
  2. package/TESTING_STRATEGY.md +0 -0
  3. package/docs/DESIGN.md +0 -0
  4. package/examples/service-wrapper-usage.js +0 -0
  5. package/examples/three-tier-testing.js +0 -0
  6. package/jest.config.js +0 -0
  7. package/onlineapps-conn-e2e-testing-1.0.0.tgz +0 -0
  8. package/package.json +1 -1
  9. package/src/CookbookTestRunner.js +4 -4
  10. package/src/CookbookTestUtils.js +0 -0
  11. package/src/ServiceReadinessValidator.js +0 -0
  12. package/src/ServiceTestHarness.js +0 -0
  13. package/src/ServiceValidator.js +0 -0
  14. package/src/TestOrchestrator.js +0 -0
  15. package/src/ValidationOrchestrator.js +29 -22
  16. package/src/WorkflowTestRunner.js +0 -0
  17. package/src/helpers/README.md +0 -0
  18. package/src/helpers/createPreValidationTests.js +0 -0
  19. package/src/helpers/createServiceReadinessTests.js +0 -0
  20. package/src/index.js +0 -0
  21. package/src/mocks/MockMQClient.js +0 -0
  22. package/src/mocks/MockRegistry.js +0 -0
  23. package/src/mocks/MockStorage.js +0 -0
  24. package/src/validators/ServiceStructureValidator.js +0 -0
  25. package/src/validators/ValidationProofGenerator.js +0 -0
  26. package/test-mq-flow.js +0 -0
  27. package/tests/component/testing-framework-integration.test.js +0 -313
  28. package/tests/integration/ServiceReadiness.test.js +0 -265
  29. package/tests/monitoring-e2e.test.js +0 -315
  30. package/tests/run-example.js +0 -257
  31. package/tests/unit/CookbookTestRunner.test.js +0 -353
  32. package/tests/unit/MockMQClient.test.js +0 -190
  33. package/tests/unit/MockRegistry.test.js +0 -233
  34. package/tests/unit/MockStorage.test.js +0 -257
  35. package/tests/unit/ServiceValidator.test.js +0 -429
  36. package/tests/unit/WorkflowTestRunner.test.js +0 -546
@@ -1,257 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Simple test runner to demonstrate connector-testing functionality
5
- */
6
-
7
- const { TestOrchestrator, ServiceTestHarness, ServiceReadinessValidator } = require('../src');
8
- const express = require('express');
9
- const path = require('path');
10
-
11
- // Create a minimal test service
12
- function createTestService() {
13
- const app = express();
14
- app.use(express.json());
15
-
16
- app.get('/health', (req, res) => {
17
- res.json({
18
- status: 'healthy',
19
- service: 'test-service',
20
- timestamp: new Date().toISOString()
21
- });
22
- });
23
-
24
- app.get('/good-day', (req, res) => {
25
- const name = req.query.name || 'World';
26
- res.json({
27
- message: `Good day, ${name}!`,
28
- timestamp: new Date().toISOString()
29
- });
30
- });
31
-
32
- app.post('/process', (req, res) => {
33
- res.json({
34
- processed: true,
35
- input: req.body,
36
- output: { transformed: true }
37
- });
38
- });
39
-
40
- return app;
41
- }
42
-
43
- // Create OpenAPI spec
44
- function createOpenApiSpec() {
45
- return {
46
- openapi: '3.0.0',
47
- info: {
48
- title: 'Test Service',
49
- version: '1.0.0',
50
- description: 'Service for testing connector-testing'
51
- },
52
- paths: {
53
- '/health': {
54
- get: {
55
- operationId: 'healthCheck',
56
- summary: 'Health check endpoint',
57
- responses: {
58
- '200': {
59
- description: 'Service is healthy',
60
- content: {
61
- 'application/json': {
62
- schema: {
63
- type: 'object',
64
- properties: {
65
- status: { type: 'string' },
66
- service: { type: 'string' },
67
- timestamp: { type: 'string' }
68
- }
69
- }
70
- }
71
- }
72
- }
73
- }
74
- }
75
- },
76
- '/good-day': {
77
- get: {
78
- operationId: 'goodDay',
79
- summary: 'Greeting endpoint',
80
- parameters: [
81
- {
82
- name: 'name',
83
- in: 'query',
84
- required: false,
85
- schema: { type: 'string' }
86
- }
87
- ],
88
- responses: {
89
- '200': {
90
- description: 'Greeting response',
91
- content: {
92
- 'application/json': {
93
- schema: {
94
- type: 'object',
95
- properties: {
96
- message: { type: 'string' },
97
- timestamp: { type: 'string' }
98
- }
99
- }
100
- }
101
- }
102
- }
103
- }
104
- }
105
- },
106
- '/process': {
107
- post: {
108
- operationId: 'processData',
109
- summary: 'Process data',
110
- requestBody: {
111
- content: {
112
- 'application/json': {
113
- schema: {
114
- type: 'object'
115
- }
116
- }
117
- }
118
- },
119
- responses: {
120
- '200': {
121
- description: 'Processing result',
122
- content: {
123
- 'application/json': {
124
- schema: {
125
- type: 'object',
126
- properties: {
127
- processed: { type: 'boolean' },
128
- input: { type: 'object' },
129
- output: { type: 'object' }
130
- }
131
- }
132
- }
133
- }
134
- }
135
- }
136
- }
137
- }
138
- }
139
- };
140
- }
141
-
142
- async function runTests() {
143
- console.log('=== Connector-Testing Demo ===\n');
144
-
145
- const app = createTestService();
146
- const openApiSpec = createOpenApiSpec();
147
-
148
- // Test 1: Service Test Harness
149
- console.log('1. Testing with ServiceTestHarness (with mocks)...\n');
150
-
151
- const harness = new ServiceTestHarness({
152
- service: app,
153
- serviceName: 'test-service',
154
- openApiSpec,
155
- mockInfrastructure: true
156
- });
157
-
158
- await harness.start();
159
- console.log(` ✓ Service started at: ${harness.baseUrl}`);
160
-
161
- // Test API calls
162
- const healthResponse = await harness.callApi('GET', '/health');
163
- console.log(` ✓ Health check: ${healthResponse.status}`);
164
-
165
- const greetingResponse = await harness.callApi('GET', '/good-day', null, {});
166
- console.log(` ✓ Greeting: ${greetingResponse.message}`);
167
-
168
- // Test workflow simulation
169
- const workflow = await harness.simulateWorkflow({
170
- steps: [
171
- {
172
- id: 'step1',
173
- type: 'task',
174
- service: 'test-service',
175
- operation: 'healthCheck'
176
- },
177
- {
178
- id: 'step2',
179
- type: 'task',
180
- service: 'test-service',
181
- operation: 'processData',
182
- input: { test: 'data' }
183
- }
184
- ]
185
- });
186
- console.log(` ✓ Workflow completed: ${workflow.completed}`);
187
-
188
- // Check mock infrastructure
189
- const messages = harness.getPublishedMessages();
190
- console.log(` ✓ Messages published: ${messages.length}`);
191
-
192
- const registration = harness.getServiceRegistration();
193
- console.log(` ✓ Service registered: ${registration.name}`);
194
-
195
- await harness.stop();
196
- console.log(' ✓ Harness stopped\n');
197
-
198
- // Test 2: Service Readiness Validator
199
- console.log('2. Testing with ServiceReadinessValidator...\n');
200
-
201
- // Start service for validation
202
- const server = app.listen(4444);
203
-
204
- const validator = new ServiceReadinessValidator();
205
- const readiness = await validator.validateReadiness({
206
- name: 'test-service',
207
- url: 'http://localhost:4444',
208
- openApiSpec,
209
- healthEndpoint: '/health'
210
- });
211
-
212
- console.log(` ✓ Readiness score: ${readiness.score}/${readiness.maxScore}`);
213
- console.log(` ✓ Service ready: ${readiness.ready}`);
214
- console.log(` ✓ Recommendation: ${readiness.recommendation}`);
215
-
216
- // Show check results
217
- console.log('\n Check results:');
218
- for (const [name, check] of Object.entries(readiness.checks)) {
219
- const status = check.passed ? '✓' : '✗';
220
- console.log(` ${status} ${name}: ${check.passed ? 'Passed' : 'Failed'}`);
221
- }
222
-
223
- server.close();
224
- console.log('\n ✓ Validator test completed\n');
225
-
226
- // Test 3: Test Orchestrator (Three-tier testing)
227
- console.log('3. Testing with TestOrchestrator (three-tier)...\n');
228
-
229
- const orchestrator = new TestOrchestrator({
230
- service: app,
231
- serviceName: 'test-service',
232
- openApiSpec
233
- });
234
-
235
- // Run only unit tests for speed
236
- console.log(' Running unit tests with full mocks...');
237
- const unitResults = await orchestrator.runUnitTests();
238
-
239
- console.log(` ✓ Unit tests passed: ${unitResults.passed}`);
240
- console.log(` ✓ Coverage: ${unitResults.coverage}%`);
241
- console.log(` ✓ Tests run: ${unitResults.tests.length}`);
242
-
243
- // Show individual test results
244
- console.log('\n Test results:');
245
- unitResults.tests.forEach(test => {
246
- const status = test.passed ? '✓' : '✗';
247
- console.log(` ${status} ${test.name}`);
248
- });
249
-
250
- console.log('\n=== All tests completed successfully! ===\n');
251
- }
252
-
253
- // Run the tests
254
- runTests().catch(error => {
255
- console.error('Test failed:', error);
256
- process.exit(1);
257
- });
@@ -1,353 +0,0 @@
1
- 'use strict';
2
-
3
- const CookbookTestRunner = require('../../src/CookbookTestRunner');
4
- const fs = require('fs');
5
- const path = require('path');
6
-
7
- describe('CookbookTestRunner @unit', () => {
8
- let runner;
9
- const testServicePath = path.join(__dirname, '../fixtures/test-service');
10
-
11
- beforeEach(() => {
12
- runner = new CookbookTestRunner({
13
- serviceName: 'test-service',
14
- serviceUrl: 'http://localhost:3000',
15
- servicePath: testServicePath,
16
- mockInfrastructure: true
17
- });
18
- });
19
-
20
- describe('constructor', () => {
21
- test('should initialize with default options', () => {
22
- const defaultRunner = new CookbookTestRunner({
23
- serviceName: 'test'
24
- });
25
-
26
- expect(defaultRunner.serviceName).toBe('test');
27
- expect(defaultRunner.serviceUrl).toBe('http://localhost:3000');
28
- expect(defaultRunner.mockInfrastructure).toBe(true);
29
- expect(defaultRunner.timeout).toBe(30000);
30
- });
31
-
32
- test('should accept custom options', () => {
33
- const customRunner = new CookbookTestRunner({
34
- serviceName: 'custom',
35
- serviceUrl: 'http://localhost:5000',
36
- mockInfrastructure: false,
37
- timeout: 60000
38
- });
39
-
40
- expect(customRunner.serviceName).toBe('custom');
41
- expect(customRunner.serviceUrl).toBe('http://localhost:5000');
42
- expect(customRunner.mockInfrastructure).toBe(false);
43
- expect(customRunner.timeout).toBe(60000);
44
- });
45
- });
46
-
47
- describe('validateCookbook()', () => {
48
- test('should validate valid cookbook', () => {
49
- const validCookbook = {
50
- version: '1.0.0',
51
- steps: [{
52
- id: 'test-1',
53
- service: 'test-service',
54
- operation: 'test-op',
55
- input: {}
56
- }]
57
- };
58
-
59
- expect(() => runner.validateCookbook(validCookbook)).not.toThrow();
60
- });
61
-
62
- test('should reject cookbook without steps', () => {
63
- const invalidCookbook = {
64
- version: '1.0.0'
65
- };
66
-
67
- expect(() => runner.validateCookbook(invalidCookbook))
68
- .toThrow('Cookbook must have steps array');
69
- });
70
-
71
- test('should reject cookbook with empty steps', () => {
72
- const invalidCookbook = {
73
- version: '1.0.0',
74
- steps: []
75
- };
76
-
77
- expect(() => runner.validateCookbook(invalidCookbook))
78
- .toThrow('Cookbook must have at least one step');
79
- });
80
-
81
- test('should reject step without service', () => {
82
- const invalidCookbook = {
83
- version: '1.0.0',
84
- steps: [{
85
- operation: 'test-op'
86
- }]
87
- };
88
-
89
- expect(() => runner.validateCookbook(invalidCookbook))
90
- .toThrow('Step must have service');
91
- });
92
-
93
- test('should reject step without operation', () => {
94
- const invalidCookbook = {
95
- version: '1.0.0',
96
- steps: [{
97
- service: 'test-service'
98
- }]
99
- };
100
-
101
- expect(() => runner.validateCookbook(invalidCookbook))
102
- .toThrow('Step must have operation');
103
- });
104
- });
105
-
106
- describe('hasExpectClauses()', () => {
107
- test('should detect cookbook with expect clauses', () => {
108
- const cookbook = {
109
- steps: [{
110
- service: 'test',
111
- operation: 'op',
112
- expect: { status: 'success' }
113
- }]
114
- };
115
-
116
- expect(runner.hasExpectClauses(cookbook)).toBe(true);
117
- });
118
-
119
- test('should detect cookbook without expect clauses', () => {
120
- const cookbook = {
121
- steps: [{
122
- service: 'test',
123
- operation: 'op'
124
- }]
125
- };
126
-
127
- expect(runner.hasExpectClauses(cookbook)).toBe(false);
128
- });
129
- });
130
-
131
- describe('validateOutput()', () => {
132
- test('should pass valid type check', () => {
133
- const expected = {
134
- message: { type: 'string' }
135
- };
136
-
137
- const actual = {
138
- message: 'Hello'
139
- };
140
-
141
- const errors = runner.validateOutput(expected, actual);
142
-
143
- expect(errors).toHaveLength(0);
144
- });
145
-
146
- test('should fail invalid type check', () => {
147
- const expected = {
148
- count: { type: 'number' }
149
- };
150
-
151
- const actual = {
152
- count: 'not a number'
153
- };
154
-
155
- const errors = runner.validateOutput(expected, actual);
156
-
157
- expect(errors.length).toBeGreaterThan(0);
158
- expect(errors[0]).toContain('expected type number');
159
- });
160
-
161
- test('should pass contains check', () => {
162
- const expected = {
163
- message: { contains: 'Hello' }
164
- };
165
-
166
- const actual = {
167
- message: 'Hello World'
168
- };
169
-
170
- const errors = runner.validateOutput(expected, actual);
171
-
172
- expect(errors).toHaveLength(0);
173
- });
174
-
175
- test('should fail contains check', () => {
176
- const expected = {
177
- message: { contains: 'Goodbye' }
178
- };
179
-
180
- const actual = {
181
- message: 'Hello World'
182
- };
183
-
184
- const errors = runner.validateOutput(expected, actual);
185
-
186
- expect(errors.length).toBeGreaterThan(0);
187
- expect(errors[0]).toContain('expected to contain');
188
- });
189
-
190
- test('should pass pattern check', () => {
191
- const expected = {
192
- timestamp: { pattern: '^\\d{4}-\\d{2}-\\d{2}T' }
193
- };
194
-
195
- const actual = {
196
- timestamp: '2025-09-30T12:00:00Z'
197
- };
198
-
199
- const errors = runner.validateOutput(expected, actual);
200
-
201
- expect(errors).toHaveLength(0);
202
- });
203
-
204
- test('should fail pattern check', () => {
205
- const expected = {
206
- code: { pattern: '^[A-Z]{3}$' }
207
- };
208
-
209
- const actual = {
210
- code: 'invalid'
211
- };
212
-
213
- const errors = runner.validateOutput(expected, actual);
214
-
215
- expect(errors.length).toBeGreaterThan(0);
216
- expect(errors[0]).toContain('does not match pattern');
217
- });
218
-
219
- test('should pass equals check', () => {
220
- const expected = {
221
- status: { equals: 'active' }
222
- };
223
-
224
- const actual = {
225
- status: 'active'
226
- };
227
-
228
- const errors = runner.validateOutput(expected, actual);
229
-
230
- expect(errors).toHaveLength(0);
231
- });
232
-
233
- test('should fail equals check', () => {
234
- const expected = {
235
- status: { equals: 'active' }
236
- };
237
-
238
- const actual = {
239
- status: 'inactive'
240
- };
241
-
242
- const errors = runner.validateOutput(expected, actual);
243
-
244
- expect(errors.length).toBeGreaterThan(0);
245
- expect(errors[0]).toContain('expected active');
246
- });
247
-
248
- test('should pass range check', () => {
249
- const expected = {
250
- count: { min: 0, max: 100 }
251
- };
252
-
253
- const actual = {
254
- count: 50
255
- };
256
-
257
- const errors = runner.validateOutput(expected, actual);
258
-
259
- expect(errors).toHaveLength(0);
260
- });
261
-
262
- test('should fail min check', () => {
263
- const expected = {
264
- count: { min: 10 }
265
- };
266
-
267
- const actual = {
268
- count: 5
269
- };
270
-
271
- const errors = runner.validateOutput(expected, actual);
272
-
273
- expect(errors.length).toBeGreaterThan(0);
274
- expect(errors[0]).toContain('less than min');
275
- });
276
-
277
- test('should fail max check', () => {
278
- const expected = {
279
- count: { max: 100 }
280
- };
281
-
282
- const actual = {
283
- count: 150
284
- };
285
-
286
- const errors = runner.validateOutput(expected, actual);
287
-
288
- expect(errors.length).toBeGreaterThan(0);
289
- expect(errors[0]).toContain('exceeds max');
290
- });
291
-
292
- test('should check field existence', () => {
293
- const expected = {
294
- optional: { exists: false },
295
- required: { exists: true }
296
- };
297
-
298
- const actual = {
299
- required: 'value'
300
- };
301
-
302
- const errors = runner.validateOutput(expected, actual);
303
-
304
- expect(errors).toHaveLength(0);
305
- });
306
-
307
- test('should detect missing required field', () => {
308
- const expected = {
309
- required: { exists: true }
310
- };
311
-
312
- const actual = {};
313
-
314
- const errors = runner.validateOutput(expected, actual);
315
-
316
- expect(errors.length).toBeGreaterThan(0);
317
- expect(errors[0]).toContain('expected to exist');
318
- });
319
- });
320
-
321
- describe('getResults()', () => {
322
- test('should return initialized results', () => {
323
- const results = runner.getResults();
324
-
325
- expect(results).toEqual({
326
- total: 0,
327
- passed: 0,
328
- failed: 0,
329
- duration: 0,
330
- steps: []
331
- });
332
- });
333
- });
334
-
335
- describe('resetResults()', () => {
336
- test('should reset results', () => {
337
- // Simulate some test runs
338
- runner.results.total = 5;
339
- runner.results.passed = 3;
340
- runner.results.failed = 2;
341
-
342
- runner.resetResults();
343
-
344
- expect(runner.results).toEqual({
345
- total: 0,
346
- passed: 0,
347
- failed: 0,
348
- duration: 0,
349
- steps: []
350
- });
351
- });
352
- });
353
- });