Skip to content

Commit

Permalink
clean up + unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
XavierM committed Sep 5, 2019
1 parent f7f1480 commit 0ee232a
Show file tree
Hide file tree
Showing 16 changed files with 336 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { encodeIpv6 } from '../../../lib/helpers';

import { getBreadcrumbsForRoute, setBreadcrumbs } from '.';
import { HostsTableType } from '../../../store/hosts/model';
import { RouteSpyState } from '../../../utils/route/spy_routes';
import { RouteSpyState } from '../../../utils/route/types';
import { TabNavigationProps } from '../type';

jest.mock('ui/chrome', () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import { getOr } from 'lodash/fp';
import { APP_NAME } from '../../../../common/constants';
import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../pages/hosts/details/utils';
import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../pages/network/ip_details';
import { getOverviewUrl } from '../../link_to';
import { SiemPageName } from '../../../pages/home/home_navigations';
import { RouteSpyState } from '../../../utils/route/types';
import { getOverviewUrl } from '../../link_to';

import { TabNavigationProps, SearchNavTab } from '../type';
import { getSearch } from '../helpers';
import { RouteSpyState } from '../../../utils/route/spy_routes';

export const setBreadcrumbs = (object: RouteSpyState & TabNavigationProps) => {
const breadcrumbs = getBreadcrumbsForRoute(object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { setBreadcrumbs } from './breadcrumbs';
import { navTabs } from '../../pages/home/home_navigations';
import { TabNavigationProps } from './type';
import { HostsTableType } from '../../store/hosts/model';
import { RouteSpyState } from '../../utils/route/spy_routes';
import { RouteSpyState } from '../../utils/route/types';

jest.mock('./breadcrumbs', () => ({
setBreadcrumbs: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { isEqual } from 'lodash/fp';
import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';

import { isEqual } from 'lodash/fp';
import { RouteSpyState } from '../../utils/route/types';
import { useRouteSpy } from '../../utils/route/use_route_spy';
import { CONSTANTS } from '../url_state/constants';

import { setBreadcrumbs } from './breadcrumbs';
import { TabNavigation } from './tab_navigation';
import { TabNavigationProps, SiemNavigationComponentProps } from './type';
Expand All @@ -21,8 +25,6 @@ import {
hostsModel,
networkModel,
} from '../../store';
import { CONSTANTS } from '../url_state/constants';
import { RouteSpyState, useRouteSpy } from '../../utils/route/spy_routes';

export class SiemNavigationComponent extends React.Component<TabNavigationProps & RouteSpyState> {
public shouldComponentUpdate(nextProps: Readonly<TabNavigationProps & RouteSpyState>): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { navTabs, SiemPageName } from '../../../pages/home/home_navigations';
import { HostsTableType } from '../../../store/hosts/model';
import { navTabsHostDetails } from '../../../pages/hosts/hosts_navigations';
import { CONSTANTS } from '../../url_state/constants';
import { RouteSpyState } from '../../../utils/route/spy_routes';
import { RouteSpyState } from '../../../utils/route/types';

describe('Tab Navigation', () => {
const pageName = SiemPageName.hosts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { defaultProps, getMockPropsObj, mockHistory, testCases } from './test_de
import { UrlStateContainerPropTypes } from './types';
import { useUrlStateHooks } from './use_url_state';
import { CONSTANTS } from './constants';
import { RouteSpyState } from '../../utils/route/spy_routes';
import { RouteSpyState } from '../../utils/route/types';
import { SiemPageName } from '../../pages/home/home_navigations';

let mockProps: UrlStateContainerPropTypes;
Expand All @@ -44,7 +44,7 @@ const mockRouteSpy: RouteSpyState = {
search: '',
pathName: '/network',
};
jest.mock('../../utils/route/spy_routes', () => ({
jest.mock('../../utils/route/use_route_spy', () => ({
useRouteSpy: () => [mockRouteSpy],
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,22 @@ import {
timelineSelectors,
} from '../../store';
import { hostsActions, inputsActions, networkActions, timelineActions } from '../../store/actions';
import { RouteSpyState } from '../../utils/route/types';
import { useRouteSpy } from '../../utils/route/use_route_spy';

import { CONSTANTS } from './constants';
import { UrlStateContainerPropTypes, UrlStateProps, KqlQuery, LocationTypes } from './types';
import { useUrlStateHooks } from './use_url_state';
import { dispatchUpdateTimeline } from '../open_timeline/helpers';
import { getCurrentLocation } from './helpers';
import { useRouteSpy, RouteSpyState } from '../../utils/route/spy_routes';

export const UrlStateContainer = React.memo<UrlStateContainerPropTypes>(
props => {
(props: UrlStateContainerPropTypes) => {
useUrlStateHooks(props);
return null;
},
(prevProps, nextProps) =>
prevProps.pageName === nextProps.pageName &&
prevProps.pathName === nextProps.pathName &&
isEqual(prevProps.urlState, nextProps.urlState)
prevProps.pathName === nextProps.pathName && isEqual(prevProps.urlState, nextProps.urlState)
);

UrlStateContainer.displayName = 'UrlStateContainer';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { Dispatch } from 'redux';
import { hostsModel, KueryFilterQuery, networkModel, SerializedFilterQuery } from '../../store';
import { UrlInputsModel } from '../../store/inputs/model';
import { InputsModelId } from '../../store/inputs/constants';
import { RouteSpyState } from '../../utils/route/types';

import { CONSTANTS } from './constants';
import { DispatchUpdateTimeline } from '../open_timeline/types';
import { RouteSpyState } from '../../utils/route/spy_routes';

export type UrlStateType = 'host' | 'network' | 'overview' | 'timeline';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { getHostsUrl, getHostDetailsUrl } from '../../../components/link_to/redi

import * as i18n from '../translations';
import { convertKueryToElasticSearchQuery, escapeQueryValue } from '../../../lib/keury';
import { RouteSpyState } from '../../../utils/route/spy_routes';
import { RouteSpyState } from '../../../utils/route/types';

export const type = hostsModel.HostsType.details;

Expand Down
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/siem/public/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Route, Router, Switch } from 'react-router-dom';

import { NotFoundPage } from './pages/404';
import { HomePage } from './pages/home';
import { ManageRoutesSpy } from './utils/route/spy_routes';
import { ManageRoutesSpy } from './utils/route/manage_spy_routes';

interface RouterProps {
history: History;
Expand Down
23 changes: 23 additions & 0 deletions x-pack/legacy/plugins/siem/public/utils/route/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { noop } from 'lodash/fp';
import { createContext, Dispatch } from 'react';

import { RouteSpyState, RouteSpyAction } from './types';

export const initRouteSpy: RouteSpyState = {
pageName: '',
detailName: undefined,
tabName: undefined,
search: '',
pathName: '/',
};

export const RouterSpyStateContext = createContext<[RouteSpyState, Dispatch<RouteSpyAction>]>([
initRouteSpy,
() => noop,
]);
202 changes: 202 additions & 0 deletions x-pack/legacy/plugins/siem/public/utils/route/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

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

import { HostsTableType } from '../../store/hosts/model';
import { RouteSpyState } from './types';
import { ManageRoutesSpy } from './manage_spy_routes';
import { SpyRouteComponent } from './spy_routes';
import { useRouteSpy } from './use_route_spy';

type Action = 'PUSH' | 'POP' | 'REPLACE';
const pop: Action = 'POP';

const defaultLocation = {
hash: '',
pathname: '/hosts',
search: '',
state: '',
};

export const mockHistory = {
action: pop,
block: jest.fn(),
createHref: jest.fn(),
go: jest.fn(),
goBack: jest.fn(),
goForward: jest.fn(),
length: 2,
listen: jest.fn(),
location: defaultLocation,
push: jest.fn(),
replace: jest.fn(),
};

const dispatchMock = jest.fn();
const mockRoutes: RouteSpyState = {
pageName: '',
detailName: undefined,
tabName: undefined,
search: '',
pathName: '/',
history: mockHistory,
};

const mockUseRouteSpy: jest.Mock = useRouteSpy as jest.Mock;
jest.mock('./use_route_spy', () => ({
useRouteSpy: jest.fn(),
}));

describe('Spy Routes', () => {
describe('At Initialization of the app', () => {
beforeEach(() => {
dispatchMock.mockReset();
dispatchMock.mockClear();
});
test('Make sure we update search state first', () => {
const pathname = '/';
mockUseRouteSpy.mockImplementation(() => [mockRoutes, dispatchMock]);
mount(
<ManageRoutesSpy>
<SpyRouteComponent
location={{ hash: '', pathname, search: '?importantQueryString="really"', state: '' }}
history={mockHistory}
match={{
isExact: false,
path: pathname,
url: pathname,
params: {
pageName: undefined,
detailName: '',
tabName: HostsTableType.hosts,
search: '',
},
}}
/>
</ManageRoutesSpy>
);

expect(dispatchMock.mock.calls[0]).toEqual([
{
type: 'updateSearch',
search: '?importantQueryString="really"',
},
]);
});

test('Make sure we update search state first and then update the route but keeping the initial search', () => {
const pathname = '/hosts/allHosts';
mockUseRouteSpy.mockImplementation(() => [mockRoutes, dispatchMock]);
mount(
<ManageRoutesSpy>
<SpyRouteComponent
location={{ hash: '', pathname, search: '?importantQueryString="really"', state: '' }}
history={mockHistory}
match={{
isExact: false,
path: pathname,
url: pathname,
params: {
pageName: 'hosts',
detailName: undefined,
tabName: HostsTableType.hosts,
search: '?IdoNotWantToSeeYou="true"',
},
}}
/>
</ManageRoutesSpy>
);

expect(dispatchMock.mock.calls[0]).toEqual([
{
type: 'updateSearch',
search: '?importantQueryString="really"',
},
]);

expect(dispatchMock.mock.calls[1]).toEqual([
{
route: {
detailName: undefined,
history: mockHistory,
pageName: 'hosts',
pathName: pathname,
tabName: HostsTableType.hosts,
},
type: 'updateRouteWithOutSearch',
},
]);
});
});

describe('When app is running', () => {
beforeEach(() => {
dispatchMock.mockReset();
dispatchMock.mockClear();
});
test('Update route should be updated when there is changed detected', () => {
const pathname = '/hosts/allHosts';
const newPathname = `hosts/${HostsTableType.authentications}`;
mockUseRouteSpy.mockImplementation(() => [mockRoutes, dispatchMock]);
const wrapper = mount(
<SpyRouteComponent
location={{ hash: '', pathname, search: '?importantQueryString="really"', state: '' }}
history={mockHistory}
match={{
isExact: false,
path: pathname,
url: pathname,
params: {
pageName: 'hosts',
detailName: undefined,
tabName: HostsTableType.hosts,
search: '?IdoNotWantToSeeYou="true"',
},
}}
/>
);

dispatchMock.mockReset();
dispatchMock.mockClear();

wrapper.setProps({
location: {
hash: '',
pathname: newPathname,
search: '?updated="true"',
state: '',
},
match: {
isExact: false,
path: newPathname,
url: newPathname,
params: {
pageName: 'hosts',
detailName: undefined,
tabName: HostsTableType.authentications,
search: '',
},
},
});
wrapper.update();
expect(dispatchMock.mock.calls[0]).toEqual([
{
route: {
detailName: undefined,
history: mockHistory,
pageName: 'hosts',
pathName: newPathname,
tabName: HostsTableType.authentications,
search: '?updated="true"',
},
type: 'updateRoute',
},
]);
});
});
});
Loading

0 comments on commit 0ee232a

Please sign in to comment.