diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx new file mode 100644 index 0000000000000..3c6dc68edefcc --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx @@ -0,0 +1,99 @@ +/* + * 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 { fireEvent, render } from '@testing-library/react'; +import React from 'react'; +import { PickEventType } from './pick_events'; +import { + createSecuritySolutionStorageMock, + kibanaObservable, + mockGlobalState, + SUB_PLUGINS_REDUCER, + TestProviders, +} from '../../../../common/mock'; +import { TimelineEventsType } from '../../../../../common'; +import { createStore } from '../../../../common/store'; +import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; + +describe('pick_events', () => { + const defaultProps = { + eventType: 'all' as TimelineEventsType, + onChangeEventTypeAndIndexesName: jest.fn(), + }; + const initialPatterns = [ + ...mockGlobalState.sourcerer.sourcererScopes[SourcererScopeName.timeline].selectedPatterns, + mockGlobalState.sourcerer.signalIndexName, + ]; + const { storage } = createSecuritySolutionStorageMock(); + const state = { + ...mockGlobalState, + sourcerer: { + ...mockGlobalState.sourcerer, + kibanaIndexPatterns: [ + { id: '1234', title: 'auditbeat-*' }, + { id: '9100', title: 'filebeat-*' }, + { id: '9100', title: 'auditbeat-*,filebeat-*' }, + { id: '5678', title: 'auditbeat-*,.siem-signals-default' }, + ], + configIndexPatterns: + mockGlobalState.sourcerer.sourcererScopes[SourcererScopeName.timeline].selectedPatterns, + signalIndexName: mockGlobalState.sourcerer.signalIndexName, + sourcererScopes: { + ...mockGlobalState.sourcerer.sourcererScopes, + [SourcererScopeName.timeline]: { + ...mockGlobalState.sourcerer.sourcererScopes[SourcererScopeName.timeline], + loading: false, + selectedPatterns: ['filebeat-*'], + }, + }, + }, + }; + const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); + beforeEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + }); + it('renders', () => { + const wrapper = render( + + + + ); + fireEvent.click(wrapper.getByTestId('sourcerer-timeline-trigger')); + expect(wrapper.getByTestId('timeline-sourcerer').textContent).toEqual( + initialPatterns.sort().join('') + ); + }); + it('correctly filters options', () => { + const wrapper = render( + + + + ); + fireEvent.click(wrapper.getByTestId('sourcerer-timeline-trigger')); + fireEvent.click(wrapper.getByTestId('comboBoxToggleListButton')); + const optionNodes = wrapper.getAllByTestId('sourcerer-option'); + expect(optionNodes.length).toBe(9); + }); + it('reset button works', () => { + const wrapper = render( + + + + ); + fireEvent.click(wrapper.getByTestId('sourcerer-timeline-trigger')); + expect(wrapper.getByTestId('timeline-sourcerer').textContent).toEqual('filebeat-*'); + + fireEvent.click(wrapper.getByTestId('sourcerer-reset')); + expect(wrapper.getByTestId('timeline-sourcerer').textContent).toEqual( + initialPatterns.sort().join('') + ); + fireEvent.click(wrapper.getByTestId('comboBoxToggleListButton')); + const optionNodes = wrapper.getAllByTestId('sourcerer-option'); + expect(optionNodes.length).toBe(2); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx index 5682bdb91ff58..dbe04eccac521 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx @@ -144,7 +144,7 @@ const PickEventTypeComponents: React.FC = ({ ...kibanaIndexPatterns.map((kip) => kip.title), signalIndexName, ].reduce>>((acc, index) => { - if (index != null && !acc.some((o) => o.label.includes(index))) { + if (index != null && !acc.some((o) => o.label === index)) { return [...acc, { label: index, value: index }]; } return acc; @@ -153,16 +153,15 @@ const PickEventTypeComponents: React.FC = ({ ); const renderOption = useCallback( - (option) => { - const { value } = option; + ({ value }) => { if (kibanaIndexPatterns.some((kip) => kip.title === value)) { return ( - <> + {value} - + ); } - return <>{value}; + return {value}; }, [kibanaIndexPatterns] ); @@ -193,14 +192,14 @@ const PickEventTypeComponents: React.FC = ({ setFilterEventType(filter); if (filter === 'all') { setSelectedOptions( - [...configIndexPatterns, signalIndexName ?? ''].map((indexSelected) => ({ + [...configIndexPatterns.sort(), signalIndexName ?? ''].map((indexSelected) => ({ label: indexSelected, value: indexSelected, })) ); } else if (filter === 'raw') { setSelectedOptions( - configIndexPatterns.map((indexSelected) => ({ + configIndexPatterns.sort().map((indexSelected) => ({ label: indexSelected, value: indexSelected, })) @@ -240,14 +239,8 @@ const PickEventTypeComponents: React.FC = ({ }, [filterEventType, onChangeEventTypeAndIndexesName, selectedOptions]); const resetDataSources = useCallback(() => { - setSelectedOptions( - sourcererScope.selectedPatterns.map((indexSelected) => ({ - label: indexSelected, - value: indexSelected, - })) - ); - setFilterEventType(eventType); - }, [eventType, sourcererScope.selectedPatterns]); + onChangeFilter('all'); + }, [onChangeFilter]); const comboBox = useMemo( () => (