From 50131953db0d5019f4cba97c2c915f3a2c0d2cb5 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Thu, 27 May 2021 19:08:18 +0200 Subject: [PATCH 1/6] testing layouts --- .../__jest__/processors/processor.helpers.tsx | 3 + .../__jest__/processors/user_agent.test.tsx | 125 ++++++++++++++++++ .../common_fields/properties_field.tsx | 13 +- .../processor_form/processors/user_agent.tsx | 72 +++++++++- 4 files changed, 199 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx index d69ceb385ddd7..260520aadb52e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx @@ -154,4 +154,7 @@ type TestSubject = | 'separatorValueField.input' | 'quoteValueField.input' | 'emptyValueField.input' + | 'extractDeviceTypeSwitch.input' + | 'propertiesValueField' + | 'regexFileField.input' | 'trimSwitch.input'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx new file mode 100644 index 0000000000000..fa1c24c9dfb39 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act } from 'react-dom/test-utils'; +import { setup, SetupResult, getProcessorValue } from './processor.helpers'; + +// Default parameter values automatically added to the user agent processor when saved +const defaultUserAgentParameters = { + if: undefined, + regex_file: undefined, + properties: undefined, + description: undefined, + ignore_missing: undefined, + ignore_failure: undefined, + extract_device_type: undefined, +}; + +const USER_AGENT_TYPE = 'user_agent'; + +describe('Processor: User Agent', () => { + let onUpdate: jest.Mock; + let testBed: SetupResult; + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(async () => { + onUpdate = jest.fn(); + + await act(async () => { + testBed = await setup({ + value: { + processors: [], + }, + onFlyoutOpen: jest.fn(), + onUpdate, + }); + }); + + testBed.component.update(); + + // Open flyout to add new processor + testBed.actions.addProcessor(); + // Add type (the other fields are not visible until a type is selected) + await testBed.actions.addProcessorType(USER_AGENT_TYPE); + }); + + test('prevents form submission if required fields are not provided', async () => { + const { + actions: { saveNewProcessor }, + form, + } = testBed; + + // Click submit button with only the processor type defined + await saveNewProcessor(); + + // Expect form error as "field" is required parameter + expect(form.getErrorsMessages()).toEqual(['A field value is required.']); + }); + + test('saves with just the default parameter value', async () => { + const { + actions: { saveNewProcessor }, + form, + } = testBed; + + // Add "field" value (required) + form.setInputValue('fieldNameField.input', 'field_1'); + // Save the field + await saveNewProcessor(); + + const processors = getProcessorValue(onUpdate, USER_AGENT_TYPE); + expect(processors[0][USER_AGENT_TYPE]).toEqual({ + ...defaultUserAgentParameters, + field: 'field_1', + }); + }); + + test('allows optional parameters to be set', async () => { + const { + actions: { saveNewProcessor }, + form, + find, + component, + } = testBed; + + // Add "field" value (required) + form.setInputValue('fieldNameField.input', 'field_1'); + + // Set optional parameteres + form.setInputValue('targetField.input', 'target_field'); + form.setInputValue('regexFileField.input', 'hello*'); + form.toggleEuiSwitch('ignoreMissingSwitch.input'); + form.toggleEuiSwitch('ignoreFailureSwitch.input'); + form.toggleEuiSwitch('extractDeviceTypeSwitch.input'); + await act(async () => { + find('propertiesValueField').simulate('change', [{ label: 'os' }]); + }); + component.update(); + + // Save the field with new changes + await saveNewProcessor(); + + const processors = getProcessorValue(onUpdate, USER_AGENT_TYPE); + expect(processors[0][USER_AGENT_TYPE]).toEqual({ + ...defaultUserAgentParameters, + field: 'field_1', + target_field: 'target_field', + properties: ['os'], + regex_file: 'hello*', + extract_device_type: true, + ignore_missing: true, + ignore_failure: true, + }); + }); +}); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx index dd52375a19436..62dff50ea3e8f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx @@ -6,9 +6,9 @@ */ import React, { FunctionComponent } from 'react'; +import { EuiComboBoxProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { EuiComboBoxOptionOption } from '@elastic/eui'; import { ComboBoxField, FIELD_TYPES, UseField } from '../../../../../../../shared_imports'; import { FieldsConfig, to } from '../shared'; @@ -29,10 +29,10 @@ const fieldsConfig: FieldsConfig = { interface Props { helpText?: React.ReactNode; - propertyOptions?: EuiComboBoxOptionOption[]; + euiFieldProps?: EuiComboBoxProps; } -export const PropertiesField: FunctionComponent = ({ helpText, propertyOptions }) => { +export const PropertiesField: FunctionComponent = ({ helpText, euiFieldProps = {} }) => { return ( = ({ helpText, propertyOp }} component={ComboBoxField} path="fields.properties" - componentProps={{ - euiFieldProps: { - options: propertyOptions || [], - noSuggestions: !propertyOptions, - }, - }} + componentProps={{ euiFieldProps }} /> ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx index 893e52bcc0073..523b09ce2df05 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx @@ -6,14 +6,14 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiCode } from '@elastic/eui'; +import { EuiCode, EuiBetaBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiComboBoxOptionOption } from '@elastic/eui'; -import { FIELD_TYPES, UseField, Field } from '../../../../../../shared_imports'; +import { FIELD_TYPES, ToggleField, UseField, Field } from '../../../../../../shared_imports'; -import { FieldsConfig, from } from './shared'; +import { FieldsConfig, from, to } from './shared'; import { IgnoreMissingField } from './common_fields/ignore_missing_field'; import { FieldNameField } from './common_fields/field_name_field'; import { TargetField } from './common_fields/target_field'; @@ -47,6 +47,52 @@ const fieldsConfig: FieldsConfig = { } ), }, + extract_device_type: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + deserializer: to.booleanOrUndef, + serializer: from.undefinedIfValue(false), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldLabel', { + defaultMessage: 'Extract Device Type', + }), + // label: ( + // + // + // Extract Device Type + // + // + // + // + // + // ) as unknown, + // helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText', { + // defaultMessage: 'Extracts device type from the user agent string.', + // }), + helpText: ( + + + Salt value for the hash function. + + + + + + ) + }} + /> + ), + } }; export const UserAgent: FunctionComponent = () => { @@ -59,7 +105,12 @@ export const UserAgent: FunctionComponent = () => { )} /> - + { 'xpack.ingestPipelines.pipelineEditor.userAgentForm.propertiesFieldHelpText', { defaultMessage: 'Properties added to the target field.' } )} - propertyOptions={propertyOptions} + euiFieldProps={{ + options: propertyOptions as [], + noSuggestions: !propertyOptions, + 'data-test-subj': 'propertiesValueField', + }} + /> + + From 336d86333002381bcce56b09f9bc9256f61024c6 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Mon, 31 May 2021 10:53:24 +0200 Subject: [PATCH 2/6] fix copy for beta badge --- .../static/forms/hook_form_lib/types.ts | 2 +- .../processor_form/processors/user_agent.tsx | 54 ++++++------------- 2 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts index 75c918d4340f2..2c3ace3e3e065 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts @@ -146,7 +146,7 @@ export interface FieldHook { } export interface FieldConfig { - readonly label?: string; + readonly label?: string | ReactNode; readonly labelAppend?: string | ReactNode; readonly helpText?: string | ReactNode; readonly type?: string; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx index 523b09ce2df05..95c3e4e1b6a24 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx @@ -52,46 +52,22 @@ const fieldsConfig: FieldsConfig = { defaultValue: false, deserializer: to.booleanOrUndef, serializer: from.undefinedIfValue(false), - label: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldLabel', { - defaultMessage: 'Extract Device Type', - }), - // label: ( - // - // - // Extract Device Type - // - // - // - // - // - // ) as unknown, - // helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText', { - // defaultMessage: 'Extracts device type from the user agent string.', - // }), - helpText: ( - - - Salt value for the hash function. - - - - - - ) - }} - /> + label: ( + + + Extract Device Type + + + + + ), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText', { + defaultMessage: 'Extracts device type from the user agent string.', + }), } }; From e6b2c92dc389d03ddd66220a626ce12655b145df Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Mon, 31 May 2021 11:21:47 +0200 Subject: [PATCH 3/6] replace hardcoded text with i18n strings --- .../processors/common_fields/properties_field.tsx | 2 +- .../processor_form/processors/user_agent.tsx | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx index 62dff50ea3e8f..c8a50cf64484e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/common_fields/properties_field.tsx @@ -32,7 +32,7 @@ interface Props { euiFieldProps?: EuiComboBoxProps; } -export const PropertiesField: FunctionComponent = ({ helpText, euiFieldProps = {} }) => { +export const PropertiesField: FunctionComponent = ({ helpText, euiFieldProps }) => { return ( - Extract Device Type + From 7d6fddd3d4ce90328d9c945a218194e6af596095 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Mon, 31 May 2021 15:02:31 +0200 Subject: [PATCH 4/6] avoid updating types and just replace label --- .../static/forms/hook_form_lib/types.ts | 2 +- .../processor_form/processors/user_agent.tsx | 49 ++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts index 2c3ace3e3e065..75c918d4340f2 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts @@ -146,7 +146,7 @@ export interface FieldHook { } export interface FieldConfig { - readonly label?: string | ReactNode; + readonly label?: string; readonly labelAppend?: string | ReactNode; readonly helpText?: string | ReactNode; readonly type?: string; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx index 11523f760a2bd..31593c651ed13 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx @@ -52,29 +52,13 @@ const fieldsConfig: FieldsConfig = { defaultValue: false, deserializer: to.booleanOrUndef, serializer: from.undefinedIfValue(false), - label: ( - - - - - - - - + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText', + { + defaultMessage: 'Extracts device type from the user agent string.', + } ), - helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText', { - defaultMessage: 'Extracts device type from the user agent string.', - }), - } + }, }; export const UserAgent: FunctionComponent = () => { @@ -123,6 +107,27 @@ export const UserAgent: FunctionComponent = () => { component={ToggleField} path="fields.extract_device_type" data-test-subj="extractDeviceTypeSwitch" + euiFieldProps={{ + label: ( + + + + + + + + + ), + }} /> From 102f7f3cc9ad980aca2e69ce1430cb2de90b35bb Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 2 Jun 2021 10:03:49 +0200 Subject: [PATCH 5/6] Small cr changes --- .../components/processor_form/processors/user_agent.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx index 31593c651ed13..21350acb829de 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx @@ -19,7 +19,7 @@ import { FieldNameField } from './common_fields/field_name_field'; import { TargetField } from './common_fields/target_field'; import { PropertiesField } from './common_fields/properties_field'; -const propertyOptions: EuiComboBoxOptionOption[] = [ +const propertyOptions: Array> = [ { label: 'name' }, { label: 'os' }, { label: 'device' }, @@ -96,8 +96,8 @@ export const UserAgent: FunctionComponent = () => { { defaultMessage: 'Properties added to the target field.' } )} euiFieldProps={{ - options: propertyOptions as [], - noSuggestions: !propertyOptions, + options: propertyOptions, + noSuggestions: false, 'data-test-subj': 'propertiesValueField', }} /> @@ -113,7 +113,7 @@ export const UserAgent: FunctionComponent = () => { From 68ac6135a6fb9a8ae1361324aa38226f65f27b34 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Thu, 24 Jun 2021 09:37:07 +0200 Subject: [PATCH 6/6] get rid of style prop and just use a smaller badge --- .../components/processor_form/processors/user_agent.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx index 21350acb829de..2b5a68f799b7e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/user_agent.tsx @@ -116,8 +116,9 @@ export const UserAgent: FunctionComponent = () => { defaultMessage="Extract device type" /> - +