Skip to content

Commit 6bed3c0

Browse files
committed
Fix small bugs and improve tests
1 parent beb285c commit 6bed3c0

File tree

7 files changed

+90
-33
lines changed

7 files changed

+90
-33
lines changed

x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.test.tsx

+72-6
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,38 @@
55
* 2.0.
66
*/
77

8-
import { mockRiskScoreState } from '../../../flyout/entity_details/mocks';
8+
import {
9+
mockHostRiskScoreState,
10+
mockUserRiskScoreState,
11+
} from '../../../flyout/entity_details/mocks';
912
import { render } from '@testing-library/react';
1013
import React from 'react';
1114
import { TestProviders } from '../../../common/mock';
1215
import { RiskSummary } from './risk_summary';
16+
import type {
17+
LensAttributes,
18+
VisualizationEmbeddableProps,
19+
} from '../../../common/components/visualization_actions/types';
1320

14-
jest.mock('../../../common/components/visualization_actions/visualization_embeddable');
21+
const mockVisualizationEmbeddable = jest
22+
.fn()
23+
.mockReturnValue(<div data-test-subj="visualization-embeddable" />);
24+
25+
jest.mock('../../../common/components/visualization_actions/visualization_embeddable', () => ({
26+
VisualizationEmbeddable: (props: VisualizationEmbeddableProps) =>
27+
mockVisualizationEmbeddable(props),
28+
}));
1529

1630
describe('RiskSummary', () => {
31+
beforeEach(() => {
32+
mockVisualizationEmbeddable.mockClear();
33+
});
34+
1735
it('renders risk summary table', () => {
1836
const { getByTestId } = render(
1937
<TestProviders>
2038
<RiskSummary
21-
riskScoreData={mockRiskScoreState}
39+
riskScoreData={mockHostRiskScoreState}
2240
queryId={'testQuery'}
2341
openDetailsPanel={() => {}}
2442
/>
@@ -34,7 +52,7 @@ describe('RiskSummary', () => {
3452
const { getByTestId } = render(
3553
<TestProviders>
3654
<RiskSummary
37-
riskScoreData={{ ...mockRiskScoreState, data: undefined }}
55+
riskScoreData={{ ...mockHostRiskScoreState, data: undefined }}
3856
queryId={'testQuery'}
3957
openDetailsPanel={() => {}}
4058
/>
@@ -47,7 +65,7 @@ describe('RiskSummary', () => {
4765
const { getByTestId } = render(
4866
<TestProviders>
4967
<RiskSummary
50-
riskScoreData={mockRiskScoreState}
68+
riskScoreData={mockHostRiskScoreState}
5169
queryId={'testQuery'}
5270
openDetailsPanel={() => {}}
5371
/>
@@ -61,7 +79,7 @@ describe('RiskSummary', () => {
6179
const { getByTestId } = render(
6280
<TestProviders>
6381
<RiskSummary
64-
riskScoreData={mockRiskScoreState}
82+
riskScoreData={mockHostRiskScoreState}
6583
queryId={'testQuery'}
6684
openDetailsPanel={() => {}}
6785
/>
@@ -70,4 +88,52 @@ describe('RiskSummary', () => {
7088

7189
expect(getByTestId('risk-summary-updatedAt')).toHaveTextContent('Updated Nov 8, 1989');
7290
});
91+
92+
it('builds lens attributes for host risk score', () => {
93+
render(
94+
<TestProviders>
95+
<RiskSummary
96+
riskScoreData={mockHostRiskScoreState}
97+
queryId={'testQuery'}
98+
openDetailsPanel={() => {}}
99+
/>
100+
</TestProviders>
101+
);
102+
103+
const lensAttributes: LensAttributes =
104+
mockVisualizationEmbeddable.mock.calls[0][0].lensAttributes;
105+
const datasourceLayers = Object.values(lensAttributes.state.datasourceStates.formBased.layers);
106+
const firstColumn = Object.values(datasourceLayers[0].columns)[0];
107+
108+
expect(lensAttributes.state.query.query).toEqual('host.name: test');
109+
expect(firstColumn).toEqual(
110+
expect.objectContaining({
111+
sourceField: 'host.risk.calculated_score_norm',
112+
})
113+
);
114+
});
115+
116+
it('builds lens attributes for user risk score', () => {
117+
render(
118+
<TestProviders>
119+
<RiskSummary
120+
riskScoreData={mockUserRiskScoreState}
121+
queryId={'testQuery'}
122+
openDetailsPanel={() => {}}
123+
/>
124+
</TestProviders>
125+
);
126+
127+
const lensAttributes: LensAttributes =
128+
mockVisualizationEmbeddable.mock.calls[0][0].lensAttributes;
129+
const datasourceLayers = Object.values(lensAttributes.state.datasourceStates.formBased.layers);
130+
const firstColumn = Object.values(datasourceLayers[0].columns)[0];
131+
132+
expect(lensAttributes.state.query.query).toEqual('user.name: test');
133+
expect(firstColumn).toEqual(
134+
expect.objectContaining({
135+
sourceField: 'user.risk.calculated_score_norm',
136+
})
137+
);
138+
});
73139
});

x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx

+10-5
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ interface TableItem {
4848
const LENS_VISUALIZATION_HEIGHT = 126; // Static height in pixels specified by design
4949
const LAST_30_DAYS = { from: 'now-30d', to: 'now' };
5050

51-
function isUserRiskData(riskData: UserRiskScore | HostRiskScore): riskData is UserRiskScore {
52-
return (riskData as UserRiskScore).user !== undefined;
51+
function isUserRiskData(
52+
riskData: UserRiskScore | HostRiskScore | undefined
53+
): riskData is UserRiskScore {
54+
return !!riskData && (riskData as UserRiskScore).user !== undefined;
5355
}
5456

5557
const getEntityData = (riskData: UserRiskScore | HostRiskScore | undefined) => {
@@ -69,13 +71,16 @@ const RiskSummaryComponent = <T extends RiskScoreEntity>({
6971
const { euiTheme } = useEuiTheme();
7072

7173
const lensAttributes = useMemo(() => {
74+
const entityName = entityData?.name ?? '';
75+
const fieldName = isUserRiskData(riskData) ? 'user.name' : 'host.name';
76+
7277
return getRiskScoreSummaryAttributes({
7378
severity: entityData?.risk?.calculated_level,
74-
query: `user.name: ${entityData?.name}`,
79+
query: `${fieldName}: ${entityName}`,
7580
spaceId: 'default',
76-
riskEntity: RiskScoreEntity.user,
81+
riskEntity: isUserRiskData(riskData) ? RiskScoreEntity.user : RiskScoreEntity.host,
7782
});
78-
}, [entityData]);
83+
}, [entityData?.name, entityData?.risk?.calculated_level, riskData]);
7984

8085
const columns: Array<EuiBasicTableColumn<TableItem>> = useMemo(
8186
() => [

x-pack/plugins/security_solution/public/flyout/entity_details/mocks/index.ts

-15
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,6 @@ export const mockHostRiskScoreState: RiskScoreState<RiskScoreEntity.host> = {
9898
loading: false,
9999
};
100100

101-
export const mockRiskScoreState = {
102-
data: [hostRiskScore],
103-
inspect: {
104-
dsl: [],
105-
response: [],
106-
},
107-
isInspected: false,
108-
refetch: () => {},
109-
totalCount: 0,
110-
isModuleEnabled: true,
111-
isAuthorized: true,
112-
isDeprecated: false,
113-
loading: false,
114-
};
115-
116101
const hostMetadata: HostMetadataInterface = {
117102
'@timestamp': 1036358673463478,
118103

x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import { TestProviders } from '../../../common/mock';
1212
import {
1313
managedUserDetails,
1414
mockManagedUserData,
15-
mockObservedUser,
1615
} from '../../../timelines/components/side_panel/new_user_detail/__mocks__';
1716
import { UserPanelHeader } from './header';
17+
import { mockObservedUser } from './mocks';
1818

1919
const mockProps = {
2020
userName: 'test',

x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th
1010
import { getOr } from 'lodash/fp';
1111
import React, { useCallback, useMemo } from 'react';
1212
import styled from 'styled-components';
13+
import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score';
1314
import type { HostItem } from '../../../../common/search_strategy';
1415
import { buildHostNamesFilter, RiskScoreEntity } from '../../../../common/search_strategy';
1516
import { DEFAULT_DARK_MODE } from '../../../../common/constants';

x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import React, { useMemo } from 'react';
1919
import { FormattedMessage } from '@kbn/i18n-react';
2020
import { css } from '@emotion/css';
21-
import type { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_details_left/tabs';
21+
import type { EntityDetailsLeftPanelTab } from '../../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
2222
import { UserAssetTableType } from '../../../../explore/users/store/model';
2323
import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details';
2424
import { ManagedUserDatasetKey } from '../../../../../common/search_strategy/security_solution/users/managed_details';
@@ -47,7 +47,7 @@ export const ManagedUser = ({
4747
managedUser: ManagedUserData;
4848
contextID: string;
4949
isDraggable: boolean;
50-
openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void;
50+
openDetailsPanel: (tab: EntityDetailsLeftPanelTab) => void;
5151
}) => {
5252
const entraManagedUser = managedUser.data?.[ManagedUserDatasetKey.ENTRA];
5353
const oktaManagedUser = managedUser.data?.[ManagedUserDatasetKey.OKTA];

x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import React from 'react';
1111
import { css } from '@emotion/react';
1212
import { FormattedMessage } from '@kbn/i18n-react';
1313
import { get } from 'lodash/fp';
14-
import { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_details_left/tabs';
14+
import { EntityDetailsLeftPanelTab } from '../../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
1515
import { ExpandablePanel } from '../../../../flyout/shared/components/expandable_panel';
1616
import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details';
1717

@@ -23,7 +23,7 @@ interface ManagedUserAccordionProps {
2323
title: string;
2424
managedUser: ManagedUserFields;
2525
tableType: UserAssetTableType;
26-
openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void;
26+
openDetailsPanel: (tab: EntityDetailsLeftPanelTab) => void;
2727
}
2828

2929
export const ManagedUserAccordion: React.FC<ManagedUserAccordionProps> = ({
@@ -66,8 +66,8 @@ export const ManagedUserAccordion: React.FC<ManagedUserAccordionProps> = ({
6666
callback: () =>
6767
openDetailsPanel(
6868
tableType === UserAssetTableType.assetOkta
69-
? UserDetailsLeftPanelTab.OKTA
70-
: UserDetailsLeftPanelTab.ENTRA
69+
? EntityDetailsLeftPanelTab.OKTA
70+
: EntityDetailsLeftPanelTab.ENTRA
7171
),
7272
tooltip: (
7373
<FormattedMessage

0 commit comments

Comments
 (0)