[CTI] ensures isThreatIntelModuleEnabled query for Overview page is made only once (#104523)

This commit is contained in:
Ece Özalp 2021-07-07 13:18:57 -04:00 committed by GitHub
parent de9ba92340
commit efa0476192
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 26 deletions

View file

@ -6,12 +6,14 @@
*/
import React from 'react';
import { ThreatIntelLinkPanelProps } from './index';
import { ThreatIntelLinkPanelProps } from '.';
import { useCtiEventCounts } from '../../containers/overview_cti_links/use_cti_event_counts';
import { CtiNoEvents } from './cti_no_events';
import { CtiWithEvents } from './cti_with_events';
export const CtiEnabledModuleComponent: React.FC<ThreatIntelLinkPanelProps> = (props) => {
export type CtiEnabledModuleProps = Omit<ThreatIntelLinkPanelProps, 'isThreatIntelModuleEnabled'>;
export const CtiEnabledModuleComponent: React.FC<CtiEnabledModuleProps> = (props) => {
const { eventCountsByDataset, totalCount } = useCtiEventCounts(props);
const { to, from } = props;

View file

@ -23,7 +23,7 @@ const warning = (
export const CtiNoEventsComponent = ({ to, from }: { to: string; from: string }) => {
const { buttonHref, listItems, isDashboardPluginDisabled } = useCtiDashboardLinks(
{ ...emptyEventCountsByDataset },
emptyEventCountsByDataset,
to,
from
);

View file

@ -6,6 +6,7 @@
*/
import React from 'react';
import { isEqual } from 'lodash';
import { useCtiDashboardLinks } from '../../containers/overview_cti_links';
import { ThreatIntelPanelView } from './threat_intel_panel_view';
@ -38,4 +39,11 @@ export const CtiWithEventsComponent = ({
CtiWithEventsComponent.displayName = 'CtiWithEvents';
export const CtiWithEvents = React.memo(CtiWithEventsComponent);
export const CtiWithEvents = React.memo(
CtiWithEventsComponent,
(prevProps, nextProps) =>
prevProps.to === nextProps.to &&
prevProps.from === nextProps.from &&
prevProps.totalCount === nextProps.totalCount &&
isEqual(prevProps.eventCountsByDataset, nextProps.eventCountsByDataset)
);

View file

@ -20,14 +20,9 @@ import {
SUB_PLUGINS_REDUCER,
} from '../../../common/mock';
import { mockTheme, mockProps } from './mock';
import { useIsThreatIntelModuleEnabled } from '../../containers/overview_cti_links/use_is_threat_intel_module_enabled';
jest.mock('../../../common/lib/kibana');
jest.mock('../../containers/overview_cti_links/use_is_threat_intel_module_enabled');
const useIsThreatIntelModuleEnabledMock = useIsThreatIntelModuleEnabled as jest.Mock;
useIsThreatIntelModuleEnabledMock.mockReturnValue(true);
describe('ThreatIntelLinkPanel', () => {
const state: State = mockGlobalState;
@ -44,7 +39,7 @@ describe('ThreatIntelLinkPanel', () => {
<Provider store={store}>
<I18nProvider>
<ThemeProvider theme={mockTheme}>
<ThreatIntelLinkPanel {...mockProps} />
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={true} />
</ThemeProvider>
</I18nProvider>
</Provider>
@ -54,12 +49,11 @@ describe('ThreatIntelLinkPanel', () => {
});
it('renders CtiDisabledModule when Threat Intel module is disabled', () => {
useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(false);
const wrapper = mount(
<Provider store={store}>
<I18nProvider>
<ThemeProvider theme={mockTheme}>
<ThreatIntelLinkPanel {...mockProps} />
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={false} />
</ThemeProvider>
</I18nProvider>
</Provider>
@ -69,12 +63,11 @@ describe('ThreatIntelLinkPanel', () => {
});
it('renders null while Threat Intel module state is loading', () => {
useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(undefined);
const wrapper = mount(
<Provider store={store}>
<I18nProvider>
<ThemeProvider theme={mockTheme}>
<ThreatIntelLinkPanel {...mockProps} />
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={undefined} />
</ThemeProvider>
</I18nProvider>
</Provider>

View file

@ -8,19 +8,18 @@
import React from 'react';
import { GlobalTimeArgs } from '../../../common/containers/use_global_time';
import { useIsThreatIntelModuleEnabled } from '../../containers/overview_cti_links/use_is_threat_intel_module_enabled';
import { CtiEnabledModule } from './cti_enabled_module';
import { CtiDisabledModule } from './cti_disabled_module';
export type ThreatIntelLinkPanelProps = Pick<
GlobalTimeArgs,
'from' | 'to' | 'deleteQuery' | 'setQuery'
>;
> & {
isThreatIntelModuleEnabled: boolean | undefined;
};
const ThreatIntelLinkPanelComponent: React.FC<ThreatIntelLinkPanelProps> = (props) => {
const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled();
switch (isThreatIntelModuleEnabled) {
switch (props.isThreatIntelModuleEnabled) {
case true:
return <CtiEnabledModule {...props} data-test-subj="cti-enabled-module" />;
case false:

View file

@ -6,19 +6,14 @@
*/
import { useEffect, useState, useMemo } from 'react';
import { ThreatIntelLinkPanelProps } from '../../components/overview_cti_links';
import { useRequestEventCounts } from './use_request_event_counts';
import { emptyEventCountsByDataset } from './helpers';
import { CtiEnabledModuleProps } from '../../components/overview_cti_links/cti_enabled_module';
export const ID = 'ctiEventCountQuery';
const PREFIX = 'threatintel.';
export const useCtiEventCounts = ({
deleteQuery,
from,
setQuery,
to,
}: ThreatIntelLinkPanelProps) => {
export const useCtiEventCounts = ({ deleteQuery, from, setQuery, to }: CtiEnabledModuleProps) => {
const [isInitialLoading, setIsInitialLoading] = useState(true);
const [loading, { data, inspect, totalCount, refetch }] = useRequestEventCounts(to, from);

View file

@ -87,6 +87,7 @@ describe('Overview', () => {
},
]);
});
describe('rendering', () => {
test('it DOES NOT render the Getting started text when an index is available', () => {
mockUseSourcererScope.mockReturnValue({
@ -277,4 +278,18 @@ describe('Overview', () => {
});
});
});
describe('Threat Intel Dashboard Links', () => {
it('invokes useIsThreatIntelModuleEnabled hook only once', () => {
useIsThreatIntelModuleEnabledMock.mockClear();
mount(
<TestProviders>
<MemoryRouter>
<Overview />
</MemoryRouter>
</TestProviders>
);
expect(useIsThreatIntelModuleEnabledMock).toHaveBeenCalledTimes(1);
});
});
});

View file

@ -33,6 +33,7 @@ import { Sourcerer } from '../../common/components/sourcerer';
import { SourcererScopeName } from '../../common/store/sourcerer/model';
import { useDeepEqualSelector } from '../../common/hooks/use_selector';
import { ThreatIntelLinkPanel } from '../components/overview_cti_links';
import { useIsThreatIntelModuleEnabled } from '../containers/overview_cti_links/use_is_threat_intel_module_enabled';
const SidebarFlexItem = styled(EuiFlexItem)`
margin-right: 24px;
@ -70,6 +71,8 @@ const OverviewComponent = () => {
addMessage('management', 'dismissEndpointNotice');
}, [addMessage]);
const { allEnabled: isIngestEnabled } = useIngestEnabledCheck();
const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled();
return (
<>
{indicesExist ? (
@ -143,6 +146,7 @@ const OverviewComponent = () => {
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ThreatIntelLinkPanel
isThreatIntelModuleEnabled={isThreatIntelModuleEnabled}
deleteQuery={deleteQuery}
from={from}
setQuery={setQuery}