From daf372adba697bf2d5318dc91c16aebbd3e0598f Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 17 Jan 2022 13:14:33 -0500 Subject: [PATCH] [Security Solution] Fix signals index initialization bug (#123087) (#123175) (cherry picked from commit fef96e99e387d419f010d38b69e6d3cc0d0c91a6) Co-authored-by: Steph Milovic --- .../app/home/global_header/index.test.tsx | 4 ++ .../components/sourcerer/index.test.tsx | 63 ++++++++++++++++++- .../common/components/sourcerer/index.tsx | 9 +++ .../timeline/eql_tab_content/index.test.tsx | 3 + .../timeline/query_tab_content/index.test.tsx | 3 + 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx b/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx index cfcf5307de8d4..2d6ca63c82bdb 100644 --- a/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/app/home/global_header/index.test.tsx @@ -41,6 +41,10 @@ jest.mock('../../../common/containers/source', () => ({ useFetchIndex: () => [false, { indicesExist: true, indexPatterns: mockIndexPattern }], })); +jest.mock('../../../common/containers/sourcerer/use_signal_helpers', () => ({ + useSignalHelpers: () => ({ signalIndexNeedsInit: false }), +})); + jest.mock('react-reverse-portal', () => ({ InPortal: ({ children }: { children: React.ReactNode }) => <>{children}, OutPortal: ({ children }: { children: React.ReactNode }) => <>{children}, diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx index 7d3dc9641929a..f4707272d2c24 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx @@ -21,10 +21,12 @@ import { createStore } from '../../store'; import { EuiSuperSelectOption } from '@elastic/eui/src/components/form/super_select/super_select_control'; import { waitFor } from '@testing-library/dom'; import { useSourcererDataView } from '../../containers/sourcerer'; +import { useSignalHelpers } from '../../containers/sourcerer/use_signal_helpers'; const mockDispatch = jest.fn(); jest.mock('../../containers/sourcerer'); +jest.mock('../../containers/sourcerer/use_signal_helpers'); const mockUseUpdateDataView = jest.fn().mockReturnValue(() => true); jest.mock('./use_update_data_view', () => ({ useUpdateDataView: () => mockUseUpdateDataView, @@ -81,10 +83,12 @@ const sourcererDataView = { describe('Sourcerer component', () => { const { storage } = createSecuritySolutionStorageMock(); - + const pollForSignalIndexMock = jest.fn(); beforeEach(() => { store = createStore(mockGlobalState, SUB_PLUGINS_REDUCER, kibanaObservable, storage); (useSourcererDataView as jest.Mock).mockReturnValue(sourcererDataView); + (useSignalHelpers as jest.Mock).mockReturnValue({ signalIndexNeedsInit: false }); + jest.clearAllMocks(); }); @@ -570,6 +574,63 @@ describe('Sourcerer component', () => { .exists() ).toBeFalsy(); }); + + it('does not poll for signals index if pollForSignalIndex is not defined', () => { + (useSignalHelpers as jest.Mock).mockReturnValue({ + signalIndexNeedsInit: false, + }); + + mount( + + + + ); + + expect(pollForSignalIndexMock).toHaveBeenCalledTimes(0); + }); + + it('does not poll for signals index if it does not exist and scope is default', () => { + (useSignalHelpers as jest.Mock).mockReturnValue({ + pollForSignalIndex: pollForSignalIndexMock, + signalIndexNeedsInit: false, + }); + + mount( + + + + ); + + expect(pollForSignalIndexMock).toHaveBeenCalledTimes(0); + }); + + it('polls for signals index if it does not exist and scope is timeline', () => { + (useSignalHelpers as jest.Mock).mockReturnValue({ + pollForSignalIndex: pollForSignalIndexMock, + signalIndexNeedsInit: false, + }); + + mount( + + + + ); + expect(pollForSignalIndexMock).toHaveBeenCalledTimes(1); + }); + + it('polls for signals index if it does not exist and scope is detections', () => { + (useSignalHelpers as jest.Mock).mockReturnValue({ + pollForSignalIndex: pollForSignalIndexMock, + signalIndexNeedsInit: false, + }); + + mount( + + + + ); + expect(pollForSignalIndexMock).toHaveBeenCalledTimes(1); + }); }); describe('sourcerer on alerts page or rules details page', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx index 924601758c730..ad3b11a74e81d 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx @@ -28,6 +28,7 @@ import { useSourcererDataView } from '../../containers/sourcerer'; import { useUpdateDataView } from './use_update_data_view'; import { Trigger } from './trigger'; import { AlertsCheckbox, SaveButtons, SourcererCallout } from './sub_components'; +import { useSignalHelpers } from '../../containers/sourcerer/use_signal_helpers'; export interface SourcererComponentProps { scope: sourcererModel.SourcererScopeName; @@ -50,6 +51,14 @@ export const Sourcerer = React.memo(({ scope: scopeId } }, } = useDeepEqualSelector((state) => sourcererScopeSelector(state, scopeId)); + const { pollForSignalIndex } = useSignalHelpers(); + + useEffect(() => { + if (pollForSignalIndex != null && (isTimelineSourcerer || isDetectionsSourcerer)) { + pollForSignalIndex(); + } + }, [isDetectionsSourcerer, isTimelineSourcerer, pollForSignalIndex]); + const { activePatterns, indicesExist, loading } = useSourcererDataView(scopeId); const [missingPatterns, setMissingPatterns] = useState( activePatterns && activePatterns.length > 0 diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx index 0096b152b3236..dba9f99681a0c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx @@ -35,6 +35,9 @@ jest.mock('../body/events/index', () => ({ })); jest.mock('../../../../common/containers/sourcerer'); +jest.mock('../../../../common/containers/sourcerer/use_signal_helpers', () => ({ + useSignalHelpers: () => ({ signalIndexNeedsInit: false }), +})); const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock; jest.mock('use-resize-observer/polyfilled'); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx index d1741c399dbab..a32e77a107a43 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx @@ -38,6 +38,9 @@ jest.mock('../body/events/index', () => ({ })); jest.mock('../../../../common/containers/sourcerer'); +jest.mock('../../../../common/containers/sourcerer/use_signal_helpers', () => ({ + useSignalHelpers: () => ({ signalIndexNeedsInit: false }), +})); const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock; jest.mock('use-resize-observer/polyfilled');