Skip to content

Commit

Permalink
[Security Solutions][Timeline] Added createFrom in action to hide (el…
Browse files Browse the repository at this point in the history
…astic#98144)

* added createFrom in action to hide

* prettier configured

* tests to check timeline modal table actions

* test changes and contant extract

* removed unused dependency

* prevent adding empty column to timeline table when no action need

* test updated

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
semd and kibanamachine committed Apr 29, 2021
1 parent 3ac08ba commit aba7a5a
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,38 @@
*/

import React from 'react';
import { shallow } from 'enzyme';
import { mount, shallow } from 'enzyme';

import { QueryBarDefineRule } from './index';
import { useFormFieldMock } from '../../../../common/mock';
import {
TestProviders,
useFormFieldMock,
mockOpenTimelineQueryResults,
} from '../../../../common/mock';
import { mockHistory, Router } from '../../../../cases/components/__mock__/router';
import { useGetAllTimeline, getAllTimeline } from '../../../../timelines/containers/all';

jest.mock('../../../../common/lib/kibana');

jest.mock('../../../../timelines/containers/all', () => {
const originalModule = jest.requireActual('../../../../timelines/containers/all');
return {
...originalModule,
useGetAllTimeline: jest.fn(),
};
});

describe('QueryBarDefineRule', () => {
beforeEach(() => {
((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({
fetchAllTimeline: jest.fn(),
timelines: getAllTimeline('', mockOpenTimelineQueryResults.timeline ?? []),
loading: false,
totalCount: mockOpenTimelineQueryResults.totalCount,
refetch: jest.fn(),
});
});

it('renders correctly', () => {
const Component = () => {
const field = useFormFieldMock();
Expand All @@ -32,7 +56,35 @@ describe('QueryBarDefineRule', () => {
);
};
const wrapper = shallow(<Component />);

expect(wrapper.dive().find('[data-test-subj="query-bar-define-rule"]')).toHaveLength(1);
});

it('renders import query from saved timeline modal actions hidden correctly', () => {
const Component = () => {
const field = useFormFieldMock();

return (
<QueryBarDefineRule
browserFields={{}}
isLoading={false}
indexPattern={{ fields: [], title: 'title' }}
onCloseTimelineSearch={jest.fn()}
openTimelineSearch={true}
dataTestSubj="query-bar-define-rule"
idAria="idAria"
field={field}
/>
);
};
const wrapper = mount(
<TestProviders>
<Router history={mockHistory}>
<Component />
</Router>
</TestProviders>
);

expect(wrapper.find('[data-test-subj="open-duplicate"]').exists()).toBeFalsy();
expect(wrapper.find('[data-test-subj="create-from-template"]').exists()).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { EuiFormRow, EuiMutationObserver } from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { Subscription } from 'rxjs';
import styled from 'styled-components';
import deepEqual from 'fast-deep-equal';
Expand Down Expand Up @@ -50,6 +50,8 @@ interface QueryBarDefineRuleProps {
onValidityChange?: (arg: boolean) => void;
}

const actionTimelineToHide: ActionTimelineToShow[] = ['duplicate', 'createFrom'];

const StyledEuiFormRow = styled(EuiFormRow)`
.kbnTypeahead__items {
max-height: 45vh !important;
Expand Down Expand Up @@ -253,8 +255,6 @@ export const QueryBarDefineRule = ({
}
};

const actionTimelineToHide = useMemo<ActionTimelineToShow[]>(() => ['duplicate'], []);

return (
<>
<StyledEuiFormRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,38 @@ import { waitFor } from '@testing-library/react';
import { AddTimelineButton } from './';
import { useKibana } from '../../../../common/lib/kibana';
import { TimelineId } from '../../../../../common/types/timeline';
import { mockOpenTimelineQueryResults, TestProviders } from '../../../../common/mock';
import { mockHistory, Router } from '../../../../cases/components/__mock__/router';
import { getAllTimeline, useGetAllTimeline } from '../../../containers/all';

jest.mock('../../open_timeline/use_timeline_status', () => {
const originalModule = jest.requireActual('../../open_timeline/use_timeline_status');
return {
...originalModule,
useTimelineStatus: jest.fn().mockReturnValue({
timelineStatus: 'active',
templateTimelineFilter: [],
installPrepackagedTimelines: jest.fn(),
}),
};
});

jest.mock('../../../../common/lib/kibana', () => ({
useKibana: jest.fn(),
useUiSetting$: jest.fn().mockReturnValue([]),
}));
jest.mock('../../../../common/lib/kibana', () => {
const originalModule = jest.requireActual('../../../../common/lib/kibana');
return {
...originalModule,
useKibana: jest.fn(),
useUiSetting$: jest.fn().mockReturnValue([]),
};
});

jest.mock('../../../containers/all', () => {
const originalModule = jest.requireActual('../../../containers/all');
return {
...originalModule,
useGetAllTimeline: jest.fn(),
};
});

jest.mock('../../timeline/properties/new_template_timeline', () => ({
NewTemplateTimeline: jest.fn(() => <div data-test-subj="create-template-btn" />),
Expand All @@ -35,8 +62,7 @@ jest.mock('../../../../common/components/inspect', () => ({
InspectButtonContainer: jest.fn(({ children }) => <div>{children}</div>),
}));

// FLAKY: https://github.com/elastic/kibana/issues/96691
describe.skip('AddTimelineButton', () => {
describe('AddTimelineButton', () => {
let wrapper: ReactWrapper;
const props = {
timelineId: TimelineId.active,
Expand Down Expand Up @@ -67,24 +93,24 @@ describe.skip('AddTimelineButton', () => {
});

test('it renders create timeline btn', async () => {
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="create-default-btn"]').exists()).toBeTruthy();
});
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="create-default-btn"]').exists()).toBeTruthy()
);
});

test('it renders create timeline template btn', async () => {
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="create-template-btn"]').exists()).toBeTruthy();
});
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="create-template-btn"]').exists()).toBeTruthy()
);
});

test('it renders Open timeline btn', async () => {
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="open-timeline-button"]').exists()).toBeTruthy();
});
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="open-timeline-button"]').exists()).toBeTruthy()
);
});
});

Expand Down Expand Up @@ -113,24 +139,86 @@ describe.skip('AddTimelineButton', () => {
});

test('it renders create timeline btn', async () => {
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="create-default-btn"]').exists()).toBeTruthy();
});
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="create-default-btn"]').exists()).toBeTruthy()
);
});

test('it renders create timeline template btn', async () => {
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="create-template-btn"]').exists()).toBeTruthy();
});
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="create-template-btn"]').exists()).toBeTruthy()
);
});

test('it renders Open timeline btn', async () => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="open-timeline-button"]').exists()).toBeTruthy()
);
});
});

describe('open modal', () => {
beforeEach(() => {
(useKibana as jest.Mock).mockReturnValue({
services: {
application: {
getUrlForApp: jest.fn(),
capabilities: {
siem: {
crud: true,
},
},
},
},
});

((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({
fetchAllTimeline: jest.fn(),
timelines: getAllTimeline('', mockOpenTimelineQueryResults.timeline ?? []),
loading: false,
totalCount: mockOpenTimelineQueryResults.totalCount,
refetch: jest.fn(),
});

wrapper = mount(
<TestProviders>
<Router history={mockHistory}>
<AddTimelineButton {...props} />
</Router>
</TestProviders>
);
});

afterEach(() => {
(useKibana as jest.Mock).mockReset();
});

it('should render timelines table', async () => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="open-timeline-button"]').exists()).toBeTruthy();
});

wrapper.find('[data-test-subj="open-timeline-button"]').first().simulate('click');
await waitFor(() => {
expect(wrapper.find('[data-test-subj="timelines-table"]').exists()).toBeTruthy();
});
});

it('should render correct actions', async () => {
wrapper.find('[data-test-subj="settings-plus-in-circle"]').last().simulate('click');
await waitFor(() =>
expect(wrapper.find('[data-test-subj="open-timeline-button"]').exists()).toBeTruthy()
);

wrapper.find('[data-test-subj="open-timeline-button"]').first().simulate('click');
await waitFor(() => {
expect(wrapper.find('[data-test-subj="open-duplicate"]').exists()).toBeTruthy();
expect(wrapper.find('[data-test-subj="create-from-template"]').exists()).toBeFalsy();
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React, { useCallback, useMemo, useState } from 'react';

import { OpenTimelineModalButton } from '../../open_timeline/open_timeline_modal/open_timeline_modal_button';
import { OpenTimelineModal } from '../../open_timeline/open_timeline_modal';
import { ActionTimelineToShow } from '../../open_timeline/types';
import * as i18n from '../../timeline/properties/translations';
import { NewTimeline } from '../../timeline/properties/helpers';
import { NewTemplateTimeline } from '../../timeline/properties/new_template_timeline';
Expand All @@ -20,6 +21,8 @@ interface AddTimelineButtonComponentProps {

export const ADD_TIMELINE_BUTTON_CLASS_NAME = 'add-timeline-button';

const actionTimelineToHide: ActionTimelineToShow[] = ['createFrom'];

const AddTimelineButtonComponent: React.FC<AddTimelineButtonComponentProps> = ({ timelineId }) => {
const [showActions, setShowActions] = useState(false);
const [showTimelineModal, setShowTimelineModal] = useState(false);
Expand Down Expand Up @@ -83,7 +86,9 @@ const AddTimelineButtonComponent: React.FC<AddTimelineButtonComponentProps> = ({
</EuiPopover>
</EuiFlexItem>

{showTimelineModal ? <OpenTimelineModal onClose={onCloseTimelineModal} /> : null}
{showTimelineModal ? (
<OpenTimelineModal onClose={onCloseTimelineModal} hideActions={actionTimelineToHide} />
) : null}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ export const getTimelinesTableColumns = ({
}),
...getExtendedColumns(showExtendedColumns),
...getIconHeaderColumns({ timelineType }),
...getActionsColumns({
actionTimelineToShow,
deleteTimelines,
enableExportTimelineDownloader,
onOpenDeleteTimelineModal,
onOpenTimeline,
}),
...(actionTimelineToShow.length
? getActionsColumns({
actionTimelineToShow,
deleteTimelines,
enableExportTimelineDownloader,
onOpenDeleteTimelineModal,
onOpenTimeline,
})
: []),
];
};

Expand Down

0 comments on commit aba7a5a

Please sign in to comment.