From 238152287d7e44dd55d56bda9a9089f2cb8f4f84 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 23 Aug 2021 11:38:01 -0700 Subject: [PATCH 01/19] [tests] prevent unhandled rejection (#109560) Co-authored-by: spalger Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../detection_engine_api_integration/utils.ts | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/utils.ts b/x-pack/test/detection_engine_api_integration/utils.ts index a067ac5974ac64..a851b838867a16 100644 --- a/x-pack/test/detection_engine_api_integration/utils.ts +++ b/x-pack/test/detection_engine_api_integration/utils.ts @@ -767,26 +767,22 @@ export const waitFor = async ( maxTimeout: number = 20000, timeoutWait: number = 10 ): Promise => { - await new Promise(async (resolve, reject) => { - let found = false; - let numberOfTries = 0; - while (!found && numberOfTries < Math.floor(maxTimeout / timeoutWait)) { - const itPasses = await functionToTest(); - if (itPasses) { - found = true; - } else { - numberOfTries++; - } - await new Promise((resolveTimeout) => setTimeout(resolveTimeout, timeoutWait)); - } - if (found) { - resolve(); + let found = false; + let numberOfTries = 0; + + while (!found && numberOfTries < Math.floor(maxTimeout / timeoutWait)) { + if (await functionToTest()) { + found = true; } else { - reject( - new Error(`timed out waiting for function condition to be true within ${functionName}`) - ); + numberOfTries++; } - }); + + await new Promise((resolveTimeout) => setTimeout(resolveTimeout, timeoutWait)); + } + + if (!found) { + throw new Error(`timed out waiting for function condition to be true within ${functionName}`); + } }; /** From a0bd0affdd9de5d051cd1ddb290c97e7c5cdfc8b Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Mon, 23 Aug 2021 12:38:56 -0600 Subject: [PATCH 02/19] [Security Solution] [Bugfix] Fix analyzer missing from alert table (#109183) * fix n test heyyyy * more dead code * fix type things * change field type to const * type fix --- .../common/components/events_viewer/index.tsx | 3 +- .../t_grid/integrated/index.test.tsx | 67 ++++++++++ .../components/t_grid/integrated/index.tsx | 105 ++++++++------- .../components/t_grid/standalone/index.tsx | 4 +- .../public/components/t_grid/styles.tsx | 4 +- x-pack/plugins/timelines/public/mock/index.ts | 1 + .../plugins/timelines/public/mock/t_grid.ts | 123 ++++++++++++++++++ 7 files changed, 248 insertions(+), 59 deletions(-) create mode 100644 x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx create mode 100644 x-pack/plugins/timelines/public/mock/t_grid.ts diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index a20055d05afaba..70fd80a13555be 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -116,7 +116,7 @@ const StatefulEventsViewerComponent: React.FC = ({ selectedPatterns, loading: isLoadingIndexPattern, } = useSourcererScope(scopeId); - const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen(); + const { globalFullScreen } = useGlobalFullScreen(); // TODO: Once we are past experimental phase this code should be removed const tGridEnabled = useIsExperimentalFeatureEnabled('tGridEnabled'); const tGridEventRenderedViewEnabled = useIsExperimentalFeatureEnabled( @@ -180,7 +180,6 @@ const StatefulEventsViewerComponent: React.FC = ({ onRuleChange, renderCellValue, rowRenderers, - setGlobalFullScreen, start, sort, additionalFilters, diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx new file mode 100644 index 00000000000000..e0c221c95e6a71 --- /dev/null +++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx @@ -0,0 +1,67 @@ +/* + * 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 React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TGridIntegrated, TGridIntegratedProps } from './index'; +import { TestProviders, tGridIntegratedProps } from '../../../mock'; + +const mockId = tGridIntegratedProps.id; +jest.mock('../../../container', () => ({ + useTimelineEvents: () => [ + false, + { + id: mockId, + inspect: { + dsl: [], + response: [], + }, + totalCount: -1, + pageInfo: { + activePage: 0, + querySize: 0, + }, + events: [], + updatedAt: 0, + }, + ], +})); +jest.mock('../helpers', () => { + const original = jest.requireActual('../helpers'); + return { + ...original, + getCombinedFilterQuery: () => ({ + bool: { + must: [], + filter: [], + }, + }), + buildCombinedQuery: () => ({ + filterQuery: '{"bool":{"must":[],"filter":[]}}', + }), + }; +}); +const defaultProps: TGridIntegratedProps = tGridIntegratedProps; +describe('integrated t_grid', () => { + const dataTestSubj = 'right-here-dawg'; + it('does not render graphOverlay if graphOverlay=null', () => { + render( + + + + ); + expect(screen.queryByTestId(dataTestSubj)).toBeNull(); + }); + it('does render graphOverlay if graphOverlay=React.ReactNode', () => { + render( + + } /> + + ); + expect(screen.queryByTestId(dataTestSubj)).not.toBeNull(); + }); +}); diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx index b2e6b592c0f456..cc34b32b048acf 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx @@ -56,8 +56,6 @@ import { SummaryViewSelector, ViewSelection } from '../event_rendered_view/selec const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped; -export const EVENTS_VIEWER_HEADER_HEIGHT = 90; // px - const TitleText = styled.span` margin-right: 12px; `; @@ -101,8 +99,10 @@ const ScrollableFlexItem = styled(EuiFlexItem)` const SECURITY_ALERTS_CONSUMERS = [AlertConsumers.SIEM]; export interface TGridIntegratedProps { + additionalFilters: React.ReactNode; browserFields: BrowserFields; columns: ColumnHeaderOptions[]; + data?: DataPublicPluginStart; dataProviders: DataProvider[]; defaultCellActions?: TGridCellAction[]; deletedEventIds: Readonly; @@ -110,9 +110,12 @@ export interface TGridIntegratedProps { end: string; entityType: EntityType; filters: Filter[]; + filterStatus?: AlertStatus; globalFullScreen: boolean; + // If truthy, the graph viewer (Resolver) is showing + graphEventId: string | undefined; graphOverlay?: React.ReactNode; - filterStatus?: AlertStatus; + hasAlertsCrud: boolean; height?: number; id: TimelineId; indexNames: string[]; @@ -122,36 +125,35 @@ export interface TGridIntegratedProps { itemsPerPage: number; itemsPerPageOptions: number[]; kqlMode: 'filter' | 'search'; - query: Query; + leadingControlColumns?: ControlColumnProps[]; onRuleChange?: () => void; + query: Query; renderCellValue: (props: CellValueElementProps) => React.ReactNode; rowRenderers: RowRenderer[]; - setGlobalFullScreen: (fullscreen: boolean) => void; - start: string; sort: Sort[]; - additionalFilters: React.ReactNode; - // If truthy, the graph viewer (Resolver) is showing - graphEventId: string | undefined; - leadingControlColumns?: ControlColumnProps[]; - trailingControlColumns?: ControlColumnProps[]; - data?: DataPublicPluginStart; + start: string; tGridEventRenderedViewEnabled: boolean; - hasAlertsCrud: boolean; + trailingControlColumns?: ControlColumnProps[]; unit?: (n: number) => string; } const TGridIntegratedComponent: React.FC = ({ + additionalFilters, browserFields, columns, - defaultCellActions, + data, dataProviders, + defaultCellActions, deletedEventIds, docValueFields, end, entityType, filters, - globalFullScreen, filterStatus, + globalFullScreen, + graphEventId, + graphOverlay = null, + hasAlertsCrud, id, indexNames, indexPattern, @@ -160,21 +162,15 @@ const TGridIntegratedComponent: React.FC = ({ itemsPerPage, itemsPerPageOptions, kqlMode, + leadingControlColumns, onRuleChange, query, renderCellValue, rowRenderers, - setGlobalFullScreen, - start, sort, - additionalFilters, - graphOverlay = null, - graphEventId, - leadingControlColumns, - trailingControlColumns, + start, tGridEventRenderedViewEnabled, - data, - hasAlertsCrud, + trailingControlColumns, unit, }) => { const dispatch = useDispatch(); @@ -236,34 +232,36 @@ const TGridIntegratedComponent: React.FC = ({ ] = useTimelineEvents({ // We rely on entityType to determine Events vs Alerts alertConsumers: SECURITY_ALERTS_CONSUMERS, + data, docValueFields, + endDate: end, entityType, fields, filterQuery: combinedQueries!.filterQuery, id, indexNames, limit: itemsPerPage, + skip: !canQueryTimeline, sort: sortField, startDate: start, - endDate: end, - skip: !canQueryTimeline, - data, }); - const filterQuery = useMemo(() => { - return getCombinedFilterQuery({ - config: esQuery.getEsQueryConfig(uiSettings), - dataProviders, - indexPattern, - browserFields, - filters, - kqlQuery: query, - kqlMode, - isEventViewer: true, - from: start, - to: end, - }); - }, [uiSettings, dataProviders, indexPattern, browserFields, filters, start, end, query, kqlMode]); + const filterQuery = useMemo( + () => + getCombinedFilterQuery({ + config: esQuery.getEsQueryConfig(uiSettings), + browserFields, + dataProviders, + filters, + from: start, + indexPattern, + isEventViewer: true, + kqlMode, + kqlQuery: query, + to: end, + }), + [uiSettings, dataProviders, indexPattern, browserFields, filters, start, end, query, kqlMode] + ); const totalCountMinusDeleted = useMemo( () => (totalCount > 0 ? totalCount - deletedEventIds.length : 0), @@ -292,6 +290,7 @@ const TGridIntegratedComponent: React.FC = ({ > {loading && } + {graphOverlay} {canQueryTimeline ? ( <> = ({ data-test-subj={`events-container-loading-${loading}`} > - + - + {!resolverIsShowing(graphEventId) && additionalFilters} {tGridEventRenderedViewEnabled && entityType === 'alerts' && ( - + )} @@ -340,33 +339,33 @@ const TGridIntegratedComponent: React.FC = ({ ) : ( <> {tableView === 'gridView' && (