[Security Solution] Fix the status of timelines' bulk actions (#74560)

* fix bulk actions

* fix lint error

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Angela Chuang 2020-08-13 10:24:40 +01:00 committed by GitHub
parent 290f9bfde2
commit 1a09c878b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 5 deletions

View file

@ -7,7 +7,7 @@
import { EuiContextMenuPanel, EuiContextMenuItem, EuiBasicTable } from '@elastic/eui';
import React, { useCallback, useMemo } from 'react';
import { TimelineType, TimelineStatus } from '../../../../common/types/timeline';
import { TimelineType } from '../../../../common/types/timeline';
import * as i18n from './translations';
import { DeleteTimelines, OpenTimelineResult } from './types';
@ -66,7 +66,7 @@ export const useEditTimelineBatchActions = ({
const getBatchItemsPopoverContent = useCallback(
(closePopover: () => void) => {
const disabled = selectedItems?.some((item) => item.status === TimelineStatus.immutable);
const disabled = selectedItems == null || selectedItems.length === 0;
return (
<>
<EditTimelineActions
@ -87,6 +87,7 @@ export const useEditTimelineBatchActions = ({
<EuiContextMenuPanel
items={[
<EuiContextMenuItem
data-test-subj="export-timeline-action"
disabled={disabled}
icon="exportAction"
key="ExportItemKey"
@ -95,6 +96,7 @@ export const useEditTimelineBatchActions = ({
{i18n.EXPORT_SELECTED}
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="delete-timeline-action"
disabled={disabled}
icon="trash"
key="DeleteItemKey"
@ -107,7 +109,6 @@ export const useEditTimelineBatchActions = ({
</>
);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[
selectedItems,
deleteTimelines,

View file

@ -9,6 +9,7 @@ import { cloneDeep } from 'lodash/fp';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { act } from '@testing-library/react';
import '../../../common/mock/match_media';
import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines_page';
@ -51,7 +52,7 @@ describe('OpenTimeline', () => {
title,
timelineType: TimelineType.default,
timelineStatus: TimelineStatus.active,
templateTimelineFilter: [<div />],
templateTimelineFilter: [<div key="mock-a" />, <div key="mock-b" />],
totalSearchResultsCount: mockSearchResults.length,
});
@ -279,6 +280,86 @@ describe('OpenTimeline', () => {
expect(wrapper.find('[data-test-subj="utility-bar-action"]').exists()).toEqual(true);
});
test('it should disable export-timeline if no timeline is selected', async () => {
const defaultProps = {
...getDefaultTestProps(mockResults),
timelineStatus: null,
selectedItems: [],
};
const wrapper = mountWithIntl(
<ThemeProvider theme={theme}>
<OpenTimeline {...defaultProps} />
</ThemeProvider>
);
wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click');
await act(async () => {
expect(
wrapper.find('[data-test-subj="export-timeline-action"]').first().prop('disabled')
).toEqual(true);
});
});
test('it should disable delete timeline if no timeline is selected', async () => {
const defaultProps = {
...getDefaultTestProps(mockResults),
timelineStatus: null,
selectedItems: [],
};
const wrapper = mountWithIntl(
<ThemeProvider theme={theme}>
<OpenTimeline {...defaultProps} />
</ThemeProvider>
);
wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click');
await act(async () => {
expect(
wrapper.find('[data-test-subj="delete-timeline-action"]').first().prop('disabled')
).toEqual(true);
});
});
test('it should enable export-timeline if a timeline is selected', async () => {
const defaultProps = {
...getDefaultTestProps(mockResults),
timelineStatus: null,
selectedItems: [{}],
};
const wrapper = mountWithIntl(
<ThemeProvider theme={theme}>
<OpenTimeline {...defaultProps} />
</ThemeProvider>
);
wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click');
await act(async () => {
expect(
wrapper.find('[data-test-subj="export-timeline-action"]').first().prop('disabled')
).toEqual(false);
});
});
test('it should enable delete timeline if a timeline is selected', async () => {
const defaultProps = {
...getDefaultTestProps(mockResults),
timelineStatus: null,
selectedItems: [{}],
};
const wrapper = mountWithIntl(
<ThemeProvider theme={theme}>
<OpenTimeline {...defaultProps} />
</ThemeProvider>
);
wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click');
await act(async () => {
expect(
wrapper.find('[data-test-subj="delete-timeline-action"]').first().prop('disabled')
).toEqual(false);
});
});
test("it should render a selectable timeline table if timelineStatus is active (selecting custom templates' tab)", () => {
const defaultProps = {
...getDefaultTestProps(mockResults),

View file

@ -160,7 +160,6 @@ export const OpenTimeline = React.memo<OpenTimelineProps>(
}, [onDeleteSelected, deleteTimelines, timelineStatus]);
const SearchRowContent = useMemo(() => <>{templateTimelineFilter}</>, [templateTimelineFilter]);
return (
<>
<EditOneTimelineAction