Skip to content

Commit

Permalink
more comments
Browse files Browse the repository at this point in the history
  • Loading branch information
christineweng committed Feb 20, 2024
1 parent 595df9c commit bba0226
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import type { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common';
import React, { createContext, memo, useContext, useMemo } from 'react';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';

import { TableId } from '@kbn/securitysolution-data-table';

import { useEventDetails } from '../shared/hooks/use_event_details';
import { FlyoutError } from '../../shared/components/flyout_error';
import { FlyoutLoading } from '../../shared/components/flyout_loading';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,50 @@
* 2.0.
*/

import { useShowEventOverview } from './use_show_event_overview';
import { useFlyoutIsExpandable } from './use_flyout_is_expandable';
import { renderHook } from '@testing-library/react-hooks';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';

const getFieldsData = jest.fn();
jest.mock('../../../../common/hooks/use_experimental_features', () => ({
useIsExperimentalFeatureEnabled: jest.fn().mockReturnValue(true),
}));
const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock;

describe('showEventOverview', () => {
describe('event renderer is not available', () => {
describe('useFlyoutIsExpandable', () => {
it('always return ture when event.kind is signal (alert document)', () => {
const dataAsNestedObject = {} as unknown as Ecs;
getFieldsData.mockImplementation((field: string) => {
if (field === 'event.kind') {
return 'signal';
}
});
const hookResult = renderHook(() =>
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject }).valueOf()
);
expect(hookResult.result.current).toBe(true);
});

it('always return false when event.kind is not signal and feature flag is off', () => {
const dataAsNestedObject = {} as unknown as Ecs;
useIsExperimentalFeatureEnabledMock.mockReturnValue(false);
getFieldsData.mockImplementation((field: string) => {
if (field === 'event.kind') {
return 'signal';
}
});
const hookResult = renderHook(() =>
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject }).valueOf()
);
expect(hookResult.result.current).toBe(true);
});

describe('event renderer is not available', () => {
beforeEach(() => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
});
const dataAsNestedObject = {} as unknown as Ecs;
describe('event.kind is not event', () => {
it('should return true if event.kind is in ecs allowed values', () => {
getFieldsData.mockImplementation((field: string) => {
Expand All @@ -23,7 +57,7 @@ describe('showEventOverview', () => {
}
});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject }).valueOf()
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject }).valueOf()
);
expect(hookResult.result.current).toBe(true);
});
Expand All @@ -35,15 +69,15 @@ describe('showEventOverview', () => {
}
});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(false);
});

it('should return false if event.kind is notavailable', () => {
getFieldsData.mockImplementation(() => {});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(false);
});
Expand All @@ -60,7 +94,7 @@ describe('showEventOverview', () => {
}
});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(true);
});
Expand All @@ -75,7 +109,7 @@ describe('showEventOverview', () => {
}
});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(false);
});
Expand All @@ -86,7 +120,7 @@ describe('showEventOverview', () => {
}
});
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(false);
});
Expand All @@ -95,9 +129,13 @@ describe('showEventOverview', () => {

describe('event renderer is available', () => {
const dataAsNestedObject = { event: { module: ['suricata'] } } as unknown as Ecs;
beforeEach(() => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
});

it('should return true', () => {
const hookResult = renderHook(() =>
useShowEventOverview({ getFieldsData, dataAsNestedObject })
useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject })
);
expect(hookResult.result.current).toBe(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import type { GetFieldsData } from '../../../../common/hooks/use_get_fields_data
import { getRowRenderer } from '../../../../timelines/components/timeline/body/renderers/get_row_renderer';
import { defaultRowRenderers } from '../../../../timelines/components/timeline/body/renderers';
import { isEcsAllowedValue } from '../utils/event_utils';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { EventKind } from '../../shared/constants/event_kinds';

export interface UseShowEventOverviewParams {
/**
Expand All @@ -25,9 +27,11 @@ export interface UseShowEventOverviewParams {
}

/**
* Hook to return true if overview should be visible
* Hook used on the right panel to decide if the flyout has an expanded section.
* This also helps deciding if the overview section should be displayed.
* The hook looks at the `event.kind` and `event.category` fields of the document.
*/
export const useShowEventOverview = ({
export const useFlyoutIsExpandable = ({
getFieldsData,
dataAsNestedObject,
}: UseShowEventOverviewParams): boolean => {
Expand All @@ -41,10 +45,24 @@ export const useShowEventOverview = ({
isEcsAllowedValue('event.category', category)
);

const expandableEventFlyoutEnabled = useIsExperimentalFeatureEnabled(
'expandableEventFlyoutEnabled'
);

return useMemo(() => {
if (eventKind === 'event') {
// alert document: always show overview
if (eventKind === EventKind.signal) {
return true;
}
// do not show overview for non-alert if feature flag is disabled
if (!expandableEventFlyoutEnabled) {
return false;
}
// event document: show overview when event category is ecs compliant or event renderer is available
if (eventKind === EventKind.event) {
return eventCategoryInECS || renderer != null;
}
// non-event document: show overview when event kind is ecs compliant or event renderer is available
return eventKindInECS || renderer != null;
}, [eventKind, eventCategoryInECS, eventKindInECS, renderer]);
}, [expandableEventFlyoutEnabled, eventKind, eventCategoryInECS, eventKindInECS, renderer]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ import { PanelContent } from './content';
import type { RightPanelTabType } from './tabs';
import * as tabs from './tabs';
import { PanelFooter } from './footer';
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
import { useShowEventOverview } from './hooks/use_show_event_overview';
import { getField } from '../shared/utils';
import { EventKind } from '../shared/constants/event_kinds';
import { useFlyoutIsExpandable } from './hooks/use_flyout_is_expandable';

export type RightPanelPaths = 'overview' | 'table' | 'json';
export const DocumentDetailsRightPanelKey: RightPanelProps['key'] = 'document-details-right';
Expand All @@ -41,18 +38,13 @@ export const RightPanel: FC<Partial<RightPanelProps>> = memo(({ path }) => {
const { openRightPanel, closeFlyout } = useExpandableFlyoutApi();
const { eventId, indexName, scopeId, isPreview, dataAsNestedObject, getFieldsData } =
useRightPanelContext();
const isEventKindSignal = getField(getFieldsData('event.kind')) === EventKind.signal;

const expandableEventFlyoutEnabled = useIsExperimentalFeatureEnabled(
'expandableEventFlyoutEnabled'
);
const showEventOverview =
useShowEventOverview({ getFieldsData, dataAsNestedObject }) && expandableEventFlyoutEnabled;
const flyoutIsExpandable = useFlyoutIsExpandable({ getFieldsData, dataAsNestedObject });
const tabsDisplayed = useMemo(() => {
return isEventKindSignal || showEventOverview
return flyoutIsExpandable
? [tabs.overviewTab, tabs.tableTab, tabs.jsonTab]
: [tabs.tableTab, tabs.jsonTab];
}, [isEventKindSignal, showEventOverview]);
}, [flyoutIsExpandable]);

const selectedTabId = useMemo(() => {
const defaultTab = tabsDisplayed[0].id;
Expand Down Expand Up @@ -89,7 +81,7 @@ export const RightPanel: FC<Partial<RightPanelProps>> = memo(({ path }) => {

return (
<>
<PanelNavigation flyoutIsExpandable={isEventKindSignal || showEventOverview} />
<PanelNavigation flyoutIsExpandable={flyoutIsExpandable} />
<PanelHeader
tabs={tabsDisplayed}
selectedTabId={selectedTabId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { isEcsAllowedValue } from './event_utils';
import { isEcsAllowedValue, getEcsAllowedValueDescription } from './event_utils';

describe('test isEcsAllowedValue', () => {
it('should return if the value is an allowed value given by field name', () => {
Expand All @@ -14,3 +14,21 @@ describe('test isEcsAllowedValue', () => {
expect(isEcsAllowedValue('not ecs field', 'file')).toBe(false);
});
});

describe('test getEcsAllowedValueDescription', () => {
it('should return correct description based on field', () => {
expect(getEcsAllowedValueDescription('event.kind', 'metric')).toBe(
'This value is used to indicate that this event describes a numeric measurement taken at given point in time.\nExamples include CPU utilization, memory usage, or device temperature.\nMetric events are often collected on a predictable frequency, such as once every few seconds, or once a minute, but can also be used to describe ad-hoc numeric metric queries.'
);
expect(getEcsAllowedValueDescription('event.category', 'malware')).toBe(
'Malware detection events and alerts. Use this category to visualize and analyze malware detections from EDR/EPP systems such as Elastic Endpoint Security, Symantec Endpoint Protection, Crowdstrike, and network IDS/IPS systems such as Suricata, or other sources of malware-related events such as Palo Alto Networks threat logs and Wildfire logs.'
);

expect(getEcsAllowedValueDescription('event.kind', 'not ecs')).toBe(
'This field is not an ecs field, description is not available.'
);
expect(getEcsAllowedValueDescription('event.category', 'not ecs')).toBe(
'This field is not an ecs field, description is not available.'
);
});
});

0 comments on commit bba0226

Please sign in to comment.