Skip to content

Commit 85dc3d6

Browse files
authored
chore(conditionals): Highlight bugs related to validations and conditional fields (#107)
* chore(conditionals): Highlight bug - conditional hidden fields should throw an error, but they do not * chore(conditionals): Highlight bug - values passed to handleValidation are mutated, but should not * chore(conditionals): Highlight bug - multiple conditionals to the same field are not applied * self-review * add @bug tag * remove unneeded assertions
1 parent 9142a0c commit 85dc3d6

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

src/tests/conditions.test.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,3 +547,165 @@ describe('Conditional with literal booleans', () => {
547547
});
548548
});
549549
});
550+
551+
describe('Conditionals - bugs and code-smells', () => {
552+
// Why do we have these bugs?
553+
// To be honest we never realized it much later later.
554+
// We will fix them in the next major version.
555+
556+
const schemaHasPet = {
557+
type: 'object',
558+
additionalProperties: false,
559+
properties: {
560+
has_pet: {
561+
title: 'Has Pet',
562+
description: 'Do you have a pet?',
563+
oneOf: [
564+
{ title: 'Yes', const: 'yes' },
565+
{ title: 'No', const: 'no' },
566+
],
567+
type: 'string',
568+
},
569+
pet_name: {
570+
title: "Pet's name",
571+
type: 'string',
572+
},
573+
},
574+
required: ['has_pet'],
575+
allOf: [
576+
{
577+
if: {
578+
properties: {
579+
has_pet: { const: 'yes' },
580+
},
581+
required: ['has_pet'],
582+
},
583+
then: {
584+
required: ['pet_name'],
585+
},
586+
else: {
587+
properties: {
588+
pet_name: false,
589+
},
590+
},
591+
},
592+
],
593+
};
594+
595+
it('Given values from hidden fields, it does not thrown an error (@bug)', () => {
596+
const { fields, handleValidation } = createHeadlessForm(schemaHasPet, {
597+
strictInputType: false,
598+
});
599+
600+
const petNameField = fields[1];
601+
602+
const validation = handleValidation({ has_pet: 'no', pet_name: 'Max' });
603+
expect(petNameField.isVisible).toBe(false);
604+
605+
// Bug: 🐛 It does not thrown an error,
606+
// but it should to be compliant with JSON Schema specs.
607+
expect(validation.formErrors).toBeUndefined();
608+
// The error should be something like:
609+
// expect(validation.formErrors).toEqual({ pet_name: 'Not allowed.'});
610+
});
611+
612+
it('Given values from hidden fields, it mutates the values (@bug)', () => {
613+
const { handleValidation } = createHeadlessForm(schemaHasPet, {
614+
strictInputType: false,
615+
});
616+
617+
const newValues = { has_pet: 'no', pet_name: 'Max' };
618+
619+
const validation = handleValidation(newValues);
620+
621+
expect(newValues).toEqual({
622+
has_pet: 'no',
623+
pet_name: null, // BUG! 🐛 Should still be "Max", should not be mutated.
624+
});
625+
626+
// Same bug as explained in the previous test.
627+
expect(validation.formErrors).toBeUndefined();
628+
});
629+
630+
it('Given multiple conditionals to the same field, it only applies the last one (@bug) - case 1', () => {
631+
const { handleValidation } = createHeadlessForm(
632+
{
633+
additionalProperties: false,
634+
properties: {
635+
field_a: { type: 'string' },
636+
field_b: { type: 'string' },
637+
field_c: { type: 'number' },
638+
},
639+
allOf: [
640+
{
641+
if: {
642+
properties: { field_a: { const: 'yes' } },
643+
required: ['field_a'],
644+
},
645+
then: { properties: { field_c: { minimum: 30 } } },
646+
},
647+
{
648+
if: {
649+
properties: { field_b: { const: 'yes' } },
650+
required: ['field_b'],
651+
},
652+
then: { properties: { field_c: { minimum: 10 } } },
653+
},
654+
],
655+
},
656+
{
657+
strictInputType: false,
658+
}
659+
);
660+
661+
const validation = handleValidation({ field_a: 'yes', field_b: 'yes', field_c: 5 });
662+
expect(validation.formErrors).toEqual({
663+
// BUG: 🐛 it should be "Must be greater or equal to 30"
664+
field_c: 'Must be greater or equal to 10',
665+
});
666+
});
667+
668+
it('Given multiple conditionals to the same field, it only applies the last one (@bug) - case 2', () => {
669+
const { handleValidation } = createHeadlessForm(
670+
{
671+
additionalProperties: false,
672+
properties: {
673+
field_a: { type: 'string' },
674+
field_b: { type: 'string' },
675+
field_c: { type: 'number' },
676+
},
677+
allOf: [
678+
{
679+
if: {
680+
properties: { field_a: { const: 'yes' } },
681+
required: ['field_a'],
682+
},
683+
then: { properties: { field_c: { minimum: 5 } } },
684+
},
685+
{
686+
if: {
687+
properties: { field_b: { const: 'yes' } },
688+
required: ['field_b'],
689+
},
690+
then: { properties: { field_c: { maximum: 10 } } },
691+
},
692+
],
693+
},
694+
{
695+
strictInputType: false,
696+
}
697+
);
698+
699+
const validation1 = handleValidation({ field_a: 'yes', field_b: 'yes', field_c: 12 });
700+
expect(validation1.formErrors).toEqual({
701+
field_c: 'Must be smaller or equal to 10',
702+
});
703+
704+
const validation2 = handleValidation({ field_a: 'yes', field_b: 'yes', field_c: 3 });
705+
// BUG: 🐛 it should be "Must be greater or equal to 5"
706+
expect(validation2.formErrors).toBeUndefined();
707+
// expect(validation1.formErrors).toEqual({
708+
// field_c: 'Must be greater or equal to 5',
709+
// });
710+
});
711+
});

0 commit comments

Comments
 (0)