Skip to content

Commit

Permalink
fix default timeline's tab (#74051)
Browse files Browse the repository at this point in the history
  • Loading branch information
angorayc authored Aug 3, 2020
1 parent 6337cbf commit 89f1ac4
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,48 @@
* you may not use this file except in compliance with the Elastic License.
*/

/* eslint-disable react/display-name */

import React from 'react';
import { renderHook, act } from '@testing-library/react-hooks';
import { mount } from 'enzyme';
import { MockedProvider } from 'react-apollo/test-utils';
import React from 'react';

// we don't have the types for waitFor just yet, so using "as waitFor" until when we do
import { wait as waitFor } from '@testing-library/react';
import { useHistory, useParams } from 'react-router-dom';

import '../../../common/mock/match_media';
import { SecurityPageName } from '../../../app/types';
import { TimelineType } from '../../../../common/types/timeline';

import { TestProviders, apolloClient } from '../../../common/mock/test_providers';
import { mockOpenTimelineQueryResults } from '../../../common/mock/timeline_results';
import { getTimelineTabsUrl } from '../../../common/components/link_to';

import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines_page';
import { useGetAllTimeline, getAllTimeline } from '../../containers/all';

import { NotePreviews } from './note_previews';
import { OPEN_TIMELINE_CLASS_NAME } from './helpers';

import { StatefulOpenTimeline } from '.';

import { useGetAllTimeline, getAllTimeline } from '../../containers/all';
import { TimelineTabsStyle } from './types';
import {
useTimelineTypes,
UseTimelineTypesArgs,
UseTimelineTypesResult,
} from './use_timeline_types';

import { useParams } from 'react-router-dom';
import { TimelineType } from '../../../../common/types/timeline';
jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');

jest.mock('../../../common/lib/kibana');
jest.mock('../../../common/components/link_to');
return {
...originalModule,
useParams: jest.fn(),
useHistory: jest.fn(),
};
});

jest.mock('./helpers', () => {
const originalModule = jest.requireActual('./helpers');
Expand All @@ -41,24 +60,31 @@ jest.mock('../../containers/all', () => {
return {
...originalModule,
useGetAllTimeline: jest.fn(),
getAllTimeline: originalModule.getAllTimeline,
};
});

jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');
jest.mock('../../../common/lib/kibana');
jest.mock('../../../common/components/link_to');

jest.mock('../../../common/components/link_to', () => {
const originalModule = jest.requireActual('../../../common/components/link_to');
return {
...originalModule,
useParams: jest.fn(),
useHistory: jest.fn().mockReturnValue([]),
getTimelineTabsUrl: jest.fn(),
useFormatUrl: jest.fn().mockReturnValue({ formatUrl: jest.fn(), search: 'urlSearch' }),
};
});

describe('StatefulOpenTimeline', () => {
const title = 'All Timelines / Open Timelines';
let mockHistory: History[];
beforeEach(() => {
(useParams as jest.Mock).mockReturnValue({ tabName: TimelineType.default });
(useParams as jest.Mock).mockReturnValue({
tabName: TimelineType.default,
pageName: SecurityPageName.timelines,
});
mockHistory = [];
(useHistory as jest.Mock).mockReturnValue(mockHistory);
((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({
fetchAllTimeline: jest.fn(),
timelines: getAllTimeline(
Expand All @@ -71,6 +97,13 @@ describe('StatefulOpenTimeline', () => {
});
});

afterEach(() => {
(getTimelineTabsUrl as jest.Mock).mockClear();
(useParams as jest.Mock).mockClear();
(useHistory as jest.Mock).mockClear();
mockHistory = [];
});

test('it has the expected initial state', () => {
const wrapper = mount(
<TestProviders>
Expand Down Expand Up @@ -101,6 +134,109 @@ describe('StatefulOpenTimeline', () => {
});
});

describe("Template timelines' tab", () => {
test("should land on correct timelines' tab with url timelines/default", () => {
const { result } = renderHook<UseTimelineTypesArgs, UseTimelineTypesResult>(
() => useTimelineTypes({ defaultTimelineCount: 0, templateTimelineCount: 0 }),
{
wrapper: ({ children }) => <TestProviders> {children}</TestProviders>,
}
);

expect(result.current.timelineType).toBe(TimelineType.default);
});

test("should land on correct timelines' tab with url timelines/template", () => {
(useParams as jest.Mock).mockReturnValue({
tabName: TimelineType.template,
pageName: SecurityPageName.timelines,
});

const { result } = renderHook<UseTimelineTypesArgs, UseTimelineTypesResult>(
() => useTimelineTypes({ defaultTimelineCount: 0, templateTimelineCount: 0 }),
{
wrapper: ({ children }) => <TestProviders> {children}</TestProviders>,
}
);

expect(result.current.timelineType).toBe(TimelineType.template);
});

test("should land on correct templates' tab after switching tab", () => {
(useParams as jest.Mock).mockReturnValue({
tabName: TimelineType.template,
pageName: SecurityPageName.timelines,
});

const wrapper = mount(
<TestProviders>
<MockedProvider mocks={mockOpenTimelineQueryResults} addTypename={false}>
<StatefulOpenTimeline
data-test-subj="stateful-timeline"
apolloClient={apolloClient}
isModal={false}
defaultPageSize={DEFAULT_SEARCH_RESULTS_PER_PAGE}
title={title}
/>
</MockedProvider>
</TestProviders>
);
wrapper
.find(`[data-test-subj="timeline-${TimelineTabsStyle.tab}-${TimelineType.template}"]`)
.first()
.simulate('click');
act(() => {
expect(history.length).toBeGreaterThan(0);
});
});

test("should selecting correct timelines' filter", () => {
(useParams as jest.Mock).mockReturnValue({
tabName: 'mockTabName',
pageName: SecurityPageName.case,
});

const { result } = renderHook<UseTimelineTypesArgs, UseTimelineTypesResult>(
() => useTimelineTypes({ defaultTimelineCount: 0, templateTimelineCount: 0 }),
{
wrapper: ({ children }) => <TestProviders> {children}</TestProviders>,
}
);

expect(result.current.timelineType).toBe(TimelineType.default);
});

test('should not change url after switching filter', () => {
(useParams as jest.Mock).mockReturnValue({
tabName: 'mockTabName',
pageName: SecurityPageName.case,
});

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>
);
wrapper
.find(
`[data-test-subj="open-timeline-modal-body-${TimelineTabsStyle.filter}-${TimelineType.template}"]`
)
.first()
.simulate('click');
act(() => {
expect(mockHistory.length).toEqual(0);
});
});
});

describe('#onQueryChange', () => {
test('it updates the query state with the expected trimmed value when the user enters a query', () => {
const wrapper = mount(
Expand Down Expand Up @@ -482,9 +618,13 @@ describe('StatefulOpenTimeline', () => {
</TestProviders>
);

expect(wrapper.find('[data-test-subj="open-timeline-modal-body-filters"]').exists()).toEqual(
true
);
expect(
wrapper
.find(
`[data-test-subj="open-timeline-modal-body-${TimelineTabsStyle.filter}-${TimelineType.default}"]`
)
.exists()
).toEqual(true);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ export const useTimelineTypes = ({
const { formatUrl, search: urlSearch } = useFormatUrl(SecurityPageName.timelines);
const { tabName } = useParams<{ pageName: SecurityPageName; tabName: string }>();
const [timelineType, setTimelineTypes] = useState<TimelineTypeLiteralWithNull>(
tabName === TimelineType.default || tabName === TimelineType.template ? tabName : null
tabName === TimelineType.default || tabName === TimelineType.template
? tabName
: TimelineType.default
);

const goToTimeline = useCallback(
Expand Down Expand Up @@ -114,6 +116,7 @@ export const useTimelineTypes = ({
<EuiTabs data-test-subj="open-timeline-subtabs">
{getFilterOrTabs(TimelineTabsStyle.tab).map((tab: TimelineTab) => (
<EuiTab
data-test-subj={`timeline-${TimelineTabsStyle.tab}-${tab.id}`}
isSelected={tab.id === tabName}
disabled={tab.disabled}
key={`timeline-${TimelineTabsStyle.tab}-${tab.id}`}
Expand All @@ -136,7 +139,7 @@ export const useTimelineTypes = ({
const timelineFilters = useMemo(() => {
return getFilterOrTabs(TimelineTabsStyle.filter).map((tab: TimelineTab) => (
<EuiFilterButton
data-test-subj="open-timeline-modal-body-filters"
data-test-subj={`open-timeline-modal-body-${TimelineTabsStyle.filter}-${tab.id}`}
hasActiveFilters={tab.id === timelineType}
key={`timeline-${TimelineTabsStyle.filter}-${tab.id}`}
numFilters={tab.count}
Expand Down

0 comments on commit 89f1ac4

Please sign in to comment.