From 508695f958b5487c8b5361611cd4942fd9bac74d Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Thu, 12 Oct 2023 14:34:31 +0200 Subject: [PATCH 1/3] Locked Status and Assignee Controls for Alert Page (#7820) --- .../components/filter_group/constants.ts | 1 + .../filter_group/filter_by_assignees.test.tsx | 111 +++++++++++++++++ .../filter_group/filter_by_assignees.tsx | 117 ++++++++++++++++++ .../alerts_table/default_config.test.tsx | 42 +++++++ .../alerts_table/default_config.tsx | 27 ++++ .../detection_page_filters/index.tsx | 43 +++++-- .../detection_engine/detection_engine.tsx | 22 +++- 7 files changed, 352 insertions(+), 11 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts index 873355fa60a76..9eef5311b278b 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/constants.ts @@ -24,6 +24,7 @@ export const TEST_IDS = { EDIT: 'filter-group__context--edit', DISCARD: `filter-group__context--discard`, }, + FILTER_BY_ASSIGNEES_BUTTON: 'filter-popover-button-assignees', }; export const COMMON_OPTIONS_LIST_CONTROL_INPUTS: Partial = { diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx new file mode 100644 index 0000000000000..1f6e1aac14607 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx @@ -0,0 +1,111 @@ +/* + * 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 } from '@testing-library/react'; +import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; + +import { FilterByAssigneesPopover } from './filter_by_assignees'; +import { TEST_IDS } from './constants'; +import { TestProviders } from '../../mock'; + +const mockUserProfiles: UserProfileWithAvatar[] = [ + { + uid: 'user-id-1', + enabled: true, + user: { username: 'user1', full_name: 'User 1', email: 'user1@test.com' }, + data: {}, + }, + { + uid: 'user-id-2', + enabled: true, + user: { username: 'user2', full_name: 'User 2', email: 'user2@test.com' }, + data: {}, + }, + { + uid: 'user-id-3', + enabled: true, + user: { username: 'user3', full_name: 'User 3', email: 'user3@test.com' }, + data: {}, + }, +]; +jest.mock('../../../detections/containers/detection_engine/alerts/use_suggest_users', () => { + return { + useSuggestUsers: () => ({ + loading: false, + userProfiles: mockUserProfiles, + }), + }; +}); + +const renderFilterByAssigneesPopover = (alertAssignees: string[], onUsersChange = jest.fn()) => + render( + + + + ); + +describe('', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render closed popover component', () => { + const { getByTestId, queryByTestId } = renderFilterByAssigneesPopover([]); + + expect(getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON)).toBeInTheDocument(); + expect(queryByTestId('euiSelectableList')).not.toBeInTheDocument(); + }); + + it('should render opened popover component', () => { + const { getByTestId } = renderFilterByAssigneesPopover([]); + + getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON).click(); + expect(getByTestId('euiSelectableList')).toBeInTheDocument(); + }); + + it('should render assignees', () => { + const { getByTestId } = renderFilterByAssigneesPopover([]); + + getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON).click(); + + const assigneesList = getByTestId('euiSelectableList'); + expect(assigneesList).toHaveTextContent('User 1'); + expect(assigneesList).toHaveTextContent('user1@test.com'); + expect(assigneesList).toHaveTextContent('User 2'); + expect(assigneesList).toHaveTextContent('user2@test.com'); + expect(assigneesList).toHaveTextContent('User 3'); + expect(assigneesList).toHaveTextContent('user3@test.com'); + }); + + it('should call onUsersChange on clsing the popover', () => { + const onUsersChangeMock = jest.fn(); + const { getByTestId, getByText } = renderFilterByAssigneesPopover([], onUsersChangeMock); + + getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON).click(); + + getByText('User 1').click(); + getByText('User 2').click(); + getByText('User 3').click(); + getByText('User 3').click(); + getByText('User 2').click(); + getByText('User 1').click(); + + expect(onUsersChangeMock).toHaveBeenCalledTimes(6); + expect(onUsersChangeMock.mock.calls).toEqual([ + [['user-id-1']], + [['user-id-2', 'user-id-1']], + [['user-id-3', 'user-id-2', 'user-id-1']], + [['user-id-2', 'user-id-1']], + [['user-id-1']], + [[]], + ]); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx new file mode 100644 index 0000000000000..b0110c731c8c1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx @@ -0,0 +1,117 @@ +/* + * 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 { isEqual } from 'lodash/fp'; +import type { FC } from 'react'; +import React, { memo, useCallback, useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; +import { UserProfilesPopover } from '@kbn/user-profile-components'; + +import { EuiFilterButton } from '@elastic/eui'; +import { useSuggestUsers } from '../../../detections/containers/detection_engine/alerts/use_suggest_users'; +import { TEST_IDS } from './constants'; + +export interface FilterByAssigneesPopoverProps { + /** + * Ids of the users assigned to the alert + */ + existingAssigneesIds: string[]; + + /** + * Callback to handle changing of the assignees selection + */ + onUsersChange: (users: string[]) => void; +} + +/** + * The popover to filter alerts by assigned users + */ +export const FilterByAssigneesPopover: FC = memo( + ({ existingAssigneesIds, onUsersChange }) => { + const [searchTerm, setSearchTerm] = useState(''); + const { loading: isLoadingUsers, userProfiles } = useSuggestUsers(searchTerm); + + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const togglePopover = useCallback(() => setIsPopoverOpen((value) => !value), []); + + const [selectedAssignees, setSelectedAssignees] = useState([]); + useEffect(() => { + if (isLoadingUsers) { + return; + } + const assignees = userProfiles.filter((user) => existingAssigneesIds.includes(user.uid)); + setSelectedAssignees(assignees); + }, [existingAssigneesIds, isLoadingUsers, userProfiles]); + + const handleSelectedAssignees = useCallback( + (newAssignees: UserProfileWithAvatar[]) => { + if (!isEqual(newAssignees, selectedAssignees)) { + setSelectedAssignees(newAssignees); + onUsersChange(newAssignees.map((user) => user.uid)); + } + }, + [onUsersChange, selectedAssignees] + ); + + const selectedStatusMessage = useCallback( + (total: number) => + i18n.translate( + 'xpack.securitySolution.flyout.right.visualizations.assignees.totalUsersAssigned', + { + defaultMessage: '{total, plural, one {# filter} other {# filters}} selected', + values: { total }, + } + ), + [] + ); + + return ( + 0} + numActiveFilters={selectedAssignees.length} + > + {i18n.translate('xpack.securitySolution.filtersGroup.assignees.buttonTitle', { + defaultMessage: 'Assignees', + })} + + } + isOpen={isPopoverOpen} + closePopover={togglePopover} + panelStyle={{ + minWidth: 520, + }} + selectableProps={{ + onSearchChange: (term: string) => { + setSearchTerm(term); + }, + onChange: handleSelectedAssignees, + selectedStatusMessage, + options: userProfiles, + selectedOptions: selectedAssignees, + isLoading: isLoadingUsers, + height: 'full', + }} + /> + ); + } +); + +FilterByAssigneesPopover.displayName = 'FilterByAssigneesPopover'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx index 8807ccf0388d2..b4b0a07fd7ab2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx @@ -7,6 +7,7 @@ import type { ExistsFilter, Filter } from '@kbn/es-query'; import { + buildAlertAssigneesFilter, buildAlertsFilter, buildAlertStatusesFilter, buildAlertStatusFilter, @@ -158,6 +159,47 @@ describe('alerts default_config', () => { }); }); + describe('buildAlertAssigneesFilter', () => { + test('given an empty list of assignees ids will return an empty filter', () => { + const filters: Filter[] = buildAlertAssigneesFilter([]); + expect(filters).toHaveLength(0); + }); + + test('builds filter containing all assignees ids passed into function', () => { + const filters = buildAlertAssigneesFilter(['user-id-1', 'user-id-2', 'user-id-3']); + const expected = { + meta: { + alias: null, + disabled: false, + negate: false, + }, + query: { + bool: { + should: [ + { + term: { + 'kibana.alert.workflow_assignee_ids': 'user-id-1', + }, + }, + { + term: { + 'kibana.alert.workflow_assignee_ids': 'user-id-2', + }, + }, + { + term: { + 'kibana.alert.workflow_assignee_ids': 'user-id-3', + }, + }, + ], + }, + }, + }; + expect(filters).toHaveLength(1); + expect(filters[0]).toEqual(expected); + }); + }); + // TODO: move these tests to ../timelines/components/timeline/body/events/event_column_view.tsx // describe.skip('getAlertActions', () => { // let setEventsLoading: ({ eventIds, isLoading }: SetEventsLoadingProps) => void; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx index 10204204e9fc3..4288231eae7d7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx @@ -9,6 +9,7 @@ import { ALERT_BUILDING_BLOCK_TYPE, ALERT_WORKFLOW_STATUS, ALERT_RULE_RULE_ID, + ALERT_WORKFLOW_ASSIGNEE_IDS, } from '@kbn/rule-data-utils'; import type { Filter } from '@kbn/es-query'; @@ -152,6 +153,32 @@ export const buildThreatMatchFilter = (showOnlyThreatIndicatorAlerts: boolean): ] : []; +export const buildAlertAssigneesFilter = (assigneesIds: string[]): Filter[] => { + if (!assigneesIds.length) { + return []; + } + const combinedQuery = { + bool: { + should: assigneesIds.map((id) => ({ + term: { + [ALERT_WORKFLOW_ASSIGNEE_IDS]: id, + }, + })), + }, + }; + + return [ + { + meta: { + alias: null, + negate: false, + disabled: false, + }, + query: combinedQuery, + }, + ]; +}; + export const getAlertsDefaultModel = (license?: LicenseService): SubsetDataTableModel => ({ ...tableDefaults, columns: getColumns(license), diff --git a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx index 6e149b9866357..3bc83d4b8ffe2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx @@ -9,7 +9,9 @@ import type { ComponentProps } from 'react'; import React, { useEffect, useState, useCallback } from 'react'; import type { Filter } from '@kbn/es-query'; import { isEqual } from 'lodash'; -import { EuiFlexItem } from '@elastic/eui'; +import { EuiFilterGroup, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { FilterByAssigneesPopover } from '../../../common/components/filter_group/filter_by_assignees'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { FilterGroupLoading } from '../../../common/components/filter_group/loading'; import { useKibana } from '../../../common/lib/kibana'; @@ -20,7 +22,10 @@ import { useSourcererDataView } from '../../../common/containers/sourcerer'; type FilterItemSetProps = Omit< ComponentProps, 'initialControls' | 'dataViewId' ->; +> & { + assignees: string[]; + onAssigneesChange: (users: string[]) => void; +}; const SECURITY_ALERT_DATA_VIEW = { id: 'security_solution_alerts_dv', @@ -28,8 +33,9 @@ const SECURITY_ALERT_DATA_VIEW = { }; const FilterItemSetComponent = (props: FilterItemSetProps) => { - const { onFilterChange, ...restFilterItemGroupProps } = props; + const { assignees, onAssigneesChange, onFilterChange, ...restFilterItemGroupProps } = props; + const { euiTheme } = useEuiTheme(); const { indexPattern: { title }, dataViewId, @@ -89,12 +95,31 @@ const FilterItemSetComponent = (props: FilterItemSetProps) => { } return ( - + + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 5291c5326ae3f..4a10917b71422 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -31,6 +31,7 @@ import { tableDefaults, TableId, } from '@kbn/securitysolution-data-table'; +import { isEqual } from 'lodash'; import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../common/constants'; import { useDataTableFilters } from '../../../common/hooks/use_data_table_filters'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; @@ -62,6 +63,7 @@ import { showGlobalFilters, } from '../../../timelines/components/timeline/helpers'; import { + buildAlertAssigneesFilter, buildAlertStatusFilter, buildShowBuildingBlockFilter, buildThreatMatchFilter, @@ -135,6 +137,16 @@ const DetectionEnginePageComponent: React.FC = ({ const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); + const [assignees, setAssignees] = useState([]); + const handleSelectedAssignees = useCallback( + (newAssignees: string[]) => { + if (!isEqual(newAssignees, assignees)) { + setAssignees(newAssignees); + } + }, + [assignees] + ); + const arePageFiltersEnabled = useIsExperimentalFeatureEnabled('alertsPageFiltersEnabled'); // when arePageFiltersEnabled === false @@ -176,8 +188,9 @@ const DetectionEnginePageComponent: React.FC = ({ ...filters, ...buildShowBuildingBlockFilter(showBuildingBlockAlerts), ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), + ...buildAlertAssigneesFilter(assignees), ]; - }, [showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, filters]); + }, [assignees, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, filters]); const alertPageFilters = useMemo(() => { if (arePageFiltersEnabled) { @@ -247,8 +260,9 @@ const DetectionEnginePageComponent: React.FC = ({ ...buildShowBuildingBlockFilter(showBuildingBlockAlerts), ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), ...(alertPageFilters ?? []), + ...buildAlertAssigneesFilter(assignees), ], - [showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, alertPageFilters] + [assignees, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, alertPageFilters] ); const { signalIndexNeedsInit, pollForSignalIndex } = useSignalHelpers(); @@ -360,6 +374,8 @@ const DetectionEnginePageComponent: React.FC = ({ }} chainingSystem={'HIERARCHICAL'} onInit={setDetectionPageFilterHandler} + assignees={assignees} + onAssigneesChange={handleSelectedAssignees} /> ), [ @@ -374,6 +390,8 @@ const DetectionEnginePageComponent: React.FC = ({ timelinesUi, to, updatedAt, + assignees, + handleSelectedAssignees, ] ); From 688bbb0a1ce22eff3b2fc5019824ddcfdd69a3a6 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Wed, 18 Oct 2023 18:32:12 +0200 Subject: [PATCH 2/3] Fix types --- .../components/filter_group/filter_by_assignees.test.tsx | 8 ++++---- .../components/filter_group/filter_by_assignees.tsx | 8 ++++---- .../components/detection_page_filters/index.tsx | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx index 1f6e1aac14607..057d112c2ee09 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx @@ -42,7 +42,7 @@ jest.mock('../../../detections/containers/detection_engine/alerts/use_suggest_us }; }); -const renderFilterByAssigneesPopover = (alertAssignees: string[], onUsersChange = jest.fn()) => +const renderFilterByAssigneesPopover = (alertAssignees?: string[], onUsersChange = jest.fn()) => render( ', () => { }); it('should render closed popover component', () => { - const { getByTestId, queryByTestId } = renderFilterByAssigneesPopover([]); + const { getByTestId, queryByTestId } = renderFilterByAssigneesPopover(); expect(getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON)).toBeInTheDocument(); expect(queryByTestId('euiSelectableList')).not.toBeInTheDocument(); }); it('should render opened popover component', () => { - const { getByTestId } = renderFilterByAssigneesPopover([]); + const { getByTestId } = renderFilterByAssigneesPopover(); getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON).click(); expect(getByTestId('euiSelectableList')).toBeInTheDocument(); }); it('should render assignees', () => { - const { getByTestId } = renderFilterByAssigneesPopover([]); + const { getByTestId } = renderFilterByAssigneesPopover(); getByTestId(TEST_IDS.FILTER_BY_ASSIGNEES_BUTTON).click(); diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx index b0110c731c8c1..8fb691168dab9 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.tsx @@ -20,12 +20,12 @@ export interface FilterByAssigneesPopoverProps { /** * Ids of the users assigned to the alert */ - existingAssigneesIds: string[]; + existingAssigneesIds?: string[]; /** * Callback to handle changing of the assignees selection */ - onUsersChange: (users: string[]) => void; + onUsersChange?: (users: string[]) => void; } /** @@ -44,7 +44,7 @@ export const FilterByAssigneesPopover: FC = memo( if (isLoadingUsers) { return; } - const assignees = userProfiles.filter((user) => existingAssigneesIds.includes(user.uid)); + const assignees = userProfiles.filter((user) => existingAssigneesIds?.includes(user.uid)); setSelectedAssignees(assignees); }, [existingAssigneesIds, isLoadingUsers, userProfiles]); @@ -52,7 +52,7 @@ export const FilterByAssigneesPopover: FC = memo( (newAssignees: UserProfileWithAvatar[]) => { if (!isEqual(newAssignees, selectedAssignees)) { setSelectedAssignees(newAssignees); - onUsersChange(newAssignees.map((user) => user.uid)); + onUsersChange?.(newAssignees.map((user) => user.uid)); } }, [onUsersChange, selectedAssignees] diff --git a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx index 3bc83d4b8ffe2..c05ecd84e5d98 100644 --- a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.tsx @@ -23,8 +23,8 @@ type FilterItemSetProps = Omit< ComponentProps, 'initialControls' | 'dataViewId' > & { - assignees: string[]; - onAssigneesChange: (users: string[]) => void; + assignees?: string[]; + onAssigneesChange?: (users: string[]) => void; }; const SECURITY_ALERT_DATA_VIEW = { From 6cc91458e033bdf8c46cf7aa8c975aba81433a4d Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Wed, 18 Oct 2023 20:26:23 +0200 Subject: [PATCH 3/3] Fix tests --- .../filter_group/filter_by_assignees.test.tsx | 3 +- .../alert_bulk_assignees.test.tsx | 3 +- .../use_bulk_alert_assignees_items.test.tsx | 3 +- .../use_alert_assignees_actions.test.tsx | 3 +- .../detection_page_filters/index.test.tsx | 29 +++++++++++++++++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx index 057d112c2ee09..a8124767f11c6 100644 --- a/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filter_group/filter_by_assignees.test.tsx @@ -7,13 +7,12 @@ import React from 'react'; import { render } from '@testing-library/react'; -import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; import { FilterByAssigneesPopover } from './filter_by_assignees'; import { TEST_IDS } from './constants'; import { TestProviders } from '../../mock'; -const mockUserProfiles: UserProfileWithAvatar[] = [ +const mockUserProfiles = [ { uid: 'user-id-1', enabled: true, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.test.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.test.tsx index a3a76c4bea327..da40356d36c54 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_assignees.test.tsx @@ -6,7 +6,6 @@ */ import type { TimelineItem } from '@kbn/timelines-plugin/common'; -import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; import { act, fireEvent, render } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../mock'; @@ -17,7 +16,7 @@ import { ALERT_WORKFLOW_ASSIGNEE_IDS } from '@kbn/rule-data-utils'; jest.mock('../../../../detections/containers/detection_engine/alerts/use_suggest_users'); -const mockUserProfiles: UserProfileWithAvatar[] = [ +const mockUserProfiles = [ { uid: 'default-test-assignee-id-1', enabled: true, user: { username: 'user1' }, data: {} }, { uid: 'default-test-assignee-id-2', enabled: true, user: { username: 'user2' }, data: {} }, ]; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.test.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.test.tsx index 7a87744b49190..959fa06f849a3 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_assignees_items.test.tsx @@ -7,7 +7,6 @@ import { ALERT_WORKFLOW_ASSIGNEE_IDS } from '@kbn/rule-data-utils'; import { TestProviders } from '@kbn/timelines-plugin/public/mock'; -import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; import { act, fireEvent, render } from '@testing-library/react'; import { renderHook } from '@testing-library/react-hooks'; import type { @@ -21,7 +20,7 @@ import { useSuggestUsers } from '../../../../detections/containers/detection_eng jest.mock('./use_set_alert_assignees'); jest.mock('../../../../detections/containers/detection_engine/alerts/use_suggest_users'); -const mockUserProfiles: UserProfileWithAvatar[] = [ +const mockUserProfiles = [ { uid: 'user-id-1', enabled: true, user: { username: 'fakeUser1' }, data: {} }, { uid: 'user-id-2', enabled: true, user: { username: 'fakeUser2' }, data: {} }, ]; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_assignees_actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_assignees_actions.test.tsx index 5110f512a4610..37d775b978b16 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_assignees_actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_assignees_actions.test.tsx @@ -6,7 +6,6 @@ */ import { TestProviders } from '@kbn/timelines-plugin/public/mock'; -import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; import { renderHook } from '@testing-library/react-hooks'; import type { UseAlertAssigneesActionsProps } from './use_alert_assignees_actions'; import { useAlertAssigneesActions } from './use_alert_assignees_actions'; @@ -23,7 +22,7 @@ jest.mock('../../../containers/detection_engine/alerts/use_alerts_privileges'); jest.mock('../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees'); jest.mock('../../../containers/detection_engine/alerts/use_suggest_users'); -const mockUserProfiles: UserProfileWithAvatar[] = [ +const mockUserProfiles = [ { uid: 'user-id-1', enabled: true, user: { username: 'fakeUser1' }, data: {} }, { uid: 'user-id-2', enabled: true, user: { username: 'fakeUser2' }, data: {} }, ]; diff --git a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.test.tsx index 984e19a879637..3c50ab7ef51d3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/detection_page_filters/index.test.tsx @@ -23,6 +23,35 @@ jest.mock('../../../common/components/filter_group'); jest.mock('../../../common/lib/kibana'); +const mockUserProfiles = [ + { + uid: 'user-id-1', + enabled: true, + user: { username: 'user1', full_name: 'User 1', email: 'user1@test.com' }, + data: {}, + }, + { + uid: 'user-id-2', + enabled: true, + user: { username: 'user2', full_name: 'User 2', email: 'user2@test.com' }, + data: {}, + }, + { + uid: 'user-id-3', + enabled: true, + user: { username: 'user3', full_name: 'User 3', email: 'user3@test.com' }, + data: {}, + }, +]; +jest.mock('../../containers/detection_engine/alerts/use_suggest_users', () => { + return { + useSuggestUsers: () => ({ + loading: false, + userProfiles: mockUserProfiles, + }), + }; +}); + const basicKibanaServicesMock = createStartServicesMock(); const getFieldByNameMock = jest.fn(() => true);