Skip to content

Commit

Permalink
[Form lib] Fix validation type execution when none is specified (#123363
Browse files Browse the repository at this point in the history
)
  • Loading branch information
sebelga authored Jan 24, 2022
1 parent 775be29 commit 2284470
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)();

Expand Down Expand Up @@ -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)();

Expand Down Expand Up @@ -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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,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[]> => {
Expand All @@ -233,10 +233,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;
}

Expand Down Expand Up @@ -395,7 +392,7 @@ export const useField = <T, FormType = FormData, I = T>(
const {
formData = __getFormData$().value,
value: valueToValidate = value,
validationType,
validationType = VALIDATION_TYPES.FIELD,
onlyBlocking = false,
} = validationData;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
FormSubmitHandler,
OnUpdateHandler,
FormHook,
FieldHook,
ValidationFunc,
FieldConfig,
VALIDATION_TYPES,
Expand All @@ -37,6 +38,14 @@ const onFormHook = (_form: FormHook<any>) => {
};

describe('useForm() hook', () => {
beforeAll(() => {
jest.useFakeTimers();
});

afterAll(() => {
jest.useRealTimers();
});

beforeEach(() => {
formHook = null;
});
Expand Down Expand Up @@ -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;
Expand All @@ -556,7 +567,12 @@ describe('useForm() hook', () => {
},
],
}}
/>
>
{(field) => {
fieldHook = field;
return null;
}}
</UseField>
</Form>
);
};
Expand All @@ -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();
});
Expand Down

0 comments on commit 2284470

Please sign in to comment.