From 228447044e7adb50a14f0658d6657be5b6eb60e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Mon, 24 Jan 2022 16:08:55 +0000 Subject: [PATCH] [Form lib] Fix validation type execution when none is specified (#123363) --- .../hook_form_lib/hooks/use_field.test.tsx | 130 ++++++++++-------- .../forms/hook_form_lib/hooks/use_field.ts | 9 +- .../hook_form_lib/hooks/use_form.test.tsx | 24 +++- 3 files changed, 97 insertions(+), 66 deletions(-) diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx index 0e5dd7eb82e72..c5e24a578bd86 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx @@ -13,41 +13,47 @@ import { Form, UseField } from '../components'; import React from 'react'; import { useForm } from '.'; import { emptyField } from '../../helpers/field_validators'; -import { FieldHook, FieldValidateResponse, VALIDATION_TYPES } from '..'; +import { FieldHook, FieldValidateResponse, VALIDATION_TYPES, FieldConfig } from '..'; describe('useField() hook', () => { + let fieldHook: FieldHook; + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + const TestField = ({ field }: { field: FieldHook }) => { + fieldHook = field; + return null; + }; + + const getTestForm = (config?: FieldConfig) => () => { + const { form } = useForm(); + + return ( +
+ + + ); + }; + describe('field.validate()', () => { const EMPTY_VALUE = ' '; - test('It should not invalidate a field with arrayItem validation when isBlocking is false', async () => { - let fieldHook: FieldHook; - - const TestField = ({ field }: { field: FieldHook }) => { - fieldHook = field; - return null; - }; - - const TestForm = () => { - const { form } = useForm(); - - return ( -
- - - ); - }; + test('it should not invalidate a field with arrayItem validation when isBlocking is false', async () => { + const TestForm = getTestForm({ + validations: [ + { + validator: emptyField('error-message'), + type: VALIDATION_TYPES.ARRAY_ITEM, + isBlocking: false, + }, + ], + }); registerTestBed(TestForm)(); @@ -78,35 +84,16 @@ describe('useField() hook', () => { expect(fieldHook!.isValid).toBe(true); }); - test('It should invalidate an arrayItem field when isBlocking is true', async () => { - let fieldHook: FieldHook; - - const TestField = ({ field }: { field: FieldHook }) => { - fieldHook = field; - return null; - }; - - const TestForm = () => { - const { form } = useForm(); - - return ( -
- - - ); - }; + test('it should invalidate an arrayItem field when isBlocking is true', async () => { + const TestForm = getTestForm({ + validations: [ + { + validator: emptyField('error-message'), + type: VALIDATION_TYPES.ARRAY_ITEM, + isBlocking: true, + }, + ], + }); registerTestBed(TestForm)(); @@ -136,5 +123,30 @@ describe('useField() hook', () => { // expect the field to be invalid because the validation error is blocking expect(fieldHook!.isValid).toBe(false); }); + + test('it should only run the FIELD validadtion type when no type is specified', async () => { + const validatorFn = jest.fn(() => undefined); + const TestForm = getTestForm({ + validations: [ + { + validator: validatorFn, + type: VALIDATION_TYPES.ARRAY_ITEM, + }, + ], + }); + + registerTestBed(TestForm)(); + + act(() => { + // This should **not** call our validator as it is of type ARRAY_ITEM + // and here, as we don't specify the validation type, we validate the default "FIELD" type. + fieldHook!.validate({ + value: 'foo', + validationType: undefined, // Although not necessary adding it to be explicit + }); + }); + + expect(validatorFn).toBeCalledTimes(0); + }); }); }); diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts index 5079a8b69ba80..0802fa1d4bd3c 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts @@ -212,7 +212,7 @@ export const useField = ( formData: any; value: I; onlyBlocking: boolean; - validationTypeToValidate?: string; + validationTypeToValidate: string; }, clearFieldErrors: FieldHook['clearErrors'] ): ValidationError[] | Promise => { @@ -233,10 +233,7 @@ export const useField = ( type: validationType, isBlocking, }: ValidationConfig) => { - if ( - typeof validationTypeToValidate !== 'undefined' && - validationType !== validationTypeToValidate - ) { + if (validationType !== undefined && validationType !== validationTypeToValidate) { return true; } @@ -395,7 +392,7 @@ export const useField = ( const { formData = __getFormData$().value, value: valueToValidate = value, - validationType, + validationType = VALIDATION_TYPES.FIELD, onlyBlocking = false, } = validationData; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx index e3e818729340e..afaaaaedef23e 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx @@ -16,6 +16,7 @@ import { FormSubmitHandler, OnUpdateHandler, FormHook, + FieldHook, ValidationFunc, FieldConfig, VALIDATION_TYPES, @@ -37,6 +38,14 @@ const onFormHook = (_form: FormHook) => { }; describe('useForm() hook', () => { + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + beforeEach(() => { formHook = null; }); @@ -539,6 +548,8 @@ describe('useForm() hook', () => { }); test('should invalidate a field with a blocking arrayItem validation when validating a form', async () => { + let fieldHook: FieldHook; + const TestComp = () => { const { form } = useForm(); formHook = form; @@ -556,7 +567,12 @@ describe('useForm() hook', () => { }, ], }} - /> + > + {(field) => { + fieldHook = field; + return null; + }} +
); }; @@ -565,6 +581,12 @@ describe('useForm() hook', () => { let isValid: boolean = false; + act(() => { + // We need to call the field validation to mark this field as invalid. + // This will then mark the form as invalid when calling formHook.validate() below + fieldHook.validate({ validationType: VALIDATION_TYPES.ARRAY_ITEM }); + }); + await act(async () => { isValid = await formHook!.validate(); });