From 5f4d4c13d6a40693a5325d8afbc21c91946e56a4 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 16 Jan 2020 18:51:31 +0100 Subject: [PATCH] [ML] Add jest test for TimeSeriesExplorerUrlStateManager. --- .../navigation_menu/top_nav/top_nav.tsx | 29 +++++++++++----- .../application/routing/routes/index.ts | 2 +- .../routes/timeseriesexplorer.test.tsx | 34 +++++++++++++++++++ .../routing/routes/timeseriesexplorer.tsx | 12 +++++-- 4 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.test.tsx diff --git a/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/top_nav/top_nav.tsx b/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/top_nav/top_nav.tsx index ca6146f3e23b5..eb068f40716bc 100644 --- a/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/top_nav/top_nav.tsx +++ b/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/top_nav/top_nav.tsx @@ -23,12 +23,14 @@ interface Duration { function getRecentlyUsedRangesFactory(timeHistory: TimeHistory) { return function(): Duration[] { - return timeHistory.get().map(({ from, to }: TimeRange) => { - return { - start: from, - end: to, - }; - }); + return ( + timeHistory.get()?.map(({ from, to }: TimeRange) => { + return { + start: from, + end: to, + }; + }) ?? [] + ); }; } @@ -54,9 +56,18 @@ export const TopNav: FC = () => { useEffect(() => { const subscriptions = new Subscription(); - subscriptions.add(timefilter.getRefreshIntervalUpdate$().subscribe(timefilterUpdateListener)); - subscriptions.add(timefilter.getTimeUpdate$().subscribe(timefilterUpdateListener)); - subscriptions.add(timefilter.getEnabledUpdated$().subscribe(timefilterUpdateListener)); + const refreshIntervalUpdate$ = timefilter.getRefreshIntervalUpdate$(); + if (refreshIntervalUpdate$ !== undefined) { + subscriptions.add(refreshIntervalUpdate$.subscribe(timefilterUpdateListener)); + } + const timeUpdate$ = timefilter.getTimeUpdate$(); + if (timeUpdate$ !== undefined) { + subscriptions.add(timeUpdate$.subscribe(timefilterUpdateListener)); + } + const enabledUpdated$ = timefilter.getEnabledUpdated$(); + if (enabledUpdated$ !== undefined) { + subscriptions.add(enabledUpdated$.subscribe(timefilterUpdateListener)); + } return function cleanup() { subscriptions.unsubscribe(); diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/index.ts b/x-pack/legacy/plugins/ml/public/application/routing/routes/index.ts index 89ed35d5588f2..44111ae32cd30 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/index.ts +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/index.ts @@ -10,6 +10,6 @@ export * from './new_job'; export * from './datavisualizer'; export * from './settings'; export * from './data_frame_analytics'; -export * from './timeseriesexplorer'; +export { timeSeriesExplorerRoute } from './timeseriesexplorer'; export * from './explorer'; export * from './access_denied'; diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.test.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.test.tsx new file mode 100644 index 0000000000000..6917ec718d3a8 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.test.tsx @@ -0,0 +1,34 @@ +/* + * 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 React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { render } from '@testing-library/react'; + +import { I18nProvider } from '@kbn/i18n/react'; + +import { TimeSeriesExplorerUrlStateManager } from './timeseriesexplorer'; + +jest.mock('ui/new_platform'); + +describe('TimeSeriesExplorerUrlStateManager', () => { + test('Initial render shows "No single metric jobs found"', () => { + const props = { + config: { get: () => 'Browser' }, + jobsWithTimeRange: [], + }; + + const { container } = render( + + + + + + ); + + expect(container.textContent).toContain('No single metric jobs found'); + }); +}); diff --git a/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx b/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx index 0dfc4809aaa9a..c3c644d43fa59 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/routes/timeseriesexplorer.tsx @@ -74,7 +74,7 @@ interface TimeSeriesExplorerUrlStateManager { jobsWithTimeRange: MlJobWithTimeRange[]; } -const TimeSeriesExplorerUrlStateManager: FC = ({ +export const TimeSeriesExplorerUrlStateManager: FC = ({ config, jobsWithTimeRange, }) => { @@ -113,7 +113,13 @@ const TimeSeriesExplorerUrlStateManager: FC = from: globalState.time.from, to: globalState.time.to, }); - setBounds(timefilter.getBounds()); + + const timefilterBounds = timefilter.getBounds(); + // Only if both min/max bounds are valid moment times set the bounds. + // An invalid string restored from globalState might return `undefined`. + if (timefilterBounds?.min !== undefined && timefilterBounds?.max !== undefined) { + setBounds(timefilter.getBounds()); + } } }, [globalState?.time?.from, globalState?.time?.to]); @@ -138,7 +144,7 @@ const TimeSeriesExplorerUrlStateManager: FC = }, [JSON.stringify(selectedJobIds)]); // Next we get globalState and appState information to pass it on as props later. - // If a job change is going on, we fall back to defaults (as if appState was already cleard), + // If a job change is going on, we fall back to defaults (as if appState was already cleared), // otherwise the page could break. const selectedDetectorIndex = isJobChange ? 0