Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AutocompleteFieldWildcardComponent } from '.';
import { useFieldValueAutocomplete } from '../hooks/use_field_value_autocomplete';
import { fields, getField } from '../fields/index.mock';
import { autocompleteStartMock } from '../autocomplete/index.mock';
import { FILENAME_WILDCARD_WARNING, FILEPATH_WARNING } from '@kbn/securitysolution-utils';

jest.mock('../hooks/use_field_value_autocomplete');

Expand Down Expand Up @@ -276,4 +277,116 @@ describe('AutocompleteFieldWildcardComponent', () => {
selectedField: getField('file.path.text'),
});
});

test('it does not invoke "onWarning" when no warning exists', () => {
const mockOnWarning = jest.fn();
wrapper = mount(
<AutocompleteFieldWildcardComponent
autocompleteService={autocompleteStartMock}
indexPattern={{
fields,
id: '1234',
title: 'logs-endpoint.events.*',
}}
isClearable={false}
isDisabled={false}
isLoading={false}
onChange={jest.fn()}
onError={jest.fn()}
onWarning={mockOnWarning}
placeholder="Placeholder text"
selectedField={getField('file.path.text')}
selectedValue="invalid path"
/>
);

act(() => {
(
wrapper.find(EuiComboBox).props() as unknown as {
onBlur: () => void;
}
).onBlur();
});

expect(mockOnWarning).not.toHaveBeenCalledWith(true);
});

test('it invokes "onWarning" when warning exists', () => {
const mockOnWarning = jest.fn();
wrapper = mount(
<AutocompleteFieldWildcardComponent
autocompleteService={autocompleteStartMock}
indexPattern={{
fields,
id: '1234',
title: 'logs-endpoint.events.*',
}}
isClearable={false}
isDisabled={false}
isLoading={false}
onChange={jest.fn()}
onError={jest.fn()}
onWarning={mockOnWarning}
placeholder="Placeholder text"
selectedField={getField('file.path.text')}
selectedValue="invalid path"
warning={FILEPATH_WARNING}
/>
);

act(() => {
(
wrapper.find(EuiComboBox).props() as unknown as {
onBlur: () => void;
}
).onBlur();
});

expect(mockOnWarning).toHaveBeenCalledWith(true);
expect(
wrapper
.find('[data-test-subj="valuesAutocompleteWildcardLabel"] div.euiFormHelpText')
.at(0)
.text()
).toEqual(FILEPATH_WARNING);
});

test('it invokes "onWarning" when warning exists and is wildcard warning', () => {
const mockOnWarning = jest.fn();
wrapper = mount(
<AutocompleteFieldWildcardComponent
autocompleteService={autocompleteStartMock}
indexPattern={{
fields,
id: '1234',
title: 'logs-endpoint.events.*',
}}
isClearable={false}
isDisabled={false}
isLoading={false}
onChange={jest.fn()}
onError={jest.fn()}
onWarning={mockOnWarning}
placeholder="Placeholder text"
selectedField={getField('file.path.text')}
selectedValue="invalid path"
warning={FILENAME_WILDCARD_WARNING}
/>
);

act(() => {
(
wrapper.find(EuiComboBox).props() as unknown as {
onBlur: () => void;
}
).onBlur();
});

expect(mockOnWarning).toHaveBeenCalledWith(true);
const helpText = wrapper
.find('[data-test-subj="valuesAutocompleteWildcardLabel"] div.euiFormHelpText')
.at(0);
expect(helpText.text()).toEqual(FILENAME_WILDCARD_WARNING);
expect(helpText.find('.euiToolTipAnchor')).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { paramIsValid } from '../param_is_valid';

const SINGLE_SELECTION = { asPlainText: true };

type Warning = string | React.ReactNode;
interface AutocompleteFieldWildcardProps {
placeholder: string;
selectedField: DataViewFieldBase | undefined;
Expand All @@ -43,7 +44,7 @@ interface AutocompleteFieldWildcardProps {
onChange: (arg: string) => void;
onError: (arg: boolean) => void;
onWarning: (arg: boolean) => void;
warning?: string;
warning?: Warning;
}

export const AutocompleteFieldWildcardComponent: React.FC<AutocompleteFieldWildcardProps> = memo(
Expand Down Expand Up @@ -103,7 +104,7 @@ export const AutocompleteFieldWildcardComponent: React.FC<AutocompleteFieldWildc
);

const handleWarning = useCallback(
(warn: string | undefined): void => {
(warn: Warning | undefined): void => {
onWarning(warn !== undefined);
},
[onWarning]
Expand Down Expand Up @@ -194,9 +195,7 @@ export const AutocompleteFieldWildcardComponent: React.FC<AutocompleteFieldWildc
if (onError != null) {
onError(false);
}
if (onWarning != null) {
onWarning(false);
}
onWarning(false);
}, [selectedField, onError, onWarning]);

const defaultInput = useMemo((): JSX.Element => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { i18n } from '@kbn/i18n';

export const FILENAME_WILDCARD_WARNING = i18n.translate('utils.filename.wildcardWarning', {
defaultMessage: `A wildcard in the filename will affect the endpoint's performance`,
defaultMessage: `Using wildcards in file paths can impact Endpoint performance`,
});

export const FILEPATH_WARNING = i18n.translate('utils.filename.pathWarning', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

import React, { useCallback, useMemo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip } from '@elastic/eui';
import styled from 'styled-components';
import {
ExceptionListType,
Expand Down Expand Up @@ -37,7 +38,11 @@ import {
FieldComponent,
OperatorComponent,
} from '@kbn/securitysolution-autocomplete';
import { OperatingSystem, validateFilePathInput } from '@kbn/securitysolution-utils';
import {
FILENAME_WILDCARD_WARNING,
OperatingSystem,
validateFilePathInput,
} from '@kbn/securitysolution-utils';
import { DataViewBase, DataViewFieldBase } from '@kbn/es-query';

import type { AutocompleteStart } from '../../../../../../../src/plugins/data/public';
Expand Down Expand Up @@ -268,6 +273,25 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
}
};

// show this when wildcard filename with matches operator
const getWildcardWarning = (precedingWarning: string): React.ReactNode => {
return (
<p>
{precedingWarning}{' '}
<EuiIconTip
type="iInCircle"
content={
<FormattedMessage
id="xpack.lists.exceptions.builder.exceptionMatchesOperator.warningMessage.wildcardInFilepath"
Comment thread
ashokaditya marked this conversation as resolved.
defaultMessage="To make a more efficient event filter, use multiple conditions and make them as specific as possible when using wildcards in the path values. For instance, adding a process.name or file.name field."
/>
}
size="m"
/>
</p>
);
};

const getFieldValueComboBox = (type: OperatorTypeEnum, isFirst: boolean): JSX.Element => {
switch (type) {
case OperatorTypeEnum.MATCH:
Expand Down Expand Up @@ -319,6 +343,9 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
[os] = osTypes as OperatingSystem[];
}
const warning = validateFilePathInput({ os, value: wildcardValue });
const actualWarning =
warning === FILENAME_WILDCARD_WARNING ? getWildcardWarning(warning) : warning;

return (
<AutocompleteFieldWildcardComponent
autocompleteService={autocompleteService}
Expand All @@ -331,7 +358,7 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
onError={handleError}
onChange={handleFieldWildcardValueChange}
onWarning={handleWarning}
warning={warning}
warning={actualWarning}
placeholder={i18n.EXCEPTION_FIELD_VALUE_PLACEHOLDER}
rowLabel={isFirst ? i18n.VALUE : undefined}
selectedField={entry.correspondingKeywordField ?? entry.field}
Expand Down