diff --git a/packages/react-ui-validations/src/ValidationWrapperInternal.tsx b/packages/react-ui-validations/src/ValidationWrapperInternal.tsx index e2c5f2fb874..7e1ffd01003 100644 --- a/packages/react-ui-validations/src/ValidationWrapperInternal.tsx +++ b/packages/react-ui-validations/src/ValidationWrapperInternal.tsx @@ -249,10 +249,12 @@ export class ValidationWrapperInternal extends React.Component< } return new Promise((resolve) => { - this.setState({ validation }, resolve); - if (Boolean(current) !== Boolean(validation)) { - this.context.onValidationUpdated(this, !validation); - } + this.setState({ validation }, () => { + if (Boolean(current) !== Boolean(validation)) { + this.context.onValidationUpdated(this, !validation); + } + resolve(); + }); }); } diff --git a/packages/react-ui-validations/tests/ValidationContainer.test.tsx b/packages/react-ui-validations/tests/ValidationContainer.test.tsx index 3ffc23e5ece..b90947bbbba 100644 --- a/packages/react-ui-validations/tests/ValidationContainer.test.tsx +++ b/packages/react-ui-validations/tests/ValidationContainer.test.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { + Button, ComboBox, DatePicker, FileUploader, @@ -15,6 +16,7 @@ import { FocusMode, ValidationContainer, ValidationContainerProps, + ValidationInfo, ValidationsFeatureFlagsContext, ValidationWrapper, } from '../src'; @@ -159,4 +161,88 @@ describe('ValidationContainer', () => { expect(screen.getByRole('textbox')).not.toHaveFocus(); }); }); + + describe('on validation updated', () => { + const renderValidationContainer = ( + children: React.ReactElement, + props?: ValidationContainerProps, + ): React.RefObject => { + const containerRef = React.createRef(); + render( + + {children} + , + ); + return containerRef; + }; + const validate = (value: string) => { + return value.includes('bad') ? ({ message: 'Ошибка', type: 'submit' } as ValidationInfo) : null; + }; + + it('works with one field', async () => { + const ValidationForm = () => { + const [value1, setValue1] = React.useState('bad'); + + return ( + <> + + + + + + ); + }; + + const onValidationUpdated = jest.fn(); + const containerRef = renderValidationContainer(, { onValidationUpdated }); + await containerRef.current?.submit(); + const errors = await screen.findAllByText('Ошибка'); + expect(errors.length).toBe(1); + + screen.getByRole('button', { name: 'Repair' }).click(); + expect(onValidationUpdated).toBeCalledWith(true); + }); + + it('works with multiple fields', async () => { + const ValidationForm = () => { + const [value1, setValue1] = React.useState('bad'); + const [value2, setValue2] = React.useState('bad'); + const validationContainerRef = React.useRef(null); + + return ( + <> + + + + + + + + + + + ); + }; + + const onValidationUpdated = jest.fn(); + const containerRef = renderValidationContainer(, { onValidationUpdated }); + await containerRef.current?.submit(); + + const errors = await screen.findAllByText('Ошибка'); + expect(errors.length).toBe(1); + + screen.getByRole('button', { name: 'Partial Repair' }).click(); + expect(onValidationUpdated).toBeCalledWith(false); + + screen.getByRole('button', { name: 'Repair' }).click(); + expect(onValidationUpdated).toBeCalledWith(true); + }); + }); });