@remoteoss/json-schema-form 0.6.4-beta.0 → 0.6.5-beta.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.
- package/CHANGELOG.md +6 -0
- package/dist/index.cjs +474 -373
- package/dist/index.js +474 -373
- package/dist/standalone.js +1388 -1287
- package/package.json +1 -1
- package/src/tests/checkIfConditionMatches.test.js +6 -6
- package/src/tests/jsonLogic.fixtures.js +405 -1
- package/src/tests/jsonLogic.test.js +201 -42
|
@@ -4,26 +4,34 @@ import {
|
|
|
4
4
|
createSchemaWithRulesOnFieldA,
|
|
5
5
|
createSchemaWithThreePropertiesWithRuleOnFieldA,
|
|
6
6
|
multiRuleSchema,
|
|
7
|
+
schemaWhereValidationAndComputedValueIsAppliedOnNormalThenStatement,
|
|
7
8
|
schemaInlineComputedAttrForMaximumMinimumValues,
|
|
8
9
|
schemaInlineComputedAttrForTitle,
|
|
9
10
|
schemaWithBadOperation,
|
|
11
|
+
schemaWithChecksAndThenValidationsOnThen,
|
|
10
12
|
schemaWithComputedAttributeThatDoesntExist,
|
|
11
13
|
schemaWithComputedAttributeThatDoesntExistDescription,
|
|
12
14
|
schemaWithComputedAttributeThatDoesntExistTitle,
|
|
13
15
|
schemaWithComputedAttributes,
|
|
14
16
|
schemaWithComputedAttributesAndErrorMessages,
|
|
17
|
+
schemaWithComputedValueChecksInIf,
|
|
15
18
|
schemaWithDeepVarThatDoesNotExist,
|
|
16
19
|
schemaWithDeepVarThatDoesNotExistOnFieldset,
|
|
20
|
+
schemaWithGreaterThanChecksForThreeFields,
|
|
21
|
+
schemaWithIfStatementWithComputedValuesAndValidationChecks,
|
|
17
22
|
schemaWithInlineMultipleRulesForComputedAttributes,
|
|
18
23
|
schemaWithInlineRuleForComputedAttributeWithCopy,
|
|
19
24
|
schemaWithInlinedRuleOnComputedAttributeThatReferencesUnknownVar,
|
|
20
25
|
schemaWithJSFLogicAndInlineRule,
|
|
21
26
|
schemaWithMissingComputedValue,
|
|
22
27
|
schemaWithMissingRule,
|
|
28
|
+
schemaWithMultipleComputedValueChecks,
|
|
23
29
|
schemaWithNativeAndJSONLogicChecks,
|
|
24
30
|
schemaWithNonRequiredField,
|
|
31
|
+
schemaWithPropertiesCheckAndValidationsInAIf,
|
|
25
32
|
schemaWithPropertyThatDoesNotExistInThatLevelButDoesInFieldset,
|
|
26
33
|
schemaWithTwoRules,
|
|
34
|
+
schemaWithTwoValidationsWhereOneOfThemIsAppliedConditionally,
|
|
27
35
|
schemaWithUnknownVariableInComputedValues,
|
|
28
36
|
schemaWithUnknownVariableInValidations,
|
|
29
37
|
schemaWithValidationThatDoesNotExistOnProperty,
|
|
@@ -363,58 +371,209 @@ describe('jsonLogic: cross-values validations', () => {
|
|
|
363
371
|
expect(handleValidation({ field_a: 10 }).formErrors).toEqual(undefined);
|
|
364
372
|
expect(fieldB.label).toEqual('I need this to work using the 20.');
|
|
365
373
|
});
|
|
366
|
-
});
|
|
367
374
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
375
|
+
it('Use multiple inline rules with different identifiers', () => {
|
|
376
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
377
|
+
schemaWithInlineMultipleRulesForComputedAttributes,
|
|
378
|
+
{
|
|
379
|
+
strictInputType: false,
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
const [, fieldB] = fields;
|
|
383
|
+
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toEqual(undefined);
|
|
384
|
+
expect(fieldB.description).toEqual('Must be between 5 and 20.');
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('Use an inline rule in a schema for a title but it just uses the value', () => {
|
|
388
|
+
const { fields, handleValidation } = createHeadlessForm(schemaInlineComputedAttrForTitle, {
|
|
372
389
|
strictInputType: false,
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
390
|
+
});
|
|
391
|
+
const [, fieldB] = fields;
|
|
392
|
+
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toEqual(undefined);
|
|
393
|
+
expect(fieldB.label).toEqual('20');
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('Use an inline rule for a minimum, maximum value', () => {
|
|
397
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
398
|
+
schemaInlineComputedAttrForMaximumMinimumValues,
|
|
399
|
+
{
|
|
400
|
+
strictInputType: false,
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
const [, fieldB] = fields;
|
|
404
|
+
|
|
405
|
+
// FIXME: We are currently setting NaN here because of how the data clean up works for json-logic
|
|
406
|
+
// We should probably set this as undefined when theres no values set?
|
|
407
|
+
// tracked in INF-53.
|
|
408
|
+
expect(fieldB).toMatchObject({ minimum: NaN, maximum: NaN });
|
|
409
|
+
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toBeUndefined();
|
|
410
|
+
expect(fieldB).toMatchObject({ minimum: 0, maximum: 20 });
|
|
411
|
+
expect(handleValidation({ field_a: 50, field_b: 20 }).formErrors).toEqual({
|
|
412
|
+
field_b: 'Must be greater or equal to 40',
|
|
413
|
+
});
|
|
414
|
+
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
|
|
415
|
+
expect(handleValidation({ field_a: 50, field_b: 70 }).formErrors).toEqual({
|
|
416
|
+
field_b: 'Must be smaller or equal to 60',
|
|
417
|
+
});
|
|
418
|
+
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
|
|
419
|
+
expect(handleValidation({ field_a: 50, field_b: 50 }).formErrors).toBeUndefined();
|
|
420
|
+
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
|
|
421
|
+
});
|
|
379
422
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
423
|
+
it('Mix use of multiple inline rules and an external rule', () => {
|
|
424
|
+
const { fields, handleValidation } = createHeadlessForm(schemaWithJSFLogicAndInlineRule, {
|
|
425
|
+
strictInputType: false,
|
|
426
|
+
});
|
|
427
|
+
handleValidation({ field_a: 10 });
|
|
428
|
+
const [, fieldB] = fields;
|
|
429
|
+
expect(fieldB.label).toEqual('Going to use 20 and 4');
|
|
383
430
|
});
|
|
384
|
-
const [, fieldB] = fields;
|
|
385
|
-
expect(handleValidation({ field_a: 10, field_b: null }).formErrors).toEqual(undefined);
|
|
386
|
-
expect(fieldB.label).toEqual('20');
|
|
387
431
|
});
|
|
388
432
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
433
|
+
describe('Conditionals', () => {
|
|
434
|
+
it('when field_a > field_b, show field_c', () => {
|
|
435
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
436
|
+
schemaWithGreaterThanChecksForThreeFields,
|
|
437
|
+
{ strictInputType: false }
|
|
438
|
+
);
|
|
439
|
+
const fieldC = fields.find((i) => i.name === 'field_c');
|
|
440
|
+
expect(fieldC.isVisible).toEqual(false);
|
|
441
|
+
|
|
442
|
+
expect(handleValidation({ field_a: 1, field_b: 3 }).formErrors).toEqual(undefined);
|
|
443
|
+
expect(handleValidation({ field_a: 1 }).formErrors).toEqual({
|
|
444
|
+
field_b: 'Required field',
|
|
445
|
+
});
|
|
446
|
+
expect(handleValidation({ field_a: 1, field_b: undefined }).formErrors).toEqual({
|
|
447
|
+
field_b: 'Required field',
|
|
448
|
+
});
|
|
449
|
+
expect(handleValidation({ field_a: 10, field_b: 3 }).formErrors).toEqual({
|
|
450
|
+
field_c: 'Required field',
|
|
451
|
+
});
|
|
452
|
+
expect(fieldC.isVisible).toEqual(true);
|
|
453
|
+
expect(handleValidation({ field_a: 10, field_b: 3, field_c: 0 }).formErrors).toEqual(
|
|
454
|
+
undefined
|
|
455
|
+
);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it('A schema with both a `x-jsf-validations` and `properties` check', () => {
|
|
459
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
460
|
+
schemaWithPropertiesCheckAndValidationsInAIf,
|
|
461
|
+
{ strictInputType: false }
|
|
462
|
+
);
|
|
463
|
+
const fieldC = fields.find((i) => i.name === 'field_c');
|
|
464
|
+
expect(handleValidation({ field_a: 1, field_b: 3 }).formErrors).toEqual(undefined);
|
|
465
|
+
expect(fieldC.isVisible).toEqual(false);
|
|
466
|
+
expect(handleValidation({ field_a: 10, field_b: 3 }).formErrors).toEqual({
|
|
467
|
+
field_c: 'Required field',
|
|
468
|
+
});
|
|
469
|
+
expect(fieldC.isVisible).toEqual(true);
|
|
470
|
+
expect(handleValidation({ field_a: 5, field_b: 3 }).formErrors).toEqual(undefined);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
it('Conditionally apply a validation on a property depending on values', () => {
|
|
474
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
475
|
+
schemaWithChecksAndThenValidationsOnThen,
|
|
476
|
+
{ strictInputType: false }
|
|
477
|
+
);
|
|
478
|
+
const cField = fields.find((i) => i.name === 'field_c');
|
|
479
|
+
expect(cField.isVisible).toEqual(false);
|
|
480
|
+
expect(cField.description).toEqual(undefined);
|
|
481
|
+
expect(handleValidation({ field_a: 10, field_b: 5 }).formErrors).toEqual({
|
|
482
|
+
field_c: 'Required field',
|
|
483
|
+
});
|
|
484
|
+
expect(handleValidation({ field_a: 10, field_b: 5, field_c: 0 }).formErrors).toEqual({
|
|
485
|
+
field_c: 'Needs more numbers',
|
|
486
|
+
});
|
|
487
|
+
expect(cField.description).toBe('I am a description!');
|
|
488
|
+
expect(handleValidation({ field_a: 10, field_b: 5, field_c: 201 }).formErrors).toEqual(
|
|
489
|
+
undefined
|
|
490
|
+
);
|
|
491
|
+
expect(handleValidation({ field_a: 5, field_b: 10 }).formErrors).toBeUndefined();
|
|
492
|
+
expect(cField).toMatchObject({
|
|
493
|
+
isVisible: false,
|
|
494
|
+
// description: null, the description will currently be `I am a description!`, how do we change it back to null from here? Needs to be fixed by RMT-58
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it('Should apply a conditional based on a true computedValue', () => {
|
|
499
|
+
const { fields, handleValidation } = createHeadlessForm(schemaWithComputedValueChecksInIf, {
|
|
393
500
|
strictInputType: false,
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
501
|
+
});
|
|
502
|
+
const cField = fields.find((i) => i.name === 'field_c');
|
|
503
|
+
expect(cField.isVisible).toEqual(false);
|
|
504
|
+
expect(cField.description).toEqual(undefined);
|
|
505
|
+
expect(handleValidation({ field_a: 10, field_b: 5 }).formErrors).toEqual({
|
|
506
|
+
field_c: 'Required field',
|
|
507
|
+
});
|
|
508
|
+
expect(handleValidation({ field_a: 10, field_b: 5, field_c: 201 }).formErrors).toEqual(
|
|
509
|
+
undefined
|
|
510
|
+
);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it('Handle multiple computedValue checks by ANDing them together', () => {
|
|
514
|
+
const { handleValidation } = createHeadlessForm(schemaWithMultipleComputedValueChecks, {
|
|
515
|
+
strictInputType: false,
|
|
516
|
+
});
|
|
517
|
+
expect(handleValidation({}).formErrors).toEqual({
|
|
518
|
+
field_a: 'Required field',
|
|
519
|
+
field_b: 'Required field',
|
|
520
|
+
});
|
|
521
|
+
expect(handleValidation({ field_a: 10, field_b: 8 }).formErrors).toEqual({
|
|
522
|
+
field_c: 'Required field',
|
|
523
|
+
});
|
|
524
|
+
expect(handleValidation({ field_a: 10, field_b: 8, field_c: 0 }).formErrors).toEqual({
|
|
525
|
+
field_c: 'Must be two times B',
|
|
526
|
+
});
|
|
527
|
+
expect(handleValidation({ field_a: 10, field_b: 8, field_c: 17 }).formErrors).toEqual(
|
|
528
|
+
undefined
|
|
529
|
+
);
|
|
402
530
|
});
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
531
|
+
|
|
532
|
+
it('Handle having a true condition with both validations and computedValue checks', () => {
|
|
533
|
+
const { handleValidation } = createHeadlessForm(
|
|
534
|
+
schemaWithIfStatementWithComputedValuesAndValidationChecks,
|
|
535
|
+
{ strictInputType: false }
|
|
536
|
+
);
|
|
537
|
+
expect(handleValidation({ field_a: 1, field_b: 1 }).formErrors).toEqual(undefined);
|
|
538
|
+
expect(handleValidation({ field_a: 10, field_b: 20 }).formErrors).toEqual(undefined);
|
|
539
|
+
expect(handleValidation({ field_a: 10, field_b: 9 }).formErrors).toEqual({
|
|
540
|
+
field_c: 'Required field',
|
|
541
|
+
});
|
|
542
|
+
expect(handleValidation({ field_a: 10, field_b: 9, field_c: 10 }).formErrors).toEqual(
|
|
543
|
+
undefined
|
|
544
|
+
);
|
|
406
545
|
});
|
|
407
|
-
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
|
|
408
|
-
expect(handleValidation({ field_a: 50, field_b: 50 }).formErrors).toBeUndefined();
|
|
409
|
-
expect(fieldB).toMatchObject({ minimum: 40, maximum: 60 });
|
|
410
|
-
});
|
|
411
546
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
547
|
+
it('Apply validations and computed values on normal if statement.', () => {
|
|
548
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
549
|
+
schemaWhereValidationAndComputedValueIsAppliedOnNormalThenStatement,
|
|
550
|
+
{ strictInputType: false }
|
|
551
|
+
);
|
|
552
|
+
expect(handleValidation({ field_a: 0, field_b: 0 }).formErrors).toEqual(undefined);
|
|
553
|
+
expect(handleValidation({ field_a: 20, field_b: 0 }).formErrors).toEqual({
|
|
554
|
+
field_b: 'Must be greater than Field A + 10',
|
|
555
|
+
});
|
|
556
|
+
const [, fieldB] = fields;
|
|
557
|
+
expect(fieldB.label).toEqual('Must be greater than 30.');
|
|
558
|
+
expect(handleValidation({ field_a: 20, field_b: 31 }).formErrors).toEqual(undefined);
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
it('When we have a required validation on a top level property and another validation is added, both should be accounted for.', () => {
|
|
562
|
+
const { handleValidation } = createHeadlessForm(
|
|
563
|
+
schemaWithTwoValidationsWhereOneOfThemIsAppliedConditionally,
|
|
564
|
+
{ strictInputType: false }
|
|
565
|
+
);
|
|
566
|
+
expect(handleValidation({ field_a: 10, field_b: 0 }).formErrors).toEqual({
|
|
567
|
+
field_b: 'Must be greater than A',
|
|
568
|
+
});
|
|
569
|
+
expect(handleValidation({ field_a: 10, field_b: 20 }).formErrors).toEqual(undefined);
|
|
570
|
+
expect(handleValidation({ field_a: 20, field_b: 10 }).formErrors).toEqual({
|
|
571
|
+
field_b: 'Must be greater than A',
|
|
572
|
+
});
|
|
573
|
+
expect(handleValidation({ field_a: 20, field_b: 21 }).formErrors).toEqual({
|
|
574
|
+
field_b: 'Must be greater than two times A',
|
|
575
|
+
});
|
|
576
|
+
expect(handleValidation({ field_a: 20, field_b: 41 }).formErrors).toEqual();
|
|
415
577
|
});
|
|
416
|
-
handleValidation({ field_a: 10 });
|
|
417
|
-
const [, fieldB] = fields;
|
|
418
|
-
expect(fieldB.label).toEqual('Going to use 20 and 4');
|
|
419
578
|
});
|
|
420
579
|
});
|