Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 { renderHook } from '@testing-library/react';
import { useSelector } from 'react-redux';
import { DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID } from '../constants';
import { useSecurityDefaultPatterns } from './use_security_default_patterns';

jest.mock('react-redux', () => ({
useSelector: jest.fn(),
}));

describe('useSecurityDefaultPatterns', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should return the default data view', () => {
const mockDataViews = [
{
id: DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID,
title: 'logs-*,metrics-*',
name: 'default_view',
},
{
id: 'custom-view-1',
title: 'Custom View 1',
name: 'custom_view_1',
},
];

(useSelector as jest.Mock).mockReturnValue({
dataViews: mockDataViews,
defaultDataViewId: DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID,
});

const { result } = renderHook(() => useSecurityDefaultPatterns());
expect(result.current).toEqual({
id: DEFAULT_SECURITY_SOLUTION_DATA_VIEW_ID,
indexPatterns: ['logs-*', 'metrics-*'],
});
});

it('should return empty id and index patterns if no default data view is found', () => {
(useSelector as jest.Mock).mockReturnValue({
dataViews: [],
defaultDataViewId: null,
});
const { result } = renderHook(() => useSecurityDefaultPatterns());
expect(result.current).toEqual({ id: '', indexPatterns: [] });
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this kind of a duplicate of this other hook?

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { sharedStateSelector } from '../redux/selectors';

interface UseSecurityDefaultPatternsResult {
/**
* The default data view id.
*/
id: string;
/**
* The index patterns of the default data view.
*/
indexPatterns: string[];
}

/**
* Returns the default data view id and index patterns.
*/
export const useSecurityDefaultPatterns = (): UseSecurityDefaultPatternsResult => {
const { dataViews: dataViewSpecs, defaultDataViewId } = useSelector(sharedStateSelector);

const defaultDataViewSpec = useMemo(
() => dataViewSpecs.find((dv) => dv.id === defaultDataViewId),
[dataViewSpecs, defaultDataViewId]
);

return useMemo(
() => ({
Comment thread
PhilippeOberti marked this conversation as resolved.
id: defaultDataViewSpec?.id ?? '',
indexPatterns: defaultDataViewSpec?.title?.split(',') ?? [],
}),
[defaultDataViewSpec]
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { useWhichFlyout } from '../../shared/hooks/use_which_flyout';
import { mockFlyoutApi } from '../../shared/mocks/mock_flyout_context';
import { DocumentDetailsAnalyzerPanelKey } from '../../shared/constants/panel_keys';
import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';
import { useSelectedPatterns } from '../../../../data_view_manager/hooks/use_selected_patterns';

jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
Expand All @@ -29,6 +31,8 @@ jest.mock('../../shared/hooks/use_which_flyout');
jest.mock(
'../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver'
);
jest.mock('../../../../common/hooks/use_experimental_features');
jest.mock('../../../../data_view_manager/hooks/use_selected_patterns');

const mockUseWhichFlyout = useWhichFlyout as jest.Mock;
const FLYOUT_KEY = 'securitySolution';
Expand All @@ -50,6 +54,10 @@ describe('<AnalyzeGraph />', () => {
beforeEach(() => {
mockUseWhichFlyout.mockReturnValue(FLYOUT_KEY);
jest.mocked(useExpandableFlyoutApi).mockReturnValue(mockFlyoutApi);
(useEnableExperimental as jest.Mock).mockReturnValue({
newDataViewPickerEnabled: true,
});
(useSelectedPatterns as jest.Mock).mockReturnValue(['index']);
});

it('renders analyzer graph correctly', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React, { useMemo, useCallback } from 'react';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
import { i18n } from '@kbn/i18n';
import { EuiPanel } from '@elastic/eui';
import { SourcererScopeName } from '../../../../sourcerer/store/model';
import { useWhichFlyout } from '../../shared/hooks/use_which_flyout';
import { useDocumentDetailsContext } from '../../shared/context';
import { ANALYZER_GRAPH_TEST_ID } from './test_ids';
Expand All @@ -19,6 +20,9 @@ import { isActiveTimeline } from '../../../../helpers';
import { DocumentDetailsAnalyzerPanelKey } from '../../shared/constants/panel_keys';
import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
import { AnalyzerPreviewNoDataMessage } from '../../right/components/analyzer_preview_container';
import { useSelectedPatterns } from '../../../../data_view_manager/hooks/use_selected_patterns';
import { useSourcererDataView } from '../../../../sourcerer/containers';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';

export const ANALYZE_GRAPH_ID = 'analyze_graph';

Expand All @@ -41,10 +45,18 @@ export const AnalyzeGraph: FC = () => {
const isEnabled = useIsInvestigateInResolverActionEnabled(dataAsNestedObject);

const key = useWhichFlyout() ?? 'memory';
const { from, to, shouldUpdate, selectedPatterns } = useTimelineDataFilters(
isActiveTimeline(scopeId)
);
const { from, to, shouldUpdate } = useTimelineDataFilters(isActiveTimeline(scopeId));
const filters = useMemo(() => ({ from, to }), [from, to]);

const { newDataViewPickerEnabled } = useEnableExperimental();
const { selectedPatterns: oldAnalyzerPatterns } = useSourcererDataView(
SourcererScopeName.analyzer
);
const experimentalAnalyzerPatterns = useSelectedPatterns(SourcererScopeName.analyzer);
const selectedPatterns = newDataViewPickerEnabled
? experimentalAnalyzerPatterns
: oldAnalyzerPatterns;

const { openPreviewPanel } = useExpandableFlyoutApi();

const onClick = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import { useFetchRelatedAlertsByAncestry } from '../../shared/hooks/use_fetch_re
import { useFetchRelatedAlertsBySameSourceEvent } from '../../shared/hooks/use_fetch_related_alerts_by_same_source_event';
import { useFetchRelatedCases } from '../../shared/hooks/use_fetch_related_cases';
import { mockContextValue } from '../../shared/mocks/mock_context';
import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters';
import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID } from '../../../shared/components/test_ids';
import { useSecurityDefaultPatterns } from '../../../../data_view_manager/hooks/use_security_default_patterns';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';

jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
Expand All @@ -43,11 +44,8 @@ jest.mock('../../shared/hooks/use_fetch_related_alerts_by_session');
jest.mock('../../shared/hooks/use_fetch_related_alerts_by_ancestry');
jest.mock('../../shared/hooks/use_fetch_related_alerts_by_same_source_event');
jest.mock('../../shared/hooks/use_fetch_related_cases');

jest.mock('../../../../timelines/containers/use_timeline_data_filters', () => ({
useTimelineDataFilters: jest.fn(),
}));
const mockUseTimelineDataFilters = useTimelineDataFilters as jest.Mock;
jest.mock('../../../../data_view_manager/hooks/use_security_default_patterns');
jest.mock('../../../../common/hooks/use_experimental_features');

const renderCorrelationDetails = () => {
return render(
Expand All @@ -68,7 +66,12 @@ const NO_DATA_MESSAGE = 'No correlations data available.';
describe('CorrelationsDetails', () => {
beforeEach(() => {
jest.clearAllMocks();
mockUseTimelineDataFilters.mockReturnValue({ selectedPatterns: ['index'] });
(useEnableExperimental as jest.Mock).mockReturnValue({
newDataViewPickerEnabled: true,
});
(useSecurityDefaultPatterns as jest.Mock).mockReturnValue({
indexPatterns: ['index'],
});
});

it('renders all sections', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React from 'react';
import { EuiPanel, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { useSelector } from 'react-redux';
import { CORRELATIONS_DETAILS_TEST_ID } from './test_ids';
import { RelatedAlertsBySession } from './related_alerts_by_session';
import { RelatedAlertsBySameSourceEvent } from './related_alerts_by_same_source_event';
Expand All @@ -20,8 +21,9 @@ import { useShowRelatedAlertsBySameSourceEvent } from '../../shared/hooks/use_sh
import { useShowRelatedAlertsBySession } from '../../shared/hooks/use_show_related_alerts_by_session';
import { RelatedAlertsByAncestry } from './related_alerts_by_ancestry';
import { SuppressedAlerts } from './suppressed_alerts';
import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters';
import { isActiveTimeline } from '../../../../helpers';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';
import { useSecurityDefaultPatterns } from '../../../../data_view_manager/hooks/use_security_default_patterns';
import { sourcererSelectors } from '../../../../sourcerer/store';

export const CORRELATIONS_TAB_ID = 'correlations';

Expand All @@ -32,7 +34,13 @@ export const CorrelationsDetails: React.FC = () => {
const { dataAsNestedObject, eventId, getFieldsData, scopeId, isRulePreview } =
useDocumentDetailsContext();

const { selectedPatterns } = useTimelineDataFilters(isActiveTimeline(scopeId));
const { newDataViewPickerEnabled } = useEnableExperimental();
const oldSecurityDefaultPatterns =
useSelector(sourcererSelectors.defaultDataView)?.patternList ?? [];
const { indexPatterns: experimentalSecurityDefaultIndexPatterns } = useSecurityDefaultPatterns();
const securityDefaultPatterns = newDataViewPickerEnabled
? experimentalSecurityDefaultIndexPatterns
: oldSecurityDefaultPatterns;

const { show: showAlertsByAncestry, documentId } = useShowRelatedAlertsByAncestry({
getFieldsData,
Expand Down Expand Up @@ -92,7 +100,7 @@ export const CorrelationsDetails: React.FC = () => {
{showAlertsByAncestry && (
<EuiFlexItem>
<RelatedAlertsByAncestry
indices={selectedPatterns}
indices={securityDefaultPatterns}
scopeId={scopeId}
documentId={documentId}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ import { render } from '@testing-library/react';
import React from 'react';
import { TestProviders } from '../../../../common/mock';
import { useAlertPrevalenceFromProcessTree } from '../../shared/hooks/use_alert_prevalence_from_process_tree';
import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters';
import { mockContextValue } from '../../shared/mocks/mock_context';
import { mockDataFormattedForFieldBrowser } from '../../shared/mocks/mock_data_formatted_for_field_browser';
import { DocumentDetailsContext } from '../../shared/context';
import { AnalyzerPreview } from './analyzer_preview';
import { ANALYZER_PREVIEW_TEST_ID } from './test_ids';
import { useSecurityDefaultPatterns } from '../../../../data_view_manager/hooks/use_security_default_patterns';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';

import * as mock from '../mocks/mock_analyzer_data';

jest.mock('../../shared/hooks/use_alert_prevalence_from_process_tree', () => ({
useAlertPrevalenceFromProcessTree: jest.fn(),
}));
const mockUseAlertPrevalenceFromProcessTree = useAlertPrevalenceFromProcessTree as jest.Mock;

jest.mock('../../../../timelines/containers/use_timeline_data_filters', () => ({
useTimelineDataFilters: jest.fn(),
}));
const mockUseTimelineDataFilters = useTimelineDataFilters as jest.Mock;
jest.mock('../../../../data_view_manager/hooks/use_security_default_patterns');
jest.mock('../../../../common/hooks/use_experimental_features');

const mockTreeValues = {
loading: false,
Expand All @@ -48,7 +48,12 @@ const NO_DATA_MESSAGE = 'An error is preventing this alert from being analyzed.'
describe('<AnalyzerPreview />', () => {
beforeEach(() => {
jest.clearAllMocks();
mockUseTimelineDataFilters.mockReturnValue({ selectedPatterns: ['index'] });
(useEnableExperimental as jest.Mock).mockReturnValue({
newDataViewPickerEnabled: true,
});
(useSecurityDefaultPatterns as jest.Mock).mockReturnValue({
indexPatterns: ['index'],
});
});

it('shows analyzer preview correctly when documentId and index are present', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { find } from 'lodash/fp';
import { EuiTreeView, EuiSkeletonText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { useSelector } from 'react-redux';
import { ANALYZER_PREVIEW_TEST_ID, ANALYZER_PREVIEW_LOADING_TEST_ID } from './test_ids';
import { getTreeNodes } from '../utils/analyzer_helpers';
import { ANCESTOR_ID, RULE_INDICES } from '../../shared/constants/field_names';
Expand All @@ -17,7 +18,9 @@ import { useAlertPrevalenceFromProcessTree } from '../../shared/hooks/use_alert_
import type { StatsNode } from '../../shared/hooks/use_alert_prevalence_from_process_tree';
import { isActiveTimeline } from '../../../../helpers';
import { getField } from '../../shared/utils';
import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';
import { useSecurityDefaultPatterns } from '../../../../data_view_manager/hooks/use_security_default_patterns';
import { sourcererSelectors } from '../../../../sourcerer/store';

const CHILD_COUNT_LIMIT = 3;
const ANCESTOR_LEVEL = 3;
Expand Down Expand Up @@ -45,9 +48,16 @@ export const AnalyzerPreview: React.FC = () => {
const ancestorId = getField(getFieldsData(ANCESTOR_ID)) ?? '';
const documentId = isRulePreview ? ancestorId : eventId; // use ancestor as fallback for alert preview

const { selectedPatterns } = useTimelineDataFilters(isActiveTimeline(scopeId));
const { newDataViewPickerEnabled } = useEnableExperimental();
const oldSecurityDefaultPatterns =
useSelector(sourcererSelectors.defaultDataView)?.patternList ?? [];
const { indexPatterns: experimentalSecurityDefaultIndexPatterns } = useSecurityDefaultPatterns();
const securityDefaultPatterns = newDataViewPickerEnabled
? experimentalSecurityDefaultIndexPatterns
: oldSecurityDefaultPatterns;

const index = find({ category: 'kibana', field: RULE_INDICES }, data);
const indices = index?.values ?? selectedPatterns; // adding sourcerer indices for non-alert documents
const indices = index?.values ?? securityDefaultPatterns; // adding sourcerer indices for non-alert documents

const { statsNodes, loading, error } = useAlertPrevalenceFromProcessTree({
isActiveTimeline: isActiveTimeline(scopeId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { useShowSuppressedAlerts } from '../../shared/hooks/use_show_suppressed_
import { useFetchRelatedAlertsByAncestry } from '../../shared/hooks/use_fetch_related_alerts_by_ancestry';
import { useFetchRelatedAlertsBySameSourceEvent } from '../../shared/hooks/use_fetch_related_alerts_by_same_source_event';
import { useFetchRelatedAlertsBySession } from '../../shared/hooks/use_fetch_related_alerts_by_session';
import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters';
import { useFetchRelatedCases } from '../../shared/hooks/use_fetch_related_cases';
import { useNavigateToLeftPanel } from '../../shared/hooks/use_navigate_to_left_panel';
import {
Expand All @@ -39,6 +38,8 @@ import {
} from '../../../shared/components/test_ids';
import { useTourContext } from '../../../../common/components/guided_onboarding_tour';
import { AlertsCasesTourSteps } from '../../../../common/components/guided_onboarding_tour/tour_config';
import { useEnableExperimental } from '../../../../common/hooks/use_experimental_features';
import { useSecurityDefaultPatterns } from '../../../../data_view_manager/hooks/use_security_default_patterns';

jest.mock('../../shared/hooks/use_show_related_alerts_by_ancestry');
jest.mock('../../shared/hooks/use_show_related_alerts_by_same_source_event');
Expand Down Expand Up @@ -101,11 +102,8 @@ const renderCorrelationsOverview = (contextValue: DocumentDetailsContext) => (

const NO_DATA_MESSAGE = 'No correlations data available.';

jest.mock('../../../../timelines/containers/use_timeline_data_filters', () => ({
useTimelineDataFilters: jest.fn(),
}));
const mockUseTimelineDataFilters = useTimelineDataFilters as jest.Mock;

jest.mock('../../../../data_view_manager/hooks/use_security_default_patterns');
jest.mock('../../../../common/hooks/use_experimental_features');
jest.mock('../../../../common/components/guided_onboarding_tour', () => ({
useTourContext: jest.fn(),
}));
Expand Down Expand Up @@ -133,7 +131,12 @@ describe('<CorrelationsOverview />', () => {
jest.mocked(useShowRelatedAlertsBySession).mockReturnValue({ show: false });
jest.mocked(useShowRelatedCases).mockReturnValue(false);
jest.mocked(useShowSuppressedAlerts).mockReturnValue({ show: false, alertSuppressionCount: 0 });
mockUseTimelineDataFilters.mockReturnValue({ selectedPatterns: ['index'] });
(useEnableExperimental as jest.Mock).mockReturnValue({
newDataViewPickerEnabled: true,
});
(useSecurityDefaultPatterns as jest.Mock).mockReturnValue({
indexPatterns: ['index'],
});
(useNavigateToLeftPanel as jest.Mock).mockReturnValue({
navigateToLeftPanel: mockNavigateToLeftPanel,
isEnabled: true,
Expand Down
Loading