@rosen-bridge/config 0.4.0 → 1.1.0

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,1363 +0,0 @@
1
- import { configDir } from './configEnvSetup';
2
- import config from 'config';
3
- import fs from 'fs';
4
- import path from 'path';
5
- import { afterAll, beforeEach, describe, expect, it } from 'vitest';
6
- import { ConfigValidator } from '../lib';
7
- import { ConfigSchema } from '../lib/schema/types/fields';
8
- import * as testData from './configTestData';
9
-
10
- afterAll(() => {
11
- fs.rmSync(configDir, { force: true, recursive: true });
12
- });
13
-
14
- beforeEach(() => {
15
- fs.readdirSync(configDir).forEach((file) => {
16
- fs.unlinkSync(path.join(configDir, file));
17
- });
18
- fs.cpSync(path.join(__dirname, 'configTestFiles'), configDir, {
19
- recursive: true,
20
- });
21
- });
22
-
23
- describe('ConfigValidator', () => {
24
- describe('generateDefault', () => {
25
- /**
26
- * @target generateDefault should return default values object for the
27
- * passed schema
28
- * @dependencies
29
- * @scenario
30
- * - call generateDefault
31
- * - check if correct default value object is returned
32
- * @expected
33
- * - correct default value object should have been returned
34
- */
35
- it(`should return default values object for the passed schema`, async () => {
36
- const config = new ConfigValidator(
37
- <ConfigSchema>testData.apiSchemaDefaultValuePairSample.schema
38
- );
39
- expect(config.generateDefault()).toEqual(
40
- testData.apiSchemaDefaultValuePairSample.defaultVal
41
- );
42
- });
43
-
44
- /**
45
- * @target generateDefault({ validate: true }) should fail when defaults violate choices
46
- * @dependencies
47
- * @scenario
48
- * - define a primitive with choices and a wrong default
49
- * - define a nested array object where a field has choices and wrong default
50
- * - call generateDefault({ validate: true }) and expect failure
51
- * @expected
52
- * - generateDefault with validate should throw
53
- */
54
- it(`should fail validate=true when defaults violate choices (primitive and nested)`, async () => {
55
- const cv1 = new ConfigValidator(
56
- <ConfigSchema>testData.wrongChoiceDefaultSchema.schema
57
- );
58
- expect(() => cv1.generateDefault({ validate: true })).toThrow();
59
-
60
- const cv2 = new ConfigValidator(
61
- <ConfigSchema>testData.nestedWrongChoiceDefaultSchema.schema
62
- );
63
- expect(() => cv2.generateDefault({ validate: true })).toThrow();
64
- });
65
-
66
- /**
67
- * @target generateDefault should return default values for array fields with
68
- * string and number items
69
- * @dependencies
70
- * @scenario
71
- * - call generateDefault on schema with array fields
72
- * - check if correct default value object is returned
73
- * @expected
74
- * - correct default value object should have been returned including arrays
75
- */
76
- it(`should return default values for array fields with string and number items`, async () => {
77
- const config = new ConfigValidator(
78
- <ConfigSchema>testData.arraySchemaDefaultValuePairSample.schema
79
- );
80
- expect(config.generateDefault()).toEqual(
81
- testData.arraySchemaDefaultValuePairSample.defaultVal
82
- );
83
- });
84
-
85
- /**
86
- * @target generateDefault should handle empty array defaults
87
- * @dependencies
88
- * @scenario
89
- * - call generateDefault on schema with empty array default
90
- * - check if empty array is included in result
91
- * @expected
92
- * - empty array should be included in default values
93
- */
94
- it(`should handle empty array defaults`, async () => {
95
- const config = new ConfigValidator(
96
- <ConfigSchema>testData.emptyArrayDefaultsPair.schema
97
- );
98
- const result = config.generateDefault();
99
- expect(result).toEqual(testData.emptyArrayDefaultsPair.defaultVal);
100
- });
101
-
102
- /**
103
- * @target generateDefault should exclude arrays without default values
104
- * @dependencies
105
- * @scenario
106
- * - call generateDefault on schema with array field without default
107
- * - check if array field is excluded from result
108
- * @expected
109
- * - array field without default should be excluded from result
110
- */
111
- it(`should exclude arrays without default values`, async () => {
112
- const config = new ConfigValidator(
113
- <ConfigSchema>testData.arrayWithoutDefaultPair.schema
114
- );
115
- const result = config.generateDefault();
116
- expect(result).toEqual(testData.arrayWithoutDefaultPair.defaultVal);
117
- expect(result).not.toHaveProperty('arrayWithoutDefault');
118
- });
119
-
120
- /**
121
- * @target generateDefault should merge array of object item defaults with provided elements
122
- * @dependencies
123
- * @scenario
124
- * - define an array of object items with item-level defaults
125
- * - provide array default with elements that override some fields
126
- * - call generateDefault
127
- * @expected
128
- * - each element is merged with object item defaults
129
- */
130
- it(`should merge array of object item defaults with provided elements`, async () => {
131
- const config = new ConfigValidator(
132
- <ConfigSchema>testData.logsArraySchemaDefaultsPair.schema
133
- );
134
- const result = config.generateDefault();
135
- expect(result).toEqual(testData.logsArraySchemaDefaultsPair.defaultVal);
136
- });
137
-
138
- /**
139
- * @target generateDefault should not validate array item defaults; validateConfig should catch it
140
- * @dependencies
141
- * @scenario
142
- * - define an array of object items with validations (choices/required)
143
- * - provide an invalid array default (e.g., wrong choice and missing required)
144
- * - call generateDefault and ensure it returns merged defaults
145
- * - call validateConfig and ensure it throws
146
- * @expected
147
- * - generateDefault should succeed and return merged values
148
- * - validateConfig should throw due to schema violations in defaults
149
- */
150
- it(`should not validate array item defaults; validateConfig should catch it`, async () => {
151
- const confValidator = new ConfigValidator(
152
- <ConfigSchema>testData.invalidLogsArrayDefaultsPair.schema
153
- );
154
- const generated = confValidator.generateDefault();
155
- expect(generated).toEqual(
156
- testData.invalidLogsArrayDefaultsPair.defaultVal
157
- );
158
- expect(() => confValidator.validateConfig(generated)).toThrow();
159
- });
160
-
161
- /**
162
- * @target generateDefault with validate option should throw for invalid defaults
163
- * @dependencies
164
- * @scenario
165
- * - define invalid defaults (choices violation and missing required)
166
- * - call generateDefault({ validate: true })
167
- * @expected
168
- * - generation should throw due to validation
169
- */
170
- it(`should throw when generateDefault is called with validate option and defaults are invalid`, async () => {
171
- const confValidator = new ConfigValidator(
172
- <ConfigSchema>testData.invalidDefaultsValidateOptionSchema.schema
173
- );
174
- expect(() => confValidator.generateDefault({ validate: true })).toThrow();
175
- });
176
-
177
- /**
178
- * @target generateDefault should carry unknown keys in array item defaults; schema ignores them
179
- * @dependencies
180
- * @scenario
181
- * - define an array of object items with known keys (path, level)
182
- * - provide defaults containing an unknown key (pathsskddkfjd)
183
- * - call generateDefault and ensure unknown key is preserved alongside item defaults
184
- * - call validateConfig and ensure no error is thrown (unknown keys are ignored by schema)
185
- * @expected
186
- * - generateDefault returns merged defaults plus unknown key
187
- * - validateConfig does not throw
188
- */
189
- it(`should reject schema defaults with unknown keys at schema validation time`, async () => {
190
- expect(
191
- () =>
192
- new ConfigValidator(
193
- <ConfigSchema>testData.unknownKeyLogsArrayDefaultsPair.schema
194
- )
195
- ).toThrow('key is not found in the schema');
196
- });
197
-
198
- /**
199
- * @target generateDefault should handle nested array fields inside array item objects
200
- * @dependencies
201
- * @scenario
202
- * - define an array of objects; each object has a nested array field
203
- * - provide array default with and without the nested array specified
204
- * - call generateDefault
205
- * @expected
206
- * - item-level non-array defaults are merged
207
- * - nested array schema default is not merged by current implementation
208
- * - nested array provided in defaults is preserved
209
- */
210
- it(`should handle nested array field inside array item objects`, async () => {
211
- const confValidator = new ConfigValidator(
212
- <ConfigSchema>testData.nestedArrayInArrayDefaultsPair.schema
213
- );
214
- const result = confValidator.generateDefault();
215
- expect(result).toEqual(
216
- testData.nestedArrayInArrayDefaultsPair.defaultVal
217
- );
218
- });
219
-
220
- /**
221
- * @target generateDefault should omit required fields without defaults and validation should fail
222
- * @dependencies
223
- * @scenario
224
- * - define a required field without default
225
- * - call generateDefault and ensure the field is not present
226
- * - call validateConfig and ensure it throws due to missing required value
227
- * @expected
228
- * - defaults omit the field
229
- * - validation throws
230
- */
231
- it(`should omit required fields without defaults and fail validation`, async () => {
232
- const confValidator = new ConfigValidator(
233
- <ConfigSchema>testData.requiredWithoutDefaultSchema.schema
234
- );
235
- const defaults = confValidator.generateDefault();
236
- expect(defaults).toEqual({});
237
- expect(() => confValidator.validateConfig(defaults)).toThrow();
238
- expect(() => confValidator.generateDefault({ validate: true })).toThrow();
239
- });
240
- });
241
-
242
- describe('validateSchema', () => {
243
- /**
244
- * @target validateSchema should not throw any exceptions when a correct
245
- * schema is passed
246
- * @dependencies
247
- * @scenario
248
- * - create a new instance of Config which calls Config.validateSchema
249
- * - check if any exception is thrown
250
- * @expected
251
- * - no errors should be thrown
252
- */
253
- it(`should not throw any exceptions when a correct schema is passed`, async () => {
254
- expect(() => {
255
- new ConfigValidator(<ConfigSchema>testData.correctApiSchema);
256
- }).not.toThrow();
257
- });
258
-
259
- /**
260
- * @target validateSchema should throw exception when a schema with
261
- * incorrect default value type is passed
262
- * @dependencies
263
- * @scenario
264
- * - create a new instance of Config which calls Config.validateSchema
265
- * - check if any exception is thrown
266
- * @expected
267
- * - exception should be thrown
268
- */
269
- it(`should throw exception when a schema with incorrect default value type
270
- is passed`, async () => {
271
- expect(
272
- () =>
273
- new ConfigValidator(
274
- <ConfigSchema>testData.schemaWithIncorrectPortDefaultValueTypeSample
275
- )
276
- ).toThrow();
277
- });
278
-
279
- /**
280
- * @target validateSchema should throw exception when array type doesn't
281
- * have an item property
282
- * @dependencies
283
- * @scenario
284
- * - create a new instance of Config which calls Config.validateSchema
285
- * - check if any exception is thrown
286
- * @expected
287
- * - exception should be thrown
288
- */
289
- it(`should throw exception when array type doesn't have an item property`, async () => {
290
- expect(
291
- () =>
292
- new ConfigValidator(
293
- <ConfigSchema>testData.arrayTypeSchemaWithoutItems
294
- )
295
- ).toThrow();
296
- });
297
-
298
- /**
299
- * @target validateSchema should throw exception when object type doesn't
300
- * have a children property
301
- * @dependencies
302
- * @scenario
303
- * - create a new instance of Config which calls Config.validateSchema
304
- * - check if any exception is thrown
305
- * @expected
306
- * - exception should be thrown
307
- */
308
- it(`should throw exception when object type doesn't have a children property`, async () => {
309
- expect(
310
- () =>
311
- new ConfigValidator(
312
- <ConfigSchema>testData.objectTypeSchemaWithoutChildren
313
- )
314
- ).toThrow();
315
- });
316
-
317
- /**
318
- * @target validateSchema should pass when array primitive defaults match items type
319
- * @dependencies
320
- * @scenario
321
- * - construct ConfigValidator with a valid array primitive default
322
- * @expected
323
- * - no error thrown
324
- */
325
- it(`should pass when array primitive defaults match items type`, async () => {
326
- expect(() => {
327
- new ConfigValidator(
328
- <ConfigSchema>testData.arrayPrimitiveDefaultsValid.schema
329
- );
330
- }).not.toThrow();
331
- });
332
-
333
- /**
334
- * @target validateSchema should fail when array primitive defaults mismatch items type
335
- * @dependencies
336
- * @scenario
337
- * - construct ConfigValidator with an invalid array primitive default
338
- * @expected
339
- * - error thrown
340
- */
341
- it(`should fail when array primitive defaults mismatch items type`, async () => {
342
- expect(
343
- () =>
344
- new ConfigValidator(
345
- <ConfigSchema>testData.arrayPrimitiveDefaultsInvalid.schema
346
- )
347
- ).toThrow();
348
- });
349
-
350
- /**
351
- * @target validateSchema should fail when array object defaults have invalid child types
352
- * @dependencies
353
- * @scenario
354
- * - construct ConfigValidator with an invalid array object default
355
- * @expected
356
- * - error thrown
357
- */
358
- it(`should fail when array object defaults have invalid child types`, async () => {
359
- expect(
360
- () =>
361
- new ConfigValidator(
362
- <ConfigSchema>testData.arrayObjectDefaultsInvalidChildType.schema
363
- )
364
- ).toThrow();
365
- });
366
-
367
- /**
368
- * @target validateSchema should fail when nested array defaults have invalid element types
369
- * @dependencies
370
- * @scenario
371
- * - construct ConfigValidator with invalid nested array defaults
372
- * @expected
373
- * - error thrown
374
- */
375
- it(`should fail when nested array defaults have invalid element types`, async () => {
376
- expect(
377
- () =>
378
- new ConfigValidator(
379
- <ConfigSchema>testData.nestedArrayDefaultsInvalid.schema
380
- )
381
- ).toThrow();
382
- });
383
-
384
- /**
385
- * @target validateSchema should pass when nested array defaults are valid
386
- * @dependencies
387
- * @scenario
388
- * - construct ConfigValidator with valid nested array defaults
389
- * @expected
390
- * - no error thrown
391
- */
392
- it(`should pass when nested array defaults are valid`, async () => {
393
- expect(() => {
394
- new ConfigValidator(
395
- <ConfigSchema>testData.nestedArrayDefaultsValid.schema
396
- );
397
- }).not.toThrow();
398
- });
399
-
400
- /**
401
- * @target validateSchema should validate nested array of objects defaults (pass)
402
- * @dependencies
403
- * @scenario
404
- * - array of objects, with a key that is an array of objects with defaults
405
- * - construct ConfigValidator and then generate defaults to ensure merge works
406
- * @expected
407
- * - constructor succeeds
408
- * - defaults merged as expected
409
- */
410
- it(`should pass for nested array of objects defaults`, async () => {
411
- const cv = new ConfigValidator(
412
- <ConfigSchema>testData.nestedArrayOfObjectsDefaultsValid.schema
413
- );
414
- const defaults = cv.generateDefault();
415
- expect(defaults).toEqual(
416
- testData.nestedArrayOfObjectsDefaultsValid.defaultVal
417
- );
418
- });
419
-
420
- /**
421
- * @target validateSchema should validate nested array of objects defaults (fail)
422
- * @dependencies
423
- * @scenario
424
- * - array of objects, inner array default has invalid element shapes
425
- * @expected
426
- * - constructor throws
427
- */
428
- it(`should fail for nested array of objects defaults with invalid inner elements`, async () => {
429
- expect(
430
- () =>
431
- new ConfigValidator(
432
- <ConfigSchema>testData.nestedArrayOfObjectsDefaultsInvalid.schema
433
- )
434
- ).toThrow();
435
- });
436
- });
437
-
438
- describe('validateConfig', () => {
439
- /**
440
- * @target validateConfig should not throw any exceptions when a correct
441
- * config is passed
442
- * @dependencies
443
- * @scenario
444
- * - call validateConfig with the config
445
- * - check if any exception is thrown
446
- * @expected
447
- * - no errors should be thrown
448
- */
449
- it(`should not throw any exceptions when a correct config is passed`, async () => {
450
- const confValidator = new ConfigValidator(
451
- <ConfigSchema>testData.apiSchemaConfigPair.schema
452
- );
453
- confValidator.validateConfig(testData.apiSchemaConfigPair.config);
454
- });
455
-
456
- /**
457
- * @target validateConfig should throw exception when a config violating
458
- * choices constraint is passed
459
- * @dependencies
460
- * @scenario
461
- * - call validateConfig with the config
462
- * - check if any exception is thrown
463
- * @expected
464
- * - exception should be thrown
465
- */
466
- it(`should throw exception when a config violating choices constraint is
467
- passed`, async () => {
468
- const confValidator = new ConfigValidator(
469
- <ConfigSchema>testData.apiSchemaConfigPairWrongChoice.schema
470
- );
471
-
472
- expect(() =>
473
- confValidator.validateConfig(
474
- testData.apiSchemaConfigPairWrongChoice.config
475
- )
476
- ).toThrow();
477
- });
478
-
479
- /**
480
- * @target validateSchema should throw exception when a config violating
481
- * regex constraint is passed
482
- * @dependencies
483
- * @scenario
484
- * - call validateConfig with the config
485
- * - check if any exception is thrown
486
- * @expected
487
- * - exception should be thrown
488
- */
489
- it(`should throw exception when a config violating regex constraint is
490
- passed`, async () => {
491
- const confValidator = new ConfigValidator(
492
- <ConfigSchema>testData.apiSchemaConfigPairWrongRegex.schema
493
- );
494
-
495
- expect(() =>
496
- confValidator.validateConfig(
497
- testData.apiSchemaConfigPairWrongRegex.config
498
- )
499
- ).toThrow();
500
- });
501
-
502
- /**
503
- * @target validateSchema should throw exception when a config violating the
504
- * "required" constraint is passed
505
- * @dependencies
506
- * @scenario
507
- * - call validateConfig with the config
508
- * - check if any exception is thrown
509
- * @expected
510
- * - exception should be thrown
511
- */
512
- it(`should throw exception when a config violating the "required" constraint
513
- is passed`, async () => {
514
- const confValidator = new ConfigValidator(
515
- <ConfigSchema>testData.apiSchemaConfigPairWrongRequired.schema
516
- );
517
-
518
- expect(() =>
519
- confValidator.validateConfig(
520
- testData.apiSchemaConfigPairWrongRequired.config
521
- )
522
- ).toThrow();
523
- });
524
-
525
- /**
526
- * @target validateSchema should throw exception when a config violating the
527
- * value type is passed
528
- * @dependencies
529
- * @scenario
530
- * - call validateConfig with the config
531
- * - check if any exception is thrown
532
- * @expected
533
- * - exception should be thrown
534
- */
535
- it(`should throw exception when a config violating the value type is passed`, async () => {
536
- const confValidator = new ConfigValidator(
537
- <ConfigSchema>testData.apiSchemaConfigPairWrongPortType.schema
538
- );
539
-
540
- expect(() =>
541
- confValidator.validateConfig(
542
- testData.apiSchemaConfigPairWrongPortType.config
543
- )
544
- ).toThrow();
545
- });
546
-
547
- /**
548
- * @target validateSchema should throw exception when a config violating the
549
- * "greater than" constraint, is passed
550
- * @dependencies
551
- * @scenario
552
- * - call validateConfig with the config
553
- * - check if any exception is thrown
554
- * @expected
555
- * - exception should be thrown
556
- */
557
- it(`should throw exception when a config violating the "greater than"
558
- constraint, is passed`, async () => {
559
- const confValidator = new ConfigValidator(
560
- <ConfigSchema>testData.apiSchemaConfigPairWrongGreater.schema
561
- );
562
-
563
- expect(() =>
564
- confValidator.validateConfig(
565
- testData.apiSchemaConfigPairWrongGreater.config
566
- )
567
- ).toThrow();
568
- });
569
-
570
- /**
571
- * @target validateSchema should throw exception when a config violating the
572
- * "greater than or equal" constraint, is passed
573
- * @dependencies
574
- * @scenario
575
- * - call validateConfig with the config
576
- * - check if any exception is thrown
577
- * @expected
578
- * - exception should be thrown
579
- */
580
- it(`should throw exception when a config violating the
581
- "greater than or equal" constraint, is passed`, async () => {
582
- const confValidator = new ConfigValidator(
583
- <ConfigSchema>testData.apiSchemaConfigPairWrongGreaterEqual.schema
584
- );
585
-
586
- expect(() =>
587
- confValidator.validateConfig(
588
- testData.apiSchemaConfigPairWrongGreaterEqual.config
589
- )
590
- ).toThrow();
591
- });
592
-
593
- /**
594
- * @target validateSchema should throw exception when a config violating the
595
- * "less than" constraint, is passed
596
- * @dependencies
597
- * @scenario
598
- * - call validateConfig with the config
599
- * - check if any exception is thrown
600
- * @expected
601
- * - exception should be thrown
602
- */
603
- it(`should throw exception when a config violating the "less than"
604
- constraint, is passed`, async () => {
605
- const confValidator = new ConfigValidator(
606
- <ConfigSchema>testData.apiSchemaConfigPairWrongLess.schema
607
- );
608
-
609
- expect(() =>
610
- confValidator.validateConfig(
611
- testData.apiSchemaConfigPairWrongLess.config
612
- )
613
- ).toThrow();
614
- });
615
-
616
- /**
617
- * @target validateSchema should throw exception when a config violating the
618
- * "less than or equal" constraint, is passed
619
- * @dependencies
620
- * @scenario
621
- * - call validateConfig with the config
622
- * - check if any exception is thrown
623
- * @expected
624
- * - exception should be thrown
625
- */
626
- it(`should throw exception when a config violating the "less than or equal"
627
- constraint, is passed`, async () => {
628
- const confValidator = new ConfigValidator(
629
- <ConfigSchema>testData.apiSchemaConfigPairWrongLessEqual.schema
630
- );
631
-
632
- expect(() =>
633
- confValidator.validateConfig(
634
- testData.apiSchemaConfigPairWrongLessEqual.config
635
- )
636
- ).toThrow();
637
- });
638
-
639
- /**
640
- * @target validateSchema should throw exception when a config violating the
641
- * "greater than for bigint" constraint, is passed
642
- * @dependencies
643
- * @scenario
644
- * - call validateConfig with the config
645
- * - check if any exception is thrown
646
- * @expected
647
- * - exception should be thrown
648
- */
649
- it(`should throw exception when a config violating the
650
- "greater than for bigint" constraint, is passed`, async () => {
651
- const confValidator = new ConfigValidator(
652
- <ConfigSchema>testData.apiSchemaConfigPairWrongGreaterBigInt.schema
653
- );
654
-
655
- expect(() =>
656
- confValidator.validateConfig(
657
- testData.apiSchemaConfigPairWrongGreaterBigInt.config
658
- )
659
- ).toThrow();
660
- });
661
-
662
- /**
663
- * @target validateSchema should throw exception when a config violating the
664
- * "greater than or equal for bigint" constraint, is passed
665
- * @dependencies
666
- * @scenario
667
- * - call validateConfig with the config
668
- * - check if any exception is thrown
669
- * @expected
670
- * - exception should be thrown
671
- */
672
- it(`should throw exception when a config violating the
673
- "greater than or equal for bigint" constraint, is passed`, async () => {
674
- const confValidator = new ConfigValidator(
675
- <ConfigSchema>testData.apiSchemaConfigPairWrongGreaterEqualBigInt.schema
676
- );
677
-
678
- expect(() =>
679
- confValidator.validateConfig(
680
- testData.apiSchemaConfigPairWrongGreaterEqualBigInt.config
681
- )
682
- ).toThrow();
683
- });
684
-
685
- /**
686
- * @target validateSchema should throw exception when a config violating the
687
- * "less than for bigint" constraint, is passed
688
- * @dependencies
689
- * @scenario
690
- * - call validateConfig with the config
691
- * - check if any exception is thrown
692
- * @expected
693
- * - exception should be thrown
694
- */
695
- it(`should throw exception when a config violating the
696
- "less than for bigint" constraint, is passed`, async () => {
697
- const confValidator = new ConfigValidator(
698
- <ConfigSchema>testData.apiSchemaConfigPairWrongLessBigInt.schema
699
- );
700
-
701
- expect(() =>
702
- confValidator.validateConfig(
703
- testData.apiSchemaConfigPairWrongLessBigInt.config
704
- )
705
- ).toThrow();
706
- });
707
-
708
- /**
709
- * @target validateSchema should throw exception when a config violating the
710
- * "less than or equal for bigint" constraint, is passed
711
- * @dependencies
712
- * @scenario
713
- * - call validateConfig with the config
714
- * - check if any exception is thrown
715
- * @expected
716
- * - exception should be thrown
717
- */
718
- it(`should throw exception when a config violating the
719
- "less than or equal for bigint" constraint, is passed`, async () => {
720
- const confValidator = new ConfigValidator(
721
- <ConfigSchema>testData.apiSchemaConfigPairWrongLessEqualBigInt.schema
722
- );
723
-
724
- expect(() =>
725
- confValidator.validateConfig(
726
- testData.apiSchemaConfigPairWrongLessEqualBigInt.config
727
- )
728
- ).toThrow();
729
- });
730
-
731
- /**
732
- * @target validateSchema should not throw exception when config violates
733
- * "required" validation but the "when" clause is false
734
- * @dependencies
735
- * @scenario
736
- * - call validateConfig with the config
737
- * - check if any exception is thrown
738
- * @expected
739
- * - exception should be thrown
740
- */
741
- it(`should not throw exception when config violates "required" validation
742
- but the "when" clause is false`, async () => {
743
- const confValidator = new ConfigValidator(
744
- <ConfigSchema>testData.apiSchemaConfigPairWrongRequiredFalseWhen.schema
745
- );
746
-
747
- confValidator.validateConfig(
748
- testData.apiSchemaConfigPairWrongRequiredFalseWhen.config
749
- );
750
- });
751
-
752
- /**
753
- * @target validateSchema should not throw exception when config violates
754
- * "regex" validation but the "when" clause is false
755
- * @dependencies
756
- * @scenario
757
- * - call validateConfig with the config
758
- * - check if any exception is thrown
759
- * @expected
760
- * - exception should be thrown
761
- */
762
- it(`should not throw exception when config violates "regex" validation but
763
- the "when" clause is false`, async () => {
764
- const confValidator = new ConfigValidator(
765
- <ConfigSchema>testData.apiSchemaConfigPairWrongRegexFalseWhen.schema
766
- );
767
-
768
- confValidator.validateConfig(
769
- testData.apiSchemaConfigPairWrongRegexFalseWhen.config
770
- );
771
- });
772
-
773
- /**
774
- * @target validateSchema should not throw exception when config violates
775
- * "choices" validation but the "when" clause is false
776
- * @dependencies
777
- * @scenario
778
- * - call validateConfig with the config
779
- * - check if any exception is thrown
780
- * @expected
781
- * - exception should be thrown
782
- */
783
- it(`should not throw exception when config violates "choices" validation but
784
- the "when" clause is false`, async () => {
785
- const confValidator = new ConfigValidator(
786
- <ConfigSchema>testData.apiSchemaConfigPairWrongChoiceFalseWhen.schema
787
- );
788
-
789
- confValidator.validateConfig(
790
- testData.apiSchemaConfigPairWrongChoiceFalseWhen.config
791
- );
792
- });
793
-
794
- /**
795
- * @target validateSchema should not throw exception when config violates
796
- * "gt" validation but the "when" clause is false
797
- * @dependencies
798
- * @scenario
799
- * - call validateConfig with the config
800
- * - check if any exception is thrown
801
- * @expected
802
- * - exception should be thrown
803
- */
804
- it(`should not throw exception when config violates "gt" validation but the
805
- "when" clause is false`, async () => {
806
- const confValidator = new ConfigValidator(
807
- <ConfigSchema>testData.apiSchemaConfigPairWrongGreaterFalseWhen.schema
808
- );
809
-
810
- confValidator.validateConfig(
811
- testData.apiSchemaConfigPairWrongGreaterFalseWhen.config
812
- );
813
- });
814
-
815
- /**
816
- * @target validateSchema should not throw exception when config violates
817
- * "gte" validation but the "when" clause is false
818
- * @dependencies
819
- * @scenario
820
- * - call validateConfig with the config
821
- * - check if any exception is thrown
822
- * @expected
823
- * - exception should be thrown
824
- */
825
- it(`should not throw exception when config violates "gte" validation but
826
- the "when" clause is false`, async () => {
827
- const confValidator = new ConfigValidator(
828
- <ConfigSchema>(
829
- testData.apiSchemaConfigPairWrongGreaterEqualFalseWhen.schema
830
- )
831
- );
832
-
833
- confValidator.validateConfig(
834
- testData.apiSchemaConfigPairWrongGreaterEqualFalseWhen.config
835
- );
836
- });
837
-
838
- /**
839
- * @target validateSchema should not throw exception when config violates
840
- * "lt" validation but the "when" clause is false
841
- * @dependencies
842
- * @scenario
843
- * - call validateConfig with the config
844
- * - check if any exception is thrown
845
- * @expected
846
- * - exception should be thrown
847
- */
848
- it(`should not throw exception when config violates "lt" validation but the
849
- "when" clause is false`, async () => {
850
- const confValidator = new ConfigValidator(
851
- <ConfigSchema>testData.apiSchemaConfigPairWrongLessFalseWhen.schema
852
- );
853
-
854
- confValidator.validateConfig(
855
- testData.apiSchemaConfigPairWrongLessFalseWhen.config
856
- );
857
- });
858
-
859
- /**
860
- * @target validateSchema should not throw exception when config violates
861
- * "lte" validation but the "when" clause is false
862
- * @dependencies
863
- * @scenario
864
- * - call validateConfig with the config
865
- * - check if any exception is thrown
866
- * @expected
867
- * - exception should be thrown
868
- */
869
- it(`should not throw exception when config violates "lte" validation but the
870
- "when" clause is false`, async () => {
871
- const confValidator = new ConfigValidator(
872
- <ConfigSchema>testData.apiSchemaConfigPairWrongLessEqualFalseWhen.schema
873
- );
874
-
875
- confValidator.validateConfig(
876
- testData.apiSchemaConfigPairWrongLessEqualFalseWhen.config
877
- );
878
- });
879
-
880
- /**
881
- * @target validateSchema should not throw exception when config violates
882
- * "bigint gt" validation but the "when" clause is false
883
- * @dependencies
884
- * @scenario
885
- * - call validateConfig with the config
886
- * - check if any exception is thrown
887
- * @expected
888
- * - exception should be thrown
889
- */
890
- it(`should not throw exception when config violates "bigint gt" validation
891
- but the "when" clause is false`, async () => {
892
- const confValidator = new ConfigValidator(
893
- <ConfigSchema>(
894
- testData.apiSchemaConfigPairWrongBigIntGreaterFalseWhen.schema
895
- )
896
- );
897
-
898
- confValidator.validateConfig(
899
- testData.apiSchemaConfigPairWrongBigIntGreaterFalseWhen.config
900
- );
901
- });
902
-
903
- /**
904
- * @target validateSchema should not throw exception when config violates
905
- * "bigint gte" validation but the "when" clause is false
906
- * @dependencies
907
- * @scenario
908
- * - call validateConfig with the config
909
- * - check if any exception is thrown
910
- * @expected
911
- * - exception should be thrown
912
- */
913
- it(`should not throw exception when config violates "bigint gte" validation
914
- but the "when" clause is false`, async () => {
915
- const confValidator = new ConfigValidator(
916
- <ConfigSchema>(
917
- testData.apiSchemaConfigPairWrongBigIntGreaterEqualFalseWhen.schema
918
- )
919
- );
920
-
921
- confValidator.validateConfig(
922
- testData.apiSchemaConfigPairWrongBigIntGreaterEqualFalseWhen.config
923
- );
924
- });
925
-
926
- /**
927
- * @target validateSchema should not throw exception when config violates
928
- * "bigint lt" validation but the "when" clause is false
929
- * @dependencies
930
- * @scenario
931
- * - call validateConfig with the config
932
- * - check if any exception is thrown
933
- * @expected
934
- * - exception should be thrown
935
- */
936
- it(`should not throw exception when config violates "bigint lt" validation
937
- but the "when" clause is false`, async () => {
938
- const confValidator = new ConfigValidator(
939
- <ConfigSchema>(
940
- testData.apiSchemaConfigPairWrongBigIntLessFalseWhen.schema
941
- )
942
- );
943
-
944
- confValidator.validateConfig(
945
- testData.apiSchemaConfigPairWrongBigIntLessFalseWhen.config
946
- );
947
- });
948
-
949
- /**
950
- * @target validateSchema should not throw exception when config violates
951
- * "bigint lte" validation but the "when" clause is false
952
- * @dependencies
953
- * @scenario
954
- * - call validateConfig with the config
955
- * - check if any exception is thrown
956
- * @expected
957
- * - exception should be thrown
958
- */
959
- it(`should not throw exception when config violates "bigint lte" validation
960
- but the "when" clause is false`, async () => {
961
- const confValidator = new ConfigValidator(
962
- <ConfigSchema>(
963
- testData.apiSchemaConfigPairWrongBigIntLessEqualFalseWhen.schema
964
- )
965
- );
966
-
967
- confValidator.validateConfig(
968
- testData.apiSchemaConfigPairWrongBigIntLessEqualFalseWhen.config
969
- );
970
- });
971
-
972
- /**
973
- * @target validateSchema should throw exception using the custom message
974
- * when the validation has error property set
975
- * @dependencies
976
- * @scenario
977
- * - call validateConfig with the config
978
- * - check if any exception is thrown with the right message
979
- * @expected
980
- * - exception should be thrown with the right message
981
- */
982
- it(`should throw exception using the custom message when the validation has
983
- error property set`, async () => {
984
- const confValidator = new ConfigValidator(
985
- <ConfigSchema>testData.apiSchemaConfigPairWrongChoice.schema
986
- );
987
-
988
- expect(() =>
989
- confValidator.validateConfig(
990
- testData.apiSchemaConfigPairWrongChoice.config
991
- )
992
- ).toThrow(
993
- testData.apiSchemaConfigPairWrongChoice.schema.apiType.validations[1]
994
- .error
995
- );
996
- });
997
-
998
- /**
999
- * @target validateSchema should not throw exception when "bigint" field is
1000
- * passed in string format in config and default field in schema
1001
- * @dependencies
1002
- * @scenario
1003
- * - call validateConfig with the config
1004
- * - check if any exception is thrown
1005
- * @expected
1006
- * - exception should not be thrown
1007
- */
1008
- it(`should not throw exception when "bigint" field is passed in string format in config and default field in schema`, async () => {
1009
- const confValidator = new ConfigValidator(
1010
- <ConfigSchema>testData.apiSchemaConfigPairWithStringBigInt.schema
1011
- );
1012
-
1013
- expect(() => {
1014
- confValidator.validateConfig(
1015
- testData.apiSchemaConfigPairWithStringBigInt.config
1016
- );
1017
- }).not.toThrow();
1018
- });
1019
-
1020
- /**
1021
- * @target validateSchema should not throw exception when "number" field is
1022
- * passed in string format
1023
- * @dependencies
1024
- * @scenario
1025
- * - call validateConfig with the config
1026
- * - check if any exception is thrown
1027
- * @expected
1028
- * - exception should not be thrown
1029
- */
1030
- it(`should not throw exception when "number" field is passed in string
1031
- format`, async () => {
1032
- const confValidator = new ConfigValidator(
1033
- <ConfigSchema>testData.apiSchemaConfigPairWithStringNumber.schema
1034
- );
1035
-
1036
- confValidator.validateConfig(
1037
- testData.apiSchemaConfigPairWithStringNumber.config
1038
- );
1039
- });
1040
-
1041
- /**
1042
- * @target validateConfig should throw exception when value doesn't match
1043
- * the schema array type
1044
- * @dependencies
1045
- * @scenario
1046
- * - call validateConfig with the config
1047
- * - check if any exception is thrown
1048
- * @expected
1049
- * - exception should be thrown
1050
- */
1051
- it(`should throw exception when value doesn't match the schema array type`, async () => {
1052
- const confValidator = new ConfigValidator(
1053
- <ConfigSchema>testData.arraySchemaConfigPairWrongValueType.schema
1054
- );
1055
-
1056
- expect(() =>
1057
- confValidator.validateConfig(
1058
- testData.arraySchemaConfigPairWrongValueType.config
1059
- )
1060
- ).toThrow();
1061
- });
1062
- });
1063
-
1064
- describe('valueAt', () => {
1065
- /**
1066
- * @target valueAt should return the value at specified path in config
1067
- * object
1068
- * @dependencies
1069
- * @scenario
1070
- * - call valueAt with the config and path
1071
- * - check if correct value is returned
1072
- * @expected
1073
- * - correct value should be returned
1074
- */
1075
- it(`should return the value at specified path in config object`, async () => {
1076
- const configObject = {
1077
- apiType: 'explorer',
1078
- servers: {
1079
- url: 'node256.mydomain.net',
1080
- },
1081
- apis: {
1082
- explorer: {
1083
- url: 'example.com',
1084
- port: 600,
1085
- },
1086
- },
1087
- };
1088
-
1089
- const value = ConfigValidator.valueAt(configObject, [
1090
- 'apis',
1091
- 'explorer',
1092
- 'url',
1093
- ]);
1094
-
1095
- expect(value).toEqual('example.com');
1096
- });
1097
-
1098
- /**
1099
- * @target valueAt should return undefined when invalid path is passed
1100
- * @dependencies
1101
- * @scenario
1102
- * - call valueAt with the config and path
1103
- * - check if undefined is returned
1104
- * @expected
1105
- * - undefined should be returned
1106
- */
1107
- it(`should return undefined when invalid path is passed`, async () => {
1108
- const configObject = {
1109
- apiType: 'explorer',
1110
- servers: {
1111
- url: 'node256.mydomain.net',
1112
- },
1113
- apis: {
1114
- explorer: {
1115
- url: 'example.com',
1116
- port: 600,
1117
- },
1118
- },
1119
- };
1120
-
1121
- const value = ConfigValidator.valueAt(configObject, [
1122
- 'apis',
1123
- 'node',
1124
- 'url',
1125
- ]);
1126
-
1127
- expect(value).toEqual(undefined);
1128
- });
1129
- });
1130
-
1131
- describe('generateTSTypes', () => {
1132
- /**
1133
- * @target generateTSTypes should return TypeScript interfaces for
1134
- * this.schema
1135
- * @dependencies
1136
- * @scenario
1137
- * - call generateTSTypes
1138
- * - check if correct types string is returned
1139
- * @expected
1140
- * - correct types string should be returned
1141
- */
1142
- it(`should return TypeScript interfaces for this.schema`, async () => {
1143
- const confValidator = new ConfigValidator(
1144
- <ConfigSchema>testData.schemaTypeScriptTypesPair.schema
1145
- );
1146
- const types = confValidator.generateTSTypes('Infrastructure');
1147
- expect(types).toEqual(testData.schemaTypeScriptTypesPair.types);
1148
- });
1149
-
1150
- /**
1151
- * @target generateTSTypes should generate unique path-based names without numeric suffixes
1152
- * @dependencies
1153
- * @scenario
1154
- * - define a schema with duplicate child keys under different parents
1155
- * - call generateTSTypes
1156
- * - check for path-based interface names
1157
- * @expected
1158
- * - types should include UserDatabase and ApisExplorer
1159
- * - types should not include numeric suffixes like Database1/Explorer1
1160
- */
1161
- it(`should generate unique path-based names without numeric suffixes`, async () => {
1162
- const confValidator = new ConfigValidator(
1163
- <ConfigSchema>testData.duplicateChildKeysSchema.schema
1164
- );
1165
- const types = confValidator.generateTSTypes('Infrastructure');
1166
-
1167
- expect(types).toContain('export interface UserDatabase');
1168
- expect(types).toContain('export interface ApisExplorer');
1169
- expect(types).not.toContain('Database1');
1170
- expect(types).not.toContain('Explorer1');
1171
- });
1172
-
1173
- /**
1174
- * @target generateTSTypes should not emit duplicate interface declarations
1175
- * @dependencies
1176
- * @scenario
1177
- * - define a schema with repeated key names under different parents
1178
- * - call generateTSTypes
1179
- * - count interface declarations for each name
1180
- * @expected
1181
- * - each interface name should be emitted only once
1182
- */
1183
- it(`should not emit duplicate interface declarations`, async () => {
1184
- const confValidator = new ConfigValidator(
1185
- <ConfigSchema>testData.duplicateChildKeysSchema.schema
1186
- );
1187
- const types = confValidator.generateTSTypes('Infrastructure');
1188
-
1189
- const countName = (name: string) =>
1190
- (types.match(new RegExp(`export interface ${name}\\b`, 'g')) || [])
1191
- .length;
1192
-
1193
- expect(countName('UserDatabase')).toBe(1);
1194
- expect(countName('ApisExplorer')).toBe(1);
1195
- });
1196
-
1197
- /**
1198
- * @target generateTSTypes should generate distinct names for identical structures at different paths
1199
- * @dependencies
1200
- * @scenario
1201
- * - define identical object structures under different parents
1202
- * - call generateTSTypes
1203
- * - check that interfaces are named by path
1204
- * @expected
1205
- * - distinct names should be generated (PrimaryConnection, BackupConnection)
1206
- */
1207
- it(`should generate distinct names for identical structures at different paths`, async () => {
1208
- const confValidator = new ConfigValidator(
1209
- <ConfigSchema>testData.identicalStructurePathsSchema.schema
1210
- );
1211
- const types = confValidator.generateTSTypes('Infrastructure');
1212
-
1213
- expect(types).toContain('export interface PrimaryConnection');
1214
- expect(types).toContain('export interface BackupConnection');
1215
- });
1216
-
1217
- /**
1218
- * @target generateTSTypes should name array item object types based on path
1219
- * @dependencies
1220
- * @scenario
1221
- * - define an array of objects at root level
1222
- * - call generateTSTypes
1223
- * - check that array item type is generated and referenced correctly
1224
- * @expected
1225
- * - Logs array should reference Logs item interface and it should be emitted once
1226
- */
1227
- it(`should name array item object types based on path`, async () => {
1228
- const confValidator = new ConfigValidator(
1229
- <ConfigSchema>testData.arrayItemsAtRootSchema.schema
1230
- );
1231
- const types = confValidator.generateTSTypes('Infrastructure');
1232
-
1233
- expect(types).toContain('export interface Logs');
1234
- expect((types.match(/export interface Logs\b/g) || []).length).toBe(1);
1235
- expect(types).toContain('logs: Logs[]');
1236
- });
1237
- });
1238
-
1239
- describe('getConfigForLevel', () => {
1240
- /**
1241
- * @target getConfigForLevel should return the correct characteristic object
1242
- * for passed level of node config package
1243
- * @dependencies
1244
- * @scenario
1245
- * - call getConfigForLevel
1246
- * - check if correct characteristic object is returned
1247
- * @expected
1248
- * - correct characteristic object should be returned
1249
- */
1250
- it(`should return the correct characteristic object for passed level of node
1251
- config package`, async () => {
1252
- const confValidator = new ConfigValidator(
1253
- <ConfigSchema>testData.schemaConfigCharPair.schema
1254
- );
1255
- const configCharacteristic = confValidator.getConfigForLevel(
1256
- config,
1257
- 'local'
1258
- );
1259
-
1260
- expect(configCharacteristic).toEqual(
1261
- testData.schemaConfigCharPair.characteristic
1262
- );
1263
- });
1264
- });
1265
-
1266
- describe('validateAndWriteConfig', () => {
1267
- /**
1268
- * @target validateAndWriteConfig should validate config when merged with
1269
- * passed object and write it to the appropriate config file
1270
- * @dependencies
1271
- * @scenario
1272
- * - call validateAndWriteConfig
1273
- * - check validateAndWriteConfig to throw no exception
1274
- * - check the config file to be correctly saved
1275
- * @expected
1276
- * - validateAndWriteConfig should throw no exception
1277
- * - the config file should be correctly saved
1278
- */
1279
- it(`should validate config when merged with passed object and write it to
1280
- the appropriate config file`, async () => {
1281
- const confValidator = new ConfigValidator(
1282
- <ConfigSchema>testData.schemaConfigCharPair.schema
1283
- );
1284
- const obj = { apiType: 'node' };
1285
- confValidator.validateAndWriteConfig(obj, config, 'default', 'json');
1286
- const savedObj = JSON.parse(
1287
- fs.readFileSync(path.join(configDir, 'default.json'), 'utf-8')
1288
- );
1289
-
1290
- expect(savedObj).toEqual(obj);
1291
- });
1292
-
1293
- /**
1294
- * @target validateAndWriteConfig should throw exception when config after
1295
- * being merged with passed object is not valid and preserve the original
1296
- * config file
1297
- * @dependencies
1298
- * @scenario
1299
- * - call validateAndWriteConfig
1300
- * - check validateAndWriteConfig to throw exception
1301
- * - check the config file to be unchanged
1302
- * @expected
1303
- * - validateAndWriteConfig should throw exception
1304
- * - config file should be unchanged
1305
- */
1306
- it(`should throw exception when config after being merged with passed object
1307
- is not valid and preserve the original config file`, async () => {
1308
- const confValidator = new ConfigValidator(
1309
- <ConfigSchema>testData.schemaConfigCharPair.schema
1310
- );
1311
- const originalObj = JSON.parse(
1312
- fs.readFileSync(path.join(configDir, 'local.json'), 'utf-8')
1313
- );
1314
-
1315
- const obj = { apiType: 'wrong-value' };
1316
-
1317
- expect(() =>
1318
- confValidator.validateAndWriteConfig(obj, config, 'local', 'json')
1319
- ).toThrow();
1320
-
1321
- const savedObj = JSON.parse(
1322
- fs.readFileSync(path.join(configDir, 'local.json'), 'utf-8')
1323
- );
1324
- expect(savedObj).toEqual(originalObj);
1325
- });
1326
-
1327
- /**
1328
- * @target validateAndWriteConfig should not throw exception when config
1329
- * after being merged with passed object is valid even if the passed object
1330
- * itself is not valid
1331
- * @dependencies
1332
- * @scenario
1333
- * - call validateAndWriteConfig
1334
- * - check validateAndWriteConfig not to throw exception
1335
- * - check the config file to be correctly saved
1336
- * @expected
1337
- * - validateAndWriteConfig should throw exception
1338
- * - config file should be correctly saved
1339
- */
1340
- it(`should throw exception when config after being merged with passed object
1341
- is not valid and preserve the original config file`, async () => {
1342
- const confValidator = new ConfigValidator(
1343
- <ConfigSchema>testData.schemaConfigCharPair.schema
1344
- );
1345
- const originalObj = JSON.parse(
1346
- fs.readFileSync(path.join(configDir, 'local.json'), 'utf-8')
1347
- );
1348
-
1349
- const obj = {
1350
- servers: {
1351
- url: 555,
1352
- },
1353
- };
1354
-
1355
- confValidator.validateAndWriteConfig(obj, config, 'local', 'json');
1356
-
1357
- const savedObj = JSON.parse(
1358
- fs.readFileSync(path.join(configDir, 'local.json'), 'utf-8')
1359
- );
1360
- expect(savedObj).toEqual(obj);
1361
- });
1362
- });
1363
- });