[Form lib] Fix validation type execution when none is specified (#123363) (#123730)

This commit is contained in:
Sébastien Loix 2022-01-25 17:22:36 +00:00 committed by GitHub
parent b624f125e7
commit 42507b9ea0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 66 deletions

View file

@ -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 (
<Form form={form}>
<UseField path="test-path" component={TestField} config={config} />
</Form>
);
};
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 (
<Form form={form}>
<UseField
path="test-path"
component={TestField}
config={{
validations: [
{
validator: emptyField('error-message'),
type: VALIDATION_TYPES.ARRAY_ITEM,
isBlocking: false,
},
],
}}
/>
</Form>
);
};
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 (
<Form form={form}>
<UseField
path="test-path"
component={TestField}
config={{
validations: [
{
validator: emptyField('error-message'),
type: VALIDATION_TYPES.ARRAY_ITEM,
isBlocking: true,
},
],
}}
/>
</Form>
);
};
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);
});
});
});

View file

@ -203,7 +203,7 @@ export const useField = <T, FormType = FormData, I = T>(
formData: any;
value: I;
onlyBlocking: boolean;
validationTypeToValidate?: string;
validationTypeToValidate: string;
},
clearFieldErrors: FieldHook['clearErrors']
): ValidationError[] | Promise<ValidationError[]> => {
@ -224,10 +224,7 @@ export const useField = <T, FormType = FormData, I = T>(
type: validationType,
isBlocking,
}: ValidationConfig<FormType, string, I>) => {
if (
typeof validationTypeToValidate !== 'undefined' &&
validationType !== validationTypeToValidate
) {
if (validationType !== undefined && validationType !== validationTypeToValidate) {
return true;
}
@ -384,7 +381,7 @@ export const useField = <T, FormType = FormData, I = T>(
const {
formData = __getFormData$().value,
value: valueToValidate = value,
validationType,
validationType = VALIDATION_TYPES.FIELD,
onlyBlocking = false,
} = validationData;

View file

@ -16,6 +16,7 @@ import {
FormSubmitHandler,
OnUpdateHandler,
FormHook,
FieldHook,
ValidationFunc,
FieldConfig,
VALIDATION_TYPES,
@ -37,6 +38,14 @@ const onFormHook = (_form: FormHook<any>) => {
};
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;
}}
</UseField>
</Form>
);
};
@ -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();
});