[Security Solution] Fix unexpected redirect (#73969)

* fix unexpected redirect

* fix types

Co-authored-by: Patryk Kopycinski <contact@patrykkopycinski.com>
This commit is contained in:
Angela Chuang 2020-07-31 22:17:24 +01:00 committed by GitHub
parent 2e37239e50
commit 2c71a3fba9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 27 deletions

View file

@ -17,11 +17,25 @@ import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines_page';
import { NotePreviews } from './note_previews';
import { OPEN_TIMELINE_CLASS_NAME } from './helpers';
import { TimelineTabsStyle } from './types';
import { StatefulOpenTimeline } from '.';
import { useGetAllTimeline, getAllTimeline } from '../../containers/all';
import { useParams } from 'react-router-dom';
import { TimelineType } from '../../../../common/types/timeline';
jest.mock('../../../common/lib/kibana');
jest.mock('../../../common/components/link_to');
jest.mock('./helpers', () => {
const originalModule = jest.requireActual('./helpers');
return {
...originalModule,
queryTimelineById: jest.fn(),
};
});
jest.mock('../../containers/all', () => {
const originalModule = jest.requireActual('../../containers/all');
return {
@ -30,19 +44,21 @@ jest.mock('../../containers/all', () => {
getAllTimeline: originalModule.getAllTimeline,
};
});
jest.mock('./use_timeline_types', () => {
jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');
return {
useTimelineTypes: jest.fn().mockReturnValue({
timelineType: 'default',
timelineTabs: <div data-test-subj="timeline-tab" />,
timelineFilters: <div data-test-subj="timeline-filter" />,
}),
...originalModule,
useParams: jest.fn(),
useHistory: jest.fn().mockReturnValue([]),
};
});
describe('StatefulOpenTimeline', () => {
const title = 'All Timelines / Open Timelines';
beforeEach(() => {
(useParams as jest.Mock).mockReturnValue({ tabName: TimelineType.default });
((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({
fetchAllTimeline: jest.fn(),
timelines: getAllTimeline(
@ -433,10 +449,7 @@ describe('StatefulOpenTimeline', () => {
});
});
/**
* enable this test when createtTemplateTimeline is ready
*/
test.skip('it renders the tabs', async () => {
test('it has the expected initial state for openTimeline - templateTimelineFilter', () => {
const wrapper = mount(
<TestProviders>
<MockedProvider mocks={mockOpenTimelineQueryResults} addTypename={false}>
@ -451,11 +464,27 @@ describe('StatefulOpenTimeline', () => {
</TestProviders>
);
await waitFor(() => {
expect(
wrapper.find(`[data-test-subj="timeline-${TimelineTabsStyle.tab}"]`).exists()
).toEqual(true);
});
expect(wrapper.find('[data-test-subj="open-timeline-subtabs"]').exists()).toEqual(true);
});
test('it has the expected initial state for openTimelineModalBody - templateTimelineFilter', () => {
const wrapper = mount(
<TestProviders>
<MockedProvider mocks={mockOpenTimelineQueryResults} addTypename={false}>
<StatefulOpenTimeline
data-test-subj="stateful-timeline"
apolloClient={apolloClient}
isModal={true}
defaultPageSize={DEFAULT_SEARCH_RESULTS_PER_PAGE}
title={title}
/>
</MockedProvider>
</TestProviders>
);
expect(wrapper.find('[data-test-subj="open-timeline-modal-body-filters"]').exists()).toEqual(
true
);
});
});

View file

@ -7,26 +7,31 @@ import React, { useState, useCallback, useMemo } from 'react';
import { useParams, useHistory } from 'react-router-dom';
import { EuiTabs, EuiTab, EuiSpacer, EuiFilterButton } from '@elastic/eui';
import { noop } from 'lodash/fp';
import { TimelineTypeLiteralWithNull, TimelineType } from '../../../../common/types/timeline';
import { SecurityPageName } from '../../../app/types';
import { getTimelineTabsUrl, useFormatUrl } from '../../../common/components/link_to';
import * as i18n from './translations';
import { TimelineTabsStyle, TimelineTab } from './types';
export const useTimelineTypes = ({
defaultTimelineCount,
templateTimelineCount,
}: {
export interface UseTimelineTypesArgs {
defaultTimelineCount?: number | null;
templateTimelineCount?: number | null;
}): {
}
export interface UseTimelineTypesResult {
timelineType: TimelineTypeLiteralWithNull;
timelineTabs: JSX.Element;
timelineFilters: JSX.Element[];
} => {
}
export const useTimelineTypes = ({
defaultTimelineCount,
templateTimelineCount,
}: UseTimelineTypesArgs): UseTimelineTypesResult => {
const history = useHistory();
const { formatUrl, search: urlSearch } = useFormatUrl(SecurityPageName.timelines);
const { tabName } = useParams<{ pageName: string; tabName: string }>();
const { tabName } = useParams<{ pageName: SecurityPageName; tabName: string }>();
const [timelineType, setTimelineTypes] = useState<TimelineTypeLiteralWithNull>(
tabName === TimelineType.default || tabName === TimelineType.template ? tabName : null
);
@ -61,7 +66,7 @@ export const useTimelineTypes = ({
timelineTabsStyle === TimelineTabsStyle.filter
? defaultTimelineCount ?? undefined
: undefined,
onClick: goToTimeline,
onClick: timelineTabsStyle === TimelineTabsStyle.tab ? goToTimeline : noop,
},
{
id: TimelineType.template,
@ -76,7 +81,7 @@ export const useTimelineTypes = ({
timelineTabsStyle === TimelineTabsStyle.filter
? templateTimelineCount ?? undefined
: undefined,
onClick: goToTemplateTimeline,
onClick: timelineTabsStyle === TimelineTabsStyle.tab ? goToTemplateTimeline : noop,
},
],
[
@ -106,7 +111,7 @@ export const useTimelineTypes = ({
const timelineTabs = useMemo(() => {
return (
<>
<EuiTabs>
<EuiTabs data-test-subj="open-timeline-subtabs">
{getFilterOrTabs(TimelineTabsStyle.tab).map((tab: TimelineTab) => (
<EuiTab
isSelected={tab.id === tabName}
@ -131,6 +136,7 @@ export const useTimelineTypes = ({
const timelineFilters = useMemo(() => {
return getFilterOrTabs(TimelineTabsStyle.filter).map((tab: TimelineTab) => (
<EuiFilterButton
data-test-subj="open-timeline-modal-body-filters"
hasActiveFilters={tab.id === timelineType}
key={`timeline-${TimelineTabsStyle.filter}-${tab.id}`}
numFilters={tab.count}

View file

@ -33,7 +33,7 @@ const TimelinesContainer = styled.div`
export const DEFAULT_SEARCH_RESULTS_PER_PAGE = 10;
export const TimelinesPageComponent: React.FC = () => {
const { tabName } = useParams();
const { tabName } = useParams<{ pageName: SecurityPageName; tabName: string }>();
const [importDataModalToggle, setImportDataModalToggle] = useState<boolean>(false);
const onImportTimelineBtnClick = useCallback(() => {
setImportDataModalToggle(true);