From 517ef60d468218ef9884eb13a9d8ed54b3876aee Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 15 Sep 2022 11:40:46 +0200 Subject: [PATCH] Fix downsample validation when downsample action disappears from the previous phase (#140628) --- .../hook_form_lib/hooks/use_field.test.tsx | 74 ++++++++++++++----- .../forms/hook_form_lib/hooks/use_field.ts | 8 +- .../downsample_interval.test.ts | 9 ++- 3 files changed, 70 insertions(+), 21 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 c5e24a578bd86..71aafa6376884 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 @@ -16,8 +16,6 @@ import { emptyField } from '../../helpers/field_validators'; import { FieldHook, FieldValidateResponse, VALIDATION_TYPES, FieldConfig } from '..'; describe('useField() hook', () => { - let fieldHook: FieldHook; - beforeAll(() => { jest.useFakeTimers(); }); @@ -26,22 +24,23 @@ describe('useField() hook', () => { jest.useRealTimers(); }); - const TestField = ({ field }: { field: FieldHook }) => { - fieldHook = field; - return null; - }; - - const getTestForm = (config?: FieldConfig) => () => { - const { form } = useForm(); - - return ( -
- - - ); - }; - describe('field.validate()', () => { + let fieldHook: FieldHook; + const TestField = ({ field }: { field: FieldHook }) => { + fieldHook = field; + return null; + }; + + const getTestForm = (config?: FieldConfig) => () => { + const { form } = useForm(); + + return ( +
+ + + ); + }; + const EMPTY_VALUE = ' '; test('it should not invalidate a field with arrayItem validation when isBlocking is false', async () => { @@ -149,4 +148,45 @@ describe('useField() hook', () => { expect(validatorFn).toBeCalledTimes(0); }); }); + + describe('fieldsToValidateOnChange', () => { + const getTestForm = + (configField1?: FieldConfig, configField2?: FieldConfig) => + ({ showField1, showField2 }: { showField1: boolean; showField2: boolean }) => { + const { form } = useForm(); + + return ( +
+ {showField1 && null} config={configField1} />} + {showField2 && null} config={configField2} />} + + ); + }; + + test('validates dependent fields on unmount', async () => { + const field2ValidatorFn = jest.fn(); + const TestForm = getTestForm( + { + fieldsToValidateOnChange: ['field1', 'field2'], + }, + { + validations: [ + { + validator: field2ValidatorFn, + }, + ], + } + ); + + const wrapper = registerTestBed(TestForm, { + memoryRouter: { wrapComponent: false }, + })({ showField1: true, showField2: true }); + expect(field2ValidatorFn).toBeCalledTimes(0); + + await act(async () => { + wrapper.setProps({ showField1: false }); + }); + expect(field2ValidatorFn).toBeCalledTimes(1); + }); + }); }); 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 206db21b50a0b..6ce084cb750b4 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 @@ -602,8 +602,14 @@ export const useField = ( // We only remove the field from the form "fieldsRefs" map when its path // changes (which in practice never occurs) or whenever the unmounts __removeField(path); + + // We also have to trigger validation of dependant fields + const dependantFields = fieldsToValidateOnChange?.filter((f) => f !== path); + if (dependantFields?.length) { + validateFields(dependantFields); + } }; - }, [path, __removeField]); + }, [path, __removeField, fieldsToValidateOnChange, validateFields]); // Value change: notify prop listener ( {...}}) // We have a separate useEffect for this as the "onChange" handler pass through prop diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts index b24a6d1a32cb7..8ad72ca3d0a82 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts @@ -112,10 +112,13 @@ describe(' downsample interval validation', () => { 'cold' ); - // disable warm phase; + // disable warm phase, check that we now get an error because of the hot phase; await actions.togglePhase('warm'); - // TODO: there is a bug that disabling a phase doesn't trigger downsample validation in other phases, - // users can work around it by changing the value + actions.errors.waitForValidation(); + actions.errors.expectMessages( + ['Must be greater than and a multiple of the hot phase value (60m)'], + 'cold' + ); await actions.cold.downsample.setDownsampleInterval('120', 'm'); actions.errors.waitForValidation(); actions.errors.expectMessages([], 'cold');