[Security Solution] Fix tooltip for timeline sourcerer (#115950)
* fix tooltip for event picker * remove unused mock * remove unused dependency Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
ed99e2466a
commit
780c43513a
4 changed files with 215 additions and 114 deletions
|
@ -7,6 +7,9 @@
|
|||
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
import { Sourcerer } from './index';
|
||||
import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
|
||||
|
@ -19,8 +22,6 @@ import {
|
|||
TestProviders,
|
||||
} from '../../mock';
|
||||
import { createStore, State } from '../../store';
|
||||
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
jest.mock('react-redux', () => {
|
||||
|
@ -46,6 +47,7 @@ const mockOptions = [
|
|||
const defaultProps = {
|
||||
scope: sourcererModel.SourcererScopeName.default,
|
||||
};
|
||||
|
||||
describe('Sourcerer component', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
@ -59,6 +61,34 @@ describe('Sourcerer component', () => {
|
|||
store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
|
||||
});
|
||||
|
||||
it('renders tooltip', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<Sourcerer {...defaultProps} />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="sourcerer-tooltip"]').prop('content')).toEqual(
|
||||
mockOptions
|
||||
.map((p) => p.label)
|
||||
.sort()
|
||||
.join(', ')
|
||||
);
|
||||
});
|
||||
|
||||
it('renders popover button inside tooltip', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<Sourcerer {...defaultProps} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="sourcerer-tooltip"] [data-test-subj="sourcerer-trigger"]')
|
||||
.exists()
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
// Using props callback instead of simulating clicks,
|
||||
// because EuiSelectable uses a virtualized list, which isn't easily testable via test subjects
|
||||
it('Mounts with all options selected', () => {
|
||||
|
|
|
@ -169,55 +169,62 @@ export const Sourcerer = React.memo<SourcererComponentProps>(({ scope: scopeId }
|
|||
[isPopoverOpen, sourcererScope.selectedPatterns]
|
||||
);
|
||||
|
||||
const buttonWithTooptip = useMemo(() => {
|
||||
return tooltipContent ? (
|
||||
<EuiToolTip position="top" content={tooltipContent} data-test-subj="sourcerer-tooltip">
|
||||
{trigger}
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
trigger
|
||||
);
|
||||
}, [trigger, tooltipContent]);
|
||||
|
||||
return (
|
||||
<EuiToolTip position="top" content={tooltipContent}>
|
||||
<EuiPopover
|
||||
data-test-subj="sourcerer-popover"
|
||||
button={trigger}
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={handleClosePopOver}
|
||||
display="block"
|
||||
panelPaddingSize="s"
|
||||
repositionOnScroll
|
||||
ownFocus
|
||||
>
|
||||
<PopoverContent>
|
||||
<EuiPopoverTitle>
|
||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||
</EuiPopoverTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText color="default">{i18n.INDEX_PATTERNS_SELECTION_LABEL}</EuiText>
|
||||
<EuiSpacer size="xs" />
|
||||
{comboBox}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<ResetButton
|
||||
aria-label={i18n.INDEX_PATTERNS_RESET}
|
||||
data-test-subj="sourcerer-reset"
|
||||
flush="left"
|
||||
onClick={resetDataSources}
|
||||
title={i18n.INDEX_PATTERNS_RESET}
|
||||
>
|
||||
{i18n.INDEX_PATTERNS_RESET}
|
||||
</ResetButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={handleSaveIndices}
|
||||
disabled={isSavingDisabled}
|
||||
data-test-subj="add-index"
|
||||
fill
|
||||
fullWidth
|
||||
size="s"
|
||||
>
|
||||
{i18n.SAVE_INDEX_PATTERNS}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</PopoverContent>
|
||||
</EuiPopover>
|
||||
</EuiToolTip>
|
||||
<EuiPopover
|
||||
data-test-subj="sourcerer-popover"
|
||||
button={buttonWithTooptip}
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={handleClosePopOver}
|
||||
panelPaddingSize="s"
|
||||
repositionOnScroll
|
||||
ownFocus
|
||||
>
|
||||
<PopoverContent>
|
||||
<EuiPopoverTitle>
|
||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||
</EuiPopoverTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText color="default">{i18n.INDEX_PATTERNS_SELECTION_LABEL}</EuiText>
|
||||
<EuiSpacer size="xs" />
|
||||
{comboBox}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<ResetButton
|
||||
aria-label={i18n.INDEX_PATTERNS_RESET}
|
||||
data-test-subj="sourcerer-reset"
|
||||
flush="left"
|
||||
onClick={resetDataSources}
|
||||
title={i18n.INDEX_PATTERNS_RESET}
|
||||
>
|
||||
{i18n.INDEX_PATTERNS_RESET}
|
||||
</ResetButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={handleSaveIndices}
|
||||
disabled={isSavingDisabled}
|
||||
data-test-subj="add-index"
|
||||
fill
|
||||
fullWidth
|
||||
size="s"
|
||||
>
|
||||
{i18n.SAVE_INDEX_PATTERNS}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</PopoverContent>
|
||||
</EuiPopover>
|
||||
);
|
||||
});
|
||||
Sourcerer.displayName = 'Sourcerer';
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { fireEvent, render, within } from '@testing-library/react';
|
||||
import { EuiToolTip } from '@elastic/eui';
|
||||
|
||||
import React from 'react';
|
||||
import { PickEventType } from './pick_events';
|
||||
import {
|
||||
|
@ -19,6 +21,14 @@ import { TimelineEventsType } from '../../../../../common';
|
|||
import { createStore } from '../../../../common/store';
|
||||
import { SourcererScopeName } from '../../../../common/store/sourcerer/model';
|
||||
|
||||
jest.mock('@elastic/eui', () => {
|
||||
const actual = jest.requireActual('@elastic/eui');
|
||||
return {
|
||||
...actual,
|
||||
EuiToolTip: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('pick_events', () => {
|
||||
const defaultProps = {
|
||||
eventType: 'all' as TimelineEventsType,
|
||||
|
@ -53,6 +63,23 @@ describe('pick_events', () => {
|
|||
},
|
||||
};
|
||||
const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
|
||||
|
||||
const mockTooltip = ({
|
||||
tooltipContent,
|
||||
children,
|
||||
}: {
|
||||
tooltipContent: string;
|
||||
children: React.ReactElement;
|
||||
}) => (
|
||||
<div data-test-subj="timeline-sourcerer-tooltip">
|
||||
<span>{tooltipContent}</span>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
beforeAll(() => {
|
||||
(EuiToolTip as unknown as jest.Mock).mockImplementation(mockTooltip);
|
||||
});
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
|
@ -68,6 +95,32 @@ describe('pick_events', () => {
|
|||
initialPatterns.sort().join('')
|
||||
);
|
||||
});
|
||||
|
||||
it('renders tooltip', () => {
|
||||
render(
|
||||
<TestProviders>
|
||||
<PickEventType {...defaultProps} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect((EuiToolTip as unknown as jest.Mock).mock.calls[0][0].content).toEqual(
|
||||
initialPatterns
|
||||
.filter((p) => p != null)
|
||||
.sort()
|
||||
.join(', ')
|
||||
);
|
||||
});
|
||||
|
||||
it('renders popover button inside tooltip', () => {
|
||||
const wrapper = render(
|
||||
<TestProviders>
|
||||
<PickEventType {...defaultProps} />
|
||||
</TestProviders>
|
||||
);
|
||||
const tooltip = wrapper.getByTestId('timeline-sourcerer-tooltip');
|
||||
expect(within(tooltip).getByTestId('sourcerer-timeline-trigger')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('correctly filters options', () => {
|
||||
const wrapper = render(
|
||||
<TestProviders store={store}>
|
||||
|
|
|
@ -295,6 +295,20 @@ const PickEventTypeComponents: React.FC<PickEventTypeProps> = ({
|
|||
[isPopoverOpen, sourcererScope.selectedPatterns]
|
||||
);
|
||||
|
||||
const buttonWithTooptip = useMemo(() => {
|
||||
return tooltipContent ? (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={tooltipContent}
|
||||
data-test-subj="timeline-sourcerer-tooltip"
|
||||
>
|
||||
{button}
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
button
|
||||
);
|
||||
}, [button, tooltipContent]);
|
||||
|
||||
const ButtonContent = useMemo(
|
||||
() => (
|
||||
<AdvancedSettings data-test-subj="advanced-settings">
|
||||
|
@ -326,69 +340,66 @@ const PickEventTypeComponents: React.FC<PickEventTypeProps> = ({
|
|||
|
||||
return (
|
||||
<PickEventContainer>
|
||||
<EuiToolTip position="top" content={tooltipContent}>
|
||||
<EuiPopover
|
||||
button={button}
|
||||
closePopover={closePopover}
|
||||
id="popover"
|
||||
isOpen={isPopoverOpen}
|
||||
ownFocus
|
||||
repositionOnScroll
|
||||
>
|
||||
<PopoverContent>
|
||||
<EuiPopoverTitle>
|
||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||
</EuiPopoverTitle>
|
||||
<EuiSpacer size="s" />
|
||||
{filter}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiAccordion
|
||||
id="accordion1"
|
||||
forceState={showAdvanceSettings ? 'open' : 'closed'}
|
||||
buttonContent={ButtonContent}
|
||||
onToggle={setAdvanceSettings}
|
||||
>
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
{comboBox}
|
||||
</>
|
||||
</EuiAccordion>
|
||||
{!showAdvanceSettings && (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<ConfigHelper size="s" color="subdued">
|
||||
{i18n.CONFIGURE_INDEX_PATTERNS}
|
||||
</ConfigHelper>
|
||||
</>
|
||||
)}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<ResetButton
|
||||
aria-label={i18n.DATA_SOURCES_RESET}
|
||||
data-test-subj="sourcerer-reset"
|
||||
flush="left"
|
||||
onClick={resetDataSources}
|
||||
title={i18n.DATA_SOURCES_RESET}
|
||||
>
|
||||
{i18n.DATA_SOURCES_RESET}
|
||||
</ResetButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={handleSaveIndices}
|
||||
data-test-subj="add-index"
|
||||
fill
|
||||
fullWidth
|
||||
size="s"
|
||||
>
|
||||
{i18n.SAVE_INDEX_PATTERNS}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</PopoverContent>
|
||||
</EuiPopover>
|
||||
</EuiToolTip>
|
||||
<EuiPopover
|
||||
button={buttonWithTooptip}
|
||||
closePopover={closePopover}
|
||||
id="popover"
|
||||
isOpen={isPopoverOpen}
|
||||
repositionOnScroll
|
||||
>
|
||||
<PopoverContent>
|
||||
<EuiPopoverTitle>
|
||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||
</EuiPopoverTitle>
|
||||
<EuiSpacer size="s" />
|
||||
{filter}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiAccordion
|
||||
id="accordion1"
|
||||
forceState={showAdvanceSettings ? 'open' : 'closed'}
|
||||
buttonContent={ButtonContent}
|
||||
onToggle={setAdvanceSettings}
|
||||
>
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
{comboBox}
|
||||
</>
|
||||
</EuiAccordion>
|
||||
{!showAdvanceSettings && (
|
||||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<ConfigHelper size="s" color="subdued">
|
||||
{i18n.CONFIGURE_INDEX_PATTERNS}
|
||||
</ConfigHelper>
|
||||
</>
|
||||
)}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<ResetButton
|
||||
aria-label={i18n.DATA_SOURCES_RESET}
|
||||
data-test-subj="sourcerer-reset"
|
||||
flush="left"
|
||||
onClick={resetDataSources}
|
||||
title={i18n.DATA_SOURCES_RESET}
|
||||
>
|
||||
{i18n.DATA_SOURCES_RESET}
|
||||
</ResetButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={handleSaveIndices}
|
||||
data-test-subj="add-index"
|
||||
fill
|
||||
fullWidth
|
||||
size="s"
|
||||
>
|
||||
{i18n.SAVE_INDEX_PATTERNS}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</PopoverContent>
|
||||
</EuiPopover>
|
||||
</PickEventContainer>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue