mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[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 React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
import { waitFor } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
|
||||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||||
import { Sourcerer } from './index';
|
import { Sourcerer } from './index';
|
||||||
import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
|
import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
|
||||||
|
@ -19,8 +22,6 @@ import {
|
||||||
TestProviders,
|
TestProviders,
|
||||||
} from '../../mock';
|
} from '../../mock';
|
||||||
import { createStore, State } from '../../store';
|
import { createStore, State } from '../../store';
|
||||||
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
|
|
||||||
import { waitFor } from '@testing-library/react';
|
|
||||||
|
|
||||||
const mockDispatch = jest.fn();
|
const mockDispatch = jest.fn();
|
||||||
jest.mock('react-redux', () => {
|
jest.mock('react-redux', () => {
|
||||||
|
@ -46,6 +47,7 @@ const mockOptions = [
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
scope: sourcererModel.SourcererScopeName.default,
|
scope: sourcererModel.SourcererScopeName.default,
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Sourcerer component', () => {
|
describe('Sourcerer component', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
@ -59,6 +61,34 @@ describe('Sourcerer component', () => {
|
||||||
store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
|
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,
|
// Using props callback instead of simulating clicks,
|
||||||
// because EuiSelectable uses a virtualized list, which isn't easily testable via test subjects
|
// because EuiSelectable uses a virtualized list, which isn't easily testable via test subjects
|
||||||
it('Mounts with all options selected', () => {
|
it('Mounts with all options selected', () => {
|
||||||
|
|
|
@ -169,55 +169,62 @@ export const Sourcerer = React.memo<SourcererComponentProps>(({ scope: scopeId }
|
||||||
[isPopoverOpen, sourcererScope.selectedPatterns]
|
[isPopoverOpen, sourcererScope.selectedPatterns]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const buttonWithTooptip = useMemo(() => {
|
||||||
|
return tooltipContent ? (
|
||||||
|
<EuiToolTip position="top" content={tooltipContent} data-test-subj="sourcerer-tooltip">
|
||||||
|
{trigger}
|
||||||
|
</EuiToolTip>
|
||||||
|
) : (
|
||||||
|
trigger
|
||||||
|
);
|
||||||
|
}, [trigger, tooltipContent]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EuiToolTip position="top" content={tooltipContent}>
|
<EuiPopover
|
||||||
<EuiPopover
|
data-test-subj="sourcerer-popover"
|
||||||
data-test-subj="sourcerer-popover"
|
button={buttonWithTooptip}
|
||||||
button={trigger}
|
isOpen={isPopoverOpen}
|
||||||
isOpen={isPopoverOpen}
|
closePopover={handleClosePopOver}
|
||||||
closePopover={handleClosePopOver}
|
panelPaddingSize="s"
|
||||||
display="block"
|
repositionOnScroll
|
||||||
panelPaddingSize="s"
|
ownFocus
|
||||||
repositionOnScroll
|
>
|
||||||
ownFocus
|
<PopoverContent>
|
||||||
>
|
<EuiPopoverTitle>
|
||||||
<PopoverContent>
|
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||||
<EuiPopoverTitle>
|
</EuiPopoverTitle>
|
||||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
<EuiSpacer size="s" />
|
||||||
</EuiPopoverTitle>
|
<EuiText color="default">{i18n.INDEX_PATTERNS_SELECTION_LABEL}</EuiText>
|
||||||
<EuiSpacer size="s" />
|
<EuiSpacer size="xs" />
|
||||||
<EuiText color="default">{i18n.INDEX_PATTERNS_SELECTION_LABEL}</EuiText>
|
{comboBox}
|
||||||
<EuiSpacer size="xs" />
|
<EuiSpacer size="s" />
|
||||||
{comboBox}
|
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||||
<EuiSpacer size="s" />
|
<EuiFlexItem>
|
||||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
<ResetButton
|
||||||
<EuiFlexItem>
|
aria-label={i18n.INDEX_PATTERNS_RESET}
|
||||||
<ResetButton
|
data-test-subj="sourcerer-reset"
|
||||||
aria-label={i18n.INDEX_PATTERNS_RESET}
|
flush="left"
|
||||||
data-test-subj="sourcerer-reset"
|
onClick={resetDataSources}
|
||||||
flush="left"
|
title={i18n.INDEX_PATTERNS_RESET}
|
||||||
onClick={resetDataSources}
|
>
|
||||||
title={i18n.INDEX_PATTERNS_RESET}
|
{i18n.INDEX_PATTERNS_RESET}
|
||||||
>
|
</ResetButton>
|
||||||
{i18n.INDEX_PATTERNS_RESET}
|
</EuiFlexItem>
|
||||||
</ResetButton>
|
<EuiFlexItem grow={false}>
|
||||||
</EuiFlexItem>
|
<EuiButton
|
||||||
<EuiFlexItem grow={false}>
|
onClick={handleSaveIndices}
|
||||||
<EuiButton
|
disabled={isSavingDisabled}
|
||||||
onClick={handleSaveIndices}
|
data-test-subj="add-index"
|
||||||
disabled={isSavingDisabled}
|
fill
|
||||||
data-test-subj="add-index"
|
fullWidth
|
||||||
fill
|
size="s"
|
||||||
fullWidth
|
>
|
||||||
size="s"
|
{i18n.SAVE_INDEX_PATTERNS}
|
||||||
>
|
</EuiButton>
|
||||||
{i18n.SAVE_INDEX_PATTERNS}
|
</EuiFlexItem>
|
||||||
</EuiButton>
|
</EuiFlexGroup>
|
||||||
</EuiFlexItem>
|
</PopoverContent>
|
||||||
</EuiFlexGroup>
|
</EuiPopover>
|
||||||
</PopoverContent>
|
|
||||||
</EuiPopover>
|
|
||||||
</EuiToolTip>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
Sourcerer.displayName = 'Sourcerer';
|
Sourcerer.displayName = 'Sourcerer';
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
* 2.0.
|
* 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 React from 'react';
|
||||||
import { PickEventType } from './pick_events';
|
import { PickEventType } from './pick_events';
|
||||||
import {
|
import {
|
||||||
|
@ -19,6 +21,14 @@ import { TimelineEventsType } from '../../../../../common';
|
||||||
import { createStore } from '../../../../common/store';
|
import { createStore } from '../../../../common/store';
|
||||||
import { SourcererScopeName } from '../../../../common/store/sourcerer/model';
|
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', () => {
|
describe('pick_events', () => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
eventType: 'all' as TimelineEventsType,
|
eventType: 'all' as TimelineEventsType,
|
||||||
|
@ -53,6 +63,23 @@ describe('pick_events', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
|
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(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
jest.restoreAllMocks();
|
jest.restoreAllMocks();
|
||||||
|
@ -68,6 +95,32 @@ describe('pick_events', () => {
|
||||||
initialPatterns.sort().join('')
|
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', () => {
|
it('correctly filters options', () => {
|
||||||
const wrapper = render(
|
const wrapper = render(
|
||||||
<TestProviders store={store}>
|
<TestProviders store={store}>
|
||||||
|
|
|
@ -295,6 +295,20 @@ const PickEventTypeComponents: React.FC<PickEventTypeProps> = ({
|
||||||
[isPopoverOpen, sourcererScope.selectedPatterns]
|
[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(
|
const ButtonContent = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<AdvancedSettings data-test-subj="advanced-settings">
|
<AdvancedSettings data-test-subj="advanced-settings">
|
||||||
|
@ -326,69 +340,66 @@ const PickEventTypeComponents: React.FC<PickEventTypeProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PickEventContainer>
|
<PickEventContainer>
|
||||||
<EuiToolTip position="top" content={tooltipContent}>
|
<EuiPopover
|
||||||
<EuiPopover
|
button={buttonWithTooptip}
|
||||||
button={button}
|
closePopover={closePopover}
|
||||||
closePopover={closePopover}
|
id="popover"
|
||||||
id="popover"
|
isOpen={isPopoverOpen}
|
||||||
isOpen={isPopoverOpen}
|
repositionOnScroll
|
||||||
ownFocus
|
>
|
||||||
repositionOnScroll
|
<PopoverContent>
|
||||||
>
|
<EuiPopoverTitle>
|
||||||
<PopoverContent>
|
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
||||||
<EuiPopoverTitle>
|
</EuiPopoverTitle>
|
||||||
<>{i18n.SELECT_INDEX_PATTERNS}</>
|
<EuiSpacer size="s" />
|
||||||
</EuiPopoverTitle>
|
{filter}
|
||||||
<EuiSpacer size="s" />
|
<EuiSpacer size="m" />
|
||||||
{filter}
|
<EuiAccordion
|
||||||
<EuiSpacer size="m" />
|
id="accordion1"
|
||||||
<EuiAccordion
|
forceState={showAdvanceSettings ? 'open' : 'closed'}
|
||||||
id="accordion1"
|
buttonContent={ButtonContent}
|
||||||
forceState={showAdvanceSettings ? 'open' : 'closed'}
|
onToggle={setAdvanceSettings}
|
||||||
buttonContent={ButtonContent}
|
>
|
||||||
onToggle={setAdvanceSettings}
|
<>
|
||||||
>
|
<EuiSpacer size="s" />
|
||||||
<>
|
{comboBox}
|
||||||
<EuiSpacer size="s" />
|
</>
|
||||||
{comboBox}
|
</EuiAccordion>
|
||||||
</>
|
{!showAdvanceSettings && (
|
||||||
</EuiAccordion>
|
<>
|
||||||
{!showAdvanceSettings && (
|
<EuiSpacer size="s" />
|
||||||
<>
|
<ConfigHelper size="s" color="subdued">
|
||||||
<EuiSpacer size="s" />
|
{i18n.CONFIGURE_INDEX_PATTERNS}
|
||||||
<ConfigHelper size="s" color="subdued">
|
</ConfigHelper>
|
||||||
{i18n.CONFIGURE_INDEX_PATTERNS}
|
</>
|
||||||
</ConfigHelper>
|
)}
|
||||||
</>
|
<EuiSpacer size="m" />
|
||||||
)}
|
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||||
<EuiSpacer size="m" />
|
<EuiFlexItem>
|
||||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
<ResetButton
|
||||||
<EuiFlexItem>
|
aria-label={i18n.DATA_SOURCES_RESET}
|
||||||
<ResetButton
|
data-test-subj="sourcerer-reset"
|
||||||
aria-label={i18n.DATA_SOURCES_RESET}
|
flush="left"
|
||||||
data-test-subj="sourcerer-reset"
|
onClick={resetDataSources}
|
||||||
flush="left"
|
title={i18n.DATA_SOURCES_RESET}
|
||||||
onClick={resetDataSources}
|
>
|
||||||
title={i18n.DATA_SOURCES_RESET}
|
{i18n.DATA_SOURCES_RESET}
|
||||||
>
|
</ResetButton>
|
||||||
{i18n.DATA_SOURCES_RESET}
|
</EuiFlexItem>
|
||||||
</ResetButton>
|
<EuiFlexItem grow={false}>
|
||||||
</EuiFlexItem>
|
<EuiButton
|
||||||
<EuiFlexItem grow={false}>
|
onClick={handleSaveIndices}
|
||||||
<EuiButton
|
data-test-subj="add-index"
|
||||||
onClick={handleSaveIndices}
|
fill
|
||||||
data-test-subj="add-index"
|
fullWidth
|
||||||
fill
|
size="s"
|
||||||
fullWidth
|
>
|
||||||
size="s"
|
{i18n.SAVE_INDEX_PATTERNS}
|
||||||
>
|
</EuiButton>
|
||||||
{i18n.SAVE_INDEX_PATTERNS}
|
</EuiFlexItem>
|
||||||
</EuiButton>
|
</EuiFlexGroup>
|
||||||
</EuiFlexItem>
|
</PopoverContent>
|
||||||
</EuiFlexGroup>
|
</EuiPopover>
|
||||||
</PopoverContent>
|
|
||||||
</EuiPopover>
|
|
||||||
</EuiToolTip>
|
|
||||||
</PickEventContainer>
|
</PickEventContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue