[Security Solution] add expandable flyout investigation section (#153807)

This commit is contained in:
Philippe Oberti 2023-04-04 10:53:44 -05:00 committed by GitHub
parent b5deb19d4f
commit ee72588faa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 282 additions and 229 deletions

View file

@ -92,8 +92,6 @@ describe.skip('Alert details expandable flyout left panel', { testIsolation: fal
.and('have.text', 'Session view');
openGraphAnalyzer();
cy.get(DOCUMENT_DETAILS_FLYOUT_VISUALIZE_TAB_GRAPH_ANALYZER_CONTENT)
.should('be.visible')
.and('have.text', 'Analyzer graph');
cy.get(DOCUMENT_DETAILS_FLYOUT_VISUALIZE_TAB_GRAPH_ANALYZER_CONTENT).should('be.visible');
});
});

View file

@ -12,9 +12,9 @@ import {
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CONTENT,
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_EVENT_TYPE_ROW,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_CONTENT,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_REASON_TITLE,
@ -27,6 +27,7 @@ import {
expandFirstAlertExpandableFlyout,
openOverviewTab,
toggleOverviewTabDescriptionSection,
toggleOverviewTabInvestigationSection,
} from '../../../tasks/document_expandable_flyout';
import { cleanKibana } from '../../../tasks/common';
import { login, visit } from '../../../tasks/login';
@ -89,11 +90,6 @@ describe.skip(
.and('contain.text', rule.name);
});
it('should display mitre attack', () => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE).should('be.visible');
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_DETAILS).should('be.visible');
});
it('should display mitre attack', () => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE)
.should('be.visible')
@ -112,45 +108,40 @@ describe.skip(
describe('investigation section', () => {
before(() => {
toggleOverviewTabDescriptionSection();
toggleOverviewTabInvestigationSection();
});
it('should display description section header and content', () => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER)
.should('be.visible')
.and('have.text', 'Investigation');
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT).should(
'be.visible'
);
});
it('should display highlighted fields', () => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS)
.scrollIntoView()
.within(() => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
.should('be.visible')
.click();
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE)
.should('be.visible')
.and('have.text', 'Highlighted fields');
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS).should(
'be.visible'
);
// close highlighted fields to reset the view for next test
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
.should('be.visible')
.click();
});
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE)
.should('be.visible')
.and('have.text', 'Highlighted fields');
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS).should(
'be.visible'
);
});
it('should navigate to table tab when clicking on highlighted fields view button', () => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS)
.scrollIntoView()
.within(() => {
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
.should('be.visible')
.click();
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK)
.should('be.visible')
.click();
});
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK)
.should('be.visible')
.click();
// the table component is rendered within a dom element with overflow, so Cypress isn't finding it
// this next line is a hack that scrolls to a specific element in the table
// (in the middle of it vertically) to ensure Cypress finds it
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_EVENT_TYPE_ROW).scrollIntoView();
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CONTENT).should('be.visible');
// go back to Overview tab to reset view for next test
openOverviewTab();
});
});
}

View file

@ -49,8 +49,10 @@ import {
HIGHLIGHTED_FIELDS_DETAILS_TEST_ID,
HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID,
HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID,
HIGHLIGHTED_FIELDS_TEST_ID,
HIGHLIGHTED_FIELDS_TITLE_TEST_ID,
INVESTIGATION_SECTION_CONTENT_TEST_ID,
INVESTIGATION_SECTION_HEADER_TEST_ID,
MITRE_ATTACK_DETAILS_TEST_ID,
MITRE_ATTACK_TITLE_TEST_ID,
REASON_DETAILS_TEST_ID,
@ -154,8 +156,13 @@ export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS = getDataTe
);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON =
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER =
getDataTestSubjectSelector(INVESTIGATION_SECTION_HEADER_TEST_ID);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT =
getDataTestSubjectSelector(INVESTIGATION_SECTION_CONTENT_TEST_ID);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE =
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID);
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_TITLE_TEST_ID);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS =
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID);
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK =

View file

@ -14,6 +14,7 @@ import {
DOCUMENT_DETAILS_FLYOUT_INVESTIGATIONS_TAB,
DOCUMENT_DETAILS_FLYOUT_JSON_TAB,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER,
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB,
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CLEAR_FILTER,
@ -59,7 +60,17 @@ export const scrollWithinDocumentDetailsExpandableFlyoutRightSection = (x: numbe
* Open the Overview tab in the document details expandable flyout right section
*/
export const openOverviewTab = () =>
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB).should('be.visible').click();
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB).scrollIntoView().should('be.visible').click();
/**
* Toggle the Overview tab description section in the document details expandable flyout right section
*/
export const toggleOverviewTabInvestigationSection = () =>
cy
.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER)
.scrollIntoView()
.should('be.visible')
.click();
/**
* Toggle the Overview tab description section in the document details expandable flyout right section
@ -67,6 +78,7 @@ export const openOverviewTab = () =>
export const toggleOverviewTabDescriptionSection = () =>
cy
.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER)
.scrollIntoView()
.should('be.visible')
.click();

View file

@ -19,27 +19,7 @@ export default {
// TODO ideally we would want to have some data here, but we need to spent some time getting all the foundation items for storybook
// (ReduxStoreProvider, CellActionsProvider...) similarly to how it was done for the TestProvidersComponent
// see ticket https://github.com/elastic/security-team/issues/6223
export const Expanded: Story<void> = () => {
const flyoutContextValue = {
openRightPanel: () => window.alert('openRightPanel called'),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
return (
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields expanded={true} />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
};
export const Collapsed: Story<void> = () => {
export const Default: Story<void> = () => {
const flyoutContextValue = {
openRightPanel: () => window.alert('openRightPanel called'),
} as unknown as ExpandableFlyoutContext;

View file

@ -8,130 +8,41 @@
import React from 'react';
import { render } from '@testing-library/react';
import { RightPanelContext } from '../context';
import {
HIGHLIGHTED_FIELDS_DETAILS_TEST_ID,
HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID,
HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID,
} from './test_ids';
import { HIGHLIGHTED_FIELDS_DETAILS_TEST_ID, HIGHLIGHTED_FIELDS_TITLE_TEST_ID } from './test_ids';
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
import { HighlightedFields } from './highlighted_fields';
import { RightPanelKey, RightPanelTableTabPath } from '..';
import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock';
import { ThemeProvider } from 'styled-components';
const mockTheme = getMockTheme({
eui: {
euiSizeL: '10px',
},
});
describe('<HighlightedFields />', () => {
it('should render the component collapsed', () => {
const flyoutContextValue = {
openRightPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
const { getByTestId } = render(
<ThemeProvider theme={mockTheme}>
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
</ThemeProvider>
);
expect(getByTestId(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID)).toBeInTheDocument();
});
it('should render the component expanded', () => {
const flyoutContextValue = {
openRightPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
const { getByTestId } = render(
<ThemeProvider theme={mockTheme}>
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields expanded={true} />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
</ThemeProvider>
);
expect(getByTestId(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID)).toBeInTheDocument();
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
});
it('should expand details when clicking on header', () => {
const flyoutContextValue = {
openRightPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
const { getByTestId } = render(
<ThemeProvider theme={mockTheme}>
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
</ThemeProvider>
);
getByTestId(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID).click();
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
});
it('should navigate to table tab when clicking on the link button', () => {
const flyoutContextValue = {
openRightPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
const { getByTestId } = render(
<ThemeProvider theme={mockTheme}>
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
</ThemeProvider>
);
getByTestId(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID).click();
getByTestId(HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK).click();
expect(flyoutContextValue.openRightPanel).toHaveBeenCalledWith({
id: RightPanelKey,
path: RightPanelTableTabPath,
params: {
id: panelContextValue.eventId,
indexName: panelContextValue.indexName,
it('should render the component', () => {
const mockTheme = getMockTheme({
eui: {
euiSizeL: '10px',
},
});
const flyoutContextValue = {
openRightPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
eventId: 'eventId',
indexName: 'indexName',
dataFormattedForFieldBrowser: [],
browserFields: {},
} as unknown as RightPanelContext;
const { getByTestId } = render(
<ThemeProvider theme={mockTheme}>
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<HighlightedFields />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
</ThemeProvider>
);
expect(getByTestId(HIGHLIGHTED_FIELDS_TITLE_TEST_ID)).toBeInTheDocument();
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
});
it('should render empty component if dataFormattedForFieldBrowser is null', () => {

View file

@ -5,27 +5,17 @@
* 2.0.
*/
import { EuiFlexGroup } from '@elastic/eui';
import type { VFC } from 'react';
import React, { useCallback, useState } from 'react';
import type { FC } from 'react';
import React, { useCallback } from 'react';
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
import { HIGHLIGHTED_FIELDS_TEST_ID } from './test_ids';
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui';
import { HIGHLIGHTED_FIELDS_DETAILS_TEST_ID, HIGHLIGHTED_FIELDS_TITLE_TEST_ID } from './test_ids';
import { AlertSummaryView } from '../../../common/components/event_details/alert_summary_view';
import { HIGHLIGHTED_FIELDS_TITLE } from './translations';
import { HeaderSection } from '../../../common/components/header_section';
import { useRightPanelContext } from '../context';
import { RightPanelKey, RightPanelTableTabPath } from '..';
export interface HighlightedFieldsProps {
/**
* Boolean to allow the component to be expanded or collapsed on first render
*/
expanded?: boolean;
}
export const HighlightedFields: VFC<HighlightedFieldsProps> = ({ expanded = false }) => {
const [isPanelExpanded, setIsPanelExpanded] = useState(expanded);
export const HighlightedFields: FC = () => {
const { openRightPanel } = useExpandableFlyoutContext();
const { eventId, indexName, dataFormattedForFieldBrowser, browserFields } =
useRightPanelContext();
@ -46,28 +36,26 @@ export const HighlightedFields: VFC<HighlightedFieldsProps> = ({ expanded = fals
}
return (
<EuiFlexGroup gutterSize="none" direction="column" data-test-subj={HIGHLIGHTED_FIELDS_TEST_ID}>
<HeaderSection
alignHeader="center"
hideSubtitle
outerDirection="row"
title={HIGHLIGHTED_FIELDS_TITLE}
titleSize="xs"
toggleQuery={setIsPanelExpanded}
toggleStatus={isPanelExpanded}
/>
{isPanelExpanded && (
<AlertSummaryView
data={dataFormattedForFieldBrowser}
eventId={eventId}
browserFields={browserFields}
isDraggable={false}
scopeId={'global'}
title={HIGHLIGHTED_FIELDS_TITLE}
isReadOnly={false} // TODO: set properly
goToTable={goToTableTab}
/>
)}
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem data-test-subj={HIGHLIGHTED_FIELDS_TITLE_TEST_ID}>
<EuiTitle size="xxs">
<h5>{HIGHLIGHTED_FIELDS_TITLE}</h5>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem data-test-subj={HIGHLIGHTED_FIELDS_DETAILS_TEST_ID}>
<EuiPanel hasBorder hasShadow={false}>
<AlertSummaryView // TODO consider using x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx instead if the link to the table have to be removed
data={dataFormattedForFieldBrowser}
eventId={eventId}
browserFields={browserFields}
isDraggable={false}
scopeId={'global'}
title={''}
isReadOnly={false} // TODO: set properly
goToTable={goToTableTab}
/>
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
);
};

View file

@ -0,0 +1,44 @@
/*
* 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 type { Story } from '@storybook/react';
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
import { InvestigationSection } from './investigation_section';
import { mockDataFormattedForFieldBrowser, mockSearchHit } from '../mocks/mock_context';
import { RightPanelContext } from '../context';
const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
const panelContextValue = {
dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
searchHit: mockSearchHit,
} as unknown as RightPanelContext;
export default {
component: InvestigationSection,
title: 'Flyout/InvestigationSection',
};
export const Expand: Story<void> = () => {
return (
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<InvestigationSection />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
};
export const Collapse: Story<void> = () => {
return (
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<InvestigationSection expanded={false} />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
};

View file

@ -0,0 +1,59 @@
/*
* 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 {
INVESTIGATION_SECTION_CONTENT_TEST_ID,
INVESTIGATION_SECTION_HEADER_TEST_ID,
} from './test_ids';
import { RightPanelContext } from '../context';
import { InvestigationSection } from './investigation_section';
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
const panelContextValue = {} as unknown as RightPanelContext;
describe('<InvestigationSection />', () => {
it('should render the component collapsed', () => {
const { getByTestId } = render(
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<InvestigationSection />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
expect(getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID)).toBeInTheDocument();
});
it('should render the component expanded', () => {
const { getByTestId } = render(
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<InvestigationSection expanded={true} />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
expect(getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID)).toBeInTheDocument();
expect(getByTestId(INVESTIGATION_SECTION_CONTENT_TEST_ID)).toBeInTheDocument();
});
it('should expand the component when clicking on the arrow on header', () => {
const { getByTestId } = render(
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
<RightPanelContext.Provider value={panelContextValue}>
<InvestigationSection />
</RightPanelContext.Provider>
</ExpandableFlyoutContext.Provider>
);
getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID).click();
expect(getByTestId(INVESTIGATION_SECTION_CONTENT_TEST_ID)).toBeInTheDocument();
});
});

View file

@ -0,0 +1,37 @@
/*
* 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 type { VFC } from 'react';
import React from 'react';
import { ExpandableSection } from './expandable_section';
import { HighlightedFields } from './highlighted_fields';
import { INVESTIGATION_SECTION_TEST_ID } from './test_ids';
import { INVESTIGATION_TITLE } from './translations';
export interface DescriptionSectionProps {
/**
* Boolean to allow the component to be expanded or collapsed on first render
*/
expanded?: boolean;
}
/**
* Most top section of the overview tab. It contains the description, reason and mitre attack information (for a document of type alert).
*/
export const InvestigationSection: VFC<DescriptionSectionProps> = ({ expanded = false }) => {
return (
<ExpandableSection
expanded={expanded}
title={INVESTIGATION_TITLE}
data-test-subj={INVESTIGATION_SECTION_TEST_ID}
>
<HighlightedFields />
</ExpandableSection>
);
};
InvestigationSection.displayName = 'InvestigationSection';

View file

@ -7,11 +7,23 @@
import { CONTENT_TEST_ID, HEADER_TEST_ID } from './expandable_section';
/* Header */
export const FLYOUT_HEADER_TITLE_TEST_ID = 'securitySolutionDocumentDetailsFlyoutHeaderTitle';
export const EXPAND_DETAILS_BUTTON_TEST_ID =
'securitySolutionDocumentDetailsFlyoutHeaderExpandDetailButton';
export const COLLAPSE_DETAILS_BUTTON_TEST_ID =
'securitySolutionDocumentDetailsFlyoutHeaderCollapseDetailButton';
export const FLYOUT_HEADER_SEVERITY_TITLE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderSeverityTitle';
export const FLYOUT_HEADER_SEVERITY_VALUE_TEST_ID = 'severity';
export const FLYOUT_HEADER_RISK_SCORE_TITLE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreTitle';
export const FLYOUT_HEADER_RISK_SCORE_VALUE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreValue';
/* Description section */
export const DESCRIPTION_SECTION_TEST_ID =
'securitySolutionDocumentDetailsFlyoutDescriptionSection';
export const DESCRIPTION_SECTION_HEADER_TEST_ID = DESCRIPTION_SECTION_TEST_ID + HEADER_TEST_ID;
@ -25,15 +37,18 @@ export const REASON_TITLE_TEST_ID = 'securitySolutionDocumentDetailsFlyoutReason
export const REASON_DETAILS_TEST_ID = 'securitySolutionDocumentDetailsFlyoutReasonDetails';
export const MITRE_ATTACK_TITLE_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackTitle';
export const MITRE_ATTACK_DETAILS_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackDetails';
export const FLYOUT_HEADER_SEVERITY_TITLE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderSeverityTitle';
export const FLYOUT_HEADER_SEVERITY_VALUE_TEST_ID = 'severity';
export const FLYOUT_HEADER_RISK_SCORE_TITLE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreTitle';
export const FLYOUT_HEADER_RISK_SCORE_VALUE_TEST_ID =
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreValue';
/* Investigation section */
export const INVESTIGATION_SECTION_TEST_ID =
'securitySolutionDocumentDetailsFlyoutInvestigationSection';
export const INVESTIGATION_SECTION_HEADER_TEST_ID = INVESTIGATION_SECTION_TEST_ID + HEADER_TEST_ID;
export const INVESTIGATION_SECTION_CONTENT_TEST_ID =
INVESTIGATION_SECTION_TEST_ID + CONTENT_TEST_ID;
export const HIGHLIGHTED_FIELDS_TITLE_TEST_ID =
'securitySolutionDocumentDetailsFlyoutHighlightedFieldsTitle';
export const HIGHLIGHTED_FIELDS_DETAILS_TEST_ID =
'securitySolutionDocumentDetailsFlyoutHighlightedFieldsDetails';
export const HIGHLIGHTED_FIELDS_TEST_ID = 'securitySolutionDocumentDetailsFlyoutHighlightedFields';
export const HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID = 'query-toggle-header';
export const HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID = 'header-section-title';
export const HIGHLIGHTED_FIELDS_DETAILS_TEST_ID = 'summary-view';
export const HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK = 'summary-view-go-to-table-link';

View file

@ -7,6 +7,8 @@
import { i18n } from '@kbn/i18n';
/* Header */
export const EXPAND_DETAILS_BUTTON = i18n.translate(
'xpack.securitySolution.flyout.documentDetails.expandDetailButton',
{ defaultMessage: 'Expand alert details' }
@ -36,6 +38,8 @@ export const RISK_SCORE_TITLE = i18n.translate(
}
);
/* Description section */
export const DESCRIPTION_TITLE = i18n.translate(
'xpack.securitySolution.flyout.documentDetails.descriptionTitle',
{
@ -83,6 +87,15 @@ export const DOCUMENT_REASON_TITLE = i18n.translate(
}
);
/* Investigation section */
export const INVESTIGATION_TITLE = i18n.translate(
'xpack.securitySolution.flyout.documentDetails.investigationSectionTitle',
{
defaultMessage: 'Investigation',
}
);
export const HIGHLIGHTED_FIELDS_TITLE = i18n.translate(
'xpack.securitySolution.flyout.documentDetails.highlightedFieldsTitle',
{ defaultMessage: 'Highlighted fields' }

View file

@ -7,9 +7,9 @@
import type { FC } from 'react';
import React, { memo } from 'react';
import { EuiHorizontalRule, EuiPanel } from '@elastic/eui';
import { EuiHorizontalRule } from '@elastic/eui';
import { InvestigationSection } from '../components/investigation_section';
import { DescriptionSection } from '../components/description_section';
import { HighlightedFields } from '../components/highlighted_fields';
/**
* Overview view displayed in the document details expandable flyout right section
@ -19,9 +19,7 @@ export const OverviewTab: FC = memo(() => {
<>
<DescriptionSection />
<EuiHorizontalRule margin="l" />
<EuiPanel hasBorder hasShadow={false}>
<HighlightedFields />
</EuiPanel>
<InvestigationSection />
</>
);
});