Skip to content

Commit

Permalink
add search in breadcrumb + fix existing unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
XavierM committed Sep 4, 2019
1 parent 9bbebed commit ecfe07a
Show file tree
Hide file tree
Showing 28 changed files with 888 additions and 680 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
import chrome from 'ui/chrome';
import '../../../mock/match_media';
import { encodeIpv6 } from '../../../lib/helpers';
import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../pages/hosts/details/utils';
import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../pages/network/ip_details';
import { TIMELINES_PAGE_NAME } from '../../link_to/redirect_to_timelines';

import { getBreadcrumbsForRoute, rootBreadcrumbs, setBreadcrumbs } from '.';
import { getBreadcrumbsForRoute, setBreadcrumbs } from '.';
import { HostsTableType } from '../../../store/hosts/model';
import { SiemPageName } from '../../../pages/home/home_navigations';
import { RouteSpyState } from '../../../utils/route/spy_routes';
import { TabNavigationProps } from '../type';

jest.mock('ui/chrome', () => ({
getBasePath: () => {
Expand All @@ -26,96 +24,184 @@ jest.mock('ui/chrome', () => ({
}),
}));

const getMockObject = (
pageName: string,
pathName: string,
detailName: string | undefined
): RouteSpyState & TabNavigationProps => ({
detailName,
hostDetails: { filterQuery: null, queryLocation: null },
hosts: { filterQuery: null, queryLocation: null },
navTabs: {
hosts: {
disabled: false,
href: '#/link-to/hosts',
id: 'hosts',
name: 'Hosts',
urlKey: 'host',
},
network: {
disabled: false,
href: '#/link-to/network',
id: 'network',
name: 'Network',
urlKey: 'network',
},
overview: {
disabled: false,
href: '#/link-to/overview',
id: 'overview',
name: 'Overview',
urlKey: 'overview',
},
timelines: {
disabled: false,
href: '#/link-to/timelines',
id: 'timelines',
name: 'Timelines',
urlKey: 'timeline',
},
},
network: { filterQuery: null, queryLocation: null },
pageName,
pathName,
search: '',
tabName: HostsTableType.authentications,
timelineId: '',
timerange: {
global: {
linkTo: ['timeline'],
timerange: {
from: 1558048243696,
fromStr: 'now-24h',
kind: 'relative',
to: 1558134643697,
toStr: 'now',
},
},
timeline: {
linkTo: ['global'],
timerange: {
from: 1558048243696,
fromStr: 'now-24h',
kind: 'relative',
to: 1558134643697,
toStr: 'now',
},
},
},
});

describe('Navigation Breadcrumbs', () => {
const hostName = 'siem-kibana';
const hostDetailsParams = {
pageName: SiemPageName.hosts,
hostName,
tabName: HostsTableType.authentications,
};
const hostBreadcrumbs = [
...rootBreadcrumbs.overview,
...getHostDetailsBreadcrumbs(hostDetailsParams),
];

const ipv4 = '192.0.2.255';
const ipv4Breadcrumbs = [...rootBreadcrumbs.overview, ...getIPDetailsBreadcrumbs(ipv4)];
const ipv6 = '2001:db8:ffff:ffff:ffff:ffff:ffff:ffff';
const ipv6Encoded = encodeIpv6(ipv6);
const ipv6Breadcrumbs = [...rootBreadcrumbs.overview, ...getIPDetailsBreadcrumbs(ipv6Encoded)];
describe('getBreadcrumbsForRoute', () => {
test('should return Host breadcrumbs when supplied link-to host pathname', () => {
const pathname = '/link-to/hosts';
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.hosts);
});

describe('getBreadcrumbsForRoute', () => {
test('should return Host breadcrumbs when supplied host pathname', () => {
const pathname = '/hosts';
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.hosts);
});

test('should return Host breadcrumbs when supplied host pathname with trailing slash', () => {
const pathname = '/hosts/';
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.hosts);
const breadcrumbs = getBreadcrumbsForRoute(getMockObject('hosts', '/hosts', undefined));
expect(breadcrumbs).toEqual([
{
href: '#/link-to/overview',
text: 'SIEM',
},
{
href:
'#/link-to/hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
text: 'Hosts',
},
{
href: '',
text: 'Authentications',
},
]);
});

test('should return Network breadcrumbs when supplied network pathname', () => {
const pathname = '/network';
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.network);
});

test('should return Timelines breadcrumbs when supplied link-to timelines pathname', () => {
const pathname = `/link-to/${TIMELINES_PAGE_NAME}`;
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.timelines);
const breadcrumbs = getBreadcrumbsForRoute(getMockObject('network', '/network', undefined));
expect(breadcrumbs).toEqual([
{ text: 'SIEM', href: '#/link-to/overview' },
{
text: 'Network',
href:
'#/link-to/network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
]);
});

test('should return Timelines breadcrumbs when supplied timelines pathname', () => {
const pathname = '/timelines';
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(rootBreadcrumbs.timelines);
});

test('should return Host Details breadcrumbs when supplied link-to pathname with hostName', () => {
const pathname = `/link-to/hosts/${hostName}`;

const breadcrumbs = getBreadcrumbsForRoute(pathname, hostDetailsParams);
expect(breadcrumbs).toEqual(hostBreadcrumbs);
const breadcrumbs = getBreadcrumbsForRoute(
getMockObject('timelines', '/timelines', undefined)
);
expect(breadcrumbs).toEqual([
{ text: 'SIEM', href: '#/link-to/overview' },
{ text: 'Timelines', href: '' },
]);
});

test('should return Host Details breadcrumbs when supplied a pathname with hostName', () => {
const pathname = `/hosts/${hostName}`;

const breadcrumbs = getBreadcrumbsForRoute(pathname, hostDetailsParams);
expect(breadcrumbs).toEqual(hostBreadcrumbs);
});

test('should return IP Details breadcrumbs when supplied link-to pathname with ipv4', () => {
const pathname = `link-to/network/ip/${ipv4}`;
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(ipv4Breadcrumbs);
const breadcrumbs = getBreadcrumbsForRoute(getMockObject('hosts', '/hosts', hostName));
expect(breadcrumbs).toEqual([
{ text: 'SIEM', href: '#/link-to/overview' },
{
text: 'Hosts',
href:
'#/link-to/hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{
text: 'siem-kibana',
href:
'#/link-to/hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{ text: 'Authentications', href: '' },
]);
});

test('should return IP Details breadcrumbs when supplied pathname with ipv4', () => {
const pathname = `/network/ip/${ipv4}`;
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(ipv4Breadcrumbs);
const breadcrumbs = getBreadcrumbsForRoute(getMockObject('network', '/network', ipv4));
expect(breadcrumbs).toEqual([
{ text: 'SIEM', href: '#/link-to/overview' },
{
text: 'Network',
href:
'#/link-to/network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{ text: '192.0.2.255', href: '' },
]);
});

test('should return IP Details breadcrumbs when supplied pathname with ipv6', () => {
const pathname = `/network/ip/${ipv6Encoded}`;
const breadcrumbs = getBreadcrumbsForRoute(pathname);
expect(breadcrumbs).toEqual(ipv6Breadcrumbs);
const breadcrumbs = getBreadcrumbsForRoute(getMockObject('network', '/network', ipv6Encoded));
expect(breadcrumbs).toEqual([
{ text: 'SIEM', href: '#/link-to/overview' },
{
text: 'Network',
href:
'#/link-to/network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{ text: '2001:db8:ffff:ffff:ffff:ffff:ffff:ffff', href: '' },
]);
});
});
describe('setBreadcrumbs()', () => {
test('should call chrome breadcrumb service with correct breadcrumbs', () => {
const pathname = `/hosts/${hostName}`;
setBreadcrumbs(pathname, hostDetailsParams);
expect(chrome.breadcrumbs.set).toBeCalledWith(hostBreadcrumbs);
setBreadcrumbs(getMockObject('hosts', '/hosts', hostName));
expect(chrome.breadcrumbs.set).toBeCalledWith([
{ text: 'SIEM', href: '#/link-to/overview' },
{
text: 'Hosts',
href:
'#/link-to/hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{
text: 'siem-kibana',
href:
'#/link-to/hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))',
},
{ text: 'Authentications', href: '' },
]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,18 @@

import chrome, { Breadcrumb } from 'ui/chrome';

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 { getNetworkUrl, getOverviewUrl, getTimelinesUrl } from '../../link_to';
import * as i18n from '../translations';
import { getHostsUrl } from '../../link_to/redirect_to_hosts';
import { HostsTableType } from '../../../store/hosts/model';
import { getOverviewUrl } from '../../link_to';
import { SiemPageName } from '../../../pages/home/home_navigations';
import { TabNavigationProps, SearchNavTab } from '../type';
import { getSearch } from '../helpers';
import { RouteSpyState } from '../../../utils/route/spy_routes';

export interface NavigationParams {
pageName?: SiemPageName;
hostName?: string;
tabName?: HostsTableType;
}

export const setBreadcrumbs = (pathname: string, params?: NavigationParams) => {
const breadcrumbs = getBreadcrumbsForRoute(pathname, params);
export const setBreadcrumbs = (object: RouteSpyState & TabNavigationProps) => {
const breadcrumbs = getBreadcrumbsForRoute(object);
if (breadcrumbs) {
chrome.breadcrumbs.set(breadcrumbs);
}
Expand All @@ -35,48 +30,49 @@ export const siemRootBreadcrumb: Breadcrumb[] = [
},
];

export const rootBreadcrumbs: { [name: string]: Breadcrumb[] } = {
overview: siemRootBreadcrumb,
hosts: [
...siemRootBreadcrumb,
{
text: i18n.HOSTS,
href: getHostsUrl(),
},
],
network: [
...siemRootBreadcrumb,
{
text: i18n.NETWORK,
href: getNetworkUrl(),
},
],
timelines: [
...siemRootBreadcrumb,
{
text: i18n.TIMELINES,
href: getTimelinesUrl(),
},
],
};

export const getBreadcrumbsForRoute = (
pathname: string,
params?: NavigationParams
object: RouteSpyState & TabNavigationProps
): Breadcrumb[] | null => {
const removeSlash = pathname.replace(/\/$/, '');
const trailingPath = removeSlash.match(/([^\/]+$)/);

if (trailingPath !== null) {
if (params != null && params.pageName === SiemPageName.hosts) {
return [...siemRootBreadcrumb, ...getHostDetailsBreadcrumbs(params)];
}
if (Object.keys(rootBreadcrumbs).includes(trailingPath[0])) {
return rootBreadcrumbs[trailingPath[0]];
}
if (pathname.match(/network\/ip\/.*?/)) {
return [...siemRootBreadcrumb, ...getIPDetailsBreadcrumbs(trailingPath[0])];
if (object != null && object.navTabs && object.pageName === SiemPageName.hosts) {
const tempNav: SearchNavTab = { urlKey: 'host', isDetailPage: false };
let urlStateKeys = [getOr(tempNav, object.pageName, object.navTabs)];
if (object.tabName != null) {
urlStateKeys = [...urlStateKeys, getOr(tempNav, object.tabName, object.navTabs)];
}
return [
...siemRootBreadcrumb,
...getHostDetailsBreadcrumbs(
object,
urlStateKeys.reduce((acc: string[], item: SearchNavTab) => {
acc = [...acc, getSearch(item, object)];
return acc;
}, [])
),
];
}
if (object != null && object.navTabs && object.pageName === SiemPageName.network) {
const tempNav: SearchNavTab = { urlKey: 'network', isDetailPage: false };
const urlStateKeys = [getOr(tempNav, object.pageName, object.navTabs)];
return [
...siemRootBreadcrumb,
...getIPDetailsBreadcrumbs(
object.detailName,
urlStateKeys.reduce((acc: string[], item) => {
acc = [...acc, getSearch(item, object)];
return acc;
}, [])
),
];
}
if (object != null && object.navTabs && object.pageName && object.navTabs[object.pageName]) {
return [
...siemRootBreadcrumb,
{
text: object.navTabs[object.pageName].name,
href: '',
},
];
}

return null;
};
Loading

0 comments on commit ecfe07a

Please sign in to comment.