Skip to content

Commit

Permalink
[ML] add mocks, fix unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
darnautov committed Dec 23, 2020
1 parent d1dc1b1 commit 41562e1
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function optionValueToInterval(value: string) {
return interval;
}

const TABLE_INTERVAL_DEFAULT = optionValueToInterval('auto');
export const TABLE_INTERVAL_DEFAULT = optionValueToInterval('auto');

export const useTableInterval = (): [TableInterval, (v: TableInterval) => void] => {
return usePageUrlState<TableInterval>('mlSelectInterval', TABLE_INTERVAL_DEFAULT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,44 @@
*/

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';
import { TimeSeriesExplorer } from '../../timeseriesexplorer';
import { TimeSeriesExplorerPage } from '../../timeseriesexplorer/timeseriesexplorer_page';
import { TimeseriesexplorerNoJobsFound } from '../../timeseriesexplorer/components/timeseriesexplorer_no_jobs_found';

jest.mock('../../services/toast_notification_service');

jest.mock('../../timeseriesexplorer', () => ({
TimeSeriesExplorer: jest.fn(() => {
return null;
}),
}));

jest.mock('../../timeseriesexplorer/timeseriesexplorer_page', () => ({
TimeSeriesExplorerPage: jest.fn(({ children }) => {
return <>{children}</>;
}),
}));

jest.mock('../../timeseriesexplorer/components/timeseriesexplorer_no_jobs_found', () => ({
TimeseriesexplorerNoJobsFound: jest.fn(() => {
return null;
}),
}));

const MockedTimeSeriesExplorer = TimeSeriesExplorer as jest.MockedClass<typeof TimeSeriesExplorer>;
const MockedTimeSeriesExplorerPage = TimeSeriesExplorerPage as jest.MockedFunction<
typeof TimeSeriesExplorerPage
>;
const MockedTimeseriesexplorerNoJobsFound = TimeseriesexplorerNoJobsFound as jest.MockedFunction<
typeof TimeseriesexplorerNoJobsFound
>;

jest.mock('../../util/url_state');

jest.mock('../../timeseriesexplorer/hooks/use_timeseriesexplorer_url_state');

jest.mock('../../contexts/kibana/kibana_context', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
Expand Down Expand Up @@ -59,27 +91,22 @@ jest.mock('../../contexts/kibana/kibana_context', () => {
};
});

jest.mock('../../util/dependency_cache', () => ({
getToastNotifications: () => ({ addSuccess: jest.fn(), addDanger: jest.fn() }),
}));

jest.mock('../../../../shared_imports');

describe('TimeSeriesExplorerUrlStateManager', () => {
test('Initial render shows "No single metric jobs found"', () => {
test('should render TimeseriesexplorerNoJobsFound when no jobs provided', () => {
const props = {
config: { get: () => 'Browser' },
jobsWithTimeRange: [],
};

const { container } = render(
render(
<I18nProvider>
<MemoryRouter>
<TimeSeriesExplorerUrlStateManager {...props} />
</MemoryRouter>
<TimeSeriesExplorerUrlStateManager {...props} />
</I18nProvider>
);

expect(container.textContent).toContain('No single metric jobs found');
// assert
expect(MockedTimeSeriesExplorer).not.toHaveBeenCalled();
expect(MockedTimeSeriesExplorerPage).toHaveBeenCalled();
expect(MockedTimeseriesexplorerNoJobsFound).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import moment from 'moment';

import { i18n } from '@kbn/i18n';

import { NavigateToPath } from '../../contexts/kibana';
import { NavigateToPath, useNotifications } from '../../contexts/kibana';

import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs';

Expand Down Expand Up @@ -93,6 +93,7 @@ export const TimeSeriesExplorerUrlStateManager: FC<TimeSeriesExplorerUrlStateMan
config,
jobsWithTimeRange,
}) => {
const { toasts } = useNotifications();
const toastNotificationService = useToastNotificationService();
const [
timeSeriesExplorerUrlState,
Expand Down Expand Up @@ -249,7 +250,12 @@ export const TimeSeriesExplorerUrlStateManager: FC<TimeSeriesExplorerUrlStateMan
setLastRefresh(Date.now());
appStateHandler(APP_STATE_ACTION.CLEAR);
}
const validatedJobId = validateJobSelection(jobsWithTimeRange, selectedJobIds, setGlobalState);
const validatedJobId = validateJobSelection(
jobsWithTimeRange,
selectedJobIds,
setGlobalState,
toasts
);
if (typeof validatedJobId === 'string') {
setSelectedJobId(validatedJobId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export const useToastNotificationService = jest.fn();
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const useTimeSeriesExplorerUrlState = jest.fn(() => {
return [{}, jest.fn()];
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { FC } from 'react';
import React from 'react';

import { TimeRangeBounds } from '../explorer/explorer_utils';

declare const TimeSeriesExplorer: FC<{
interface Props {
appStateHandler: (action: string, payload: any) => void;
autoZoomDuration: number;
bounds: TimeRangeBounds;
Expand All @@ -21,4 +21,7 @@ declare const TimeSeriesExplorer: FC<{
tableInterval: string;
tableSeverity: number;
zoom?: { from?: string; to?: string };
}>;
}

// eslint-disable-next-line react/prefer-stateless-function
declare class TimeSeriesExplorer extends React.Component<Props, any> {}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import { difference, without } from 'lodash';

import { i18n } from '@kbn/i18n';

import { getToastNotifications } from '../../util/dependency_cache';

import { ToastsStart } from 'kibana/public';
import { MlJobWithTimeRange } from '../../../../common/types/anomaly_detection_jobs';

import { getTimeRangeFromSelection } from '../../components/job_selector/job_select_service_utils';
Expand All @@ -24,9 +23,9 @@ import { createTimeSeriesJobData } from './timeseriesexplorer_utils';
export function validateJobSelection(
jobsWithTimeRange: MlJobWithTimeRange[],
selectedJobIds: string[],
setGlobalState: (...args: any) => void
setGlobalState: (...args: any) => void,
toastNotifications: ToastsStart
) {
const toastNotifications = getToastNotifications();
const jobs = createTimeSeriesJobData(mlJobService.jobs);
const timeSeriesJobIds: string[] = jobs.map((j: any) => j.id);

Expand Down
27 changes: 27 additions & 0 deletions x-pack/plugins/ml/public/application/util/__mocks__/url_state.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 { AppStateKey } from '../url_state';
import { TABLE_INTERVAL_DEFAULT } from '../../components/controls/select_interval/select_interval';

export const useUrlState = jest.fn((accessor: '_a' | '_g') => {
if (accessor === '_g') {
return [{ refreshInterval: { value: 0, pause: true } }, jest.fn()];
}
});

export const usePageUrlState = jest.fn((pageKey: AppStateKey) => {
let state: unknown;
switch (pageKey) {
case 'timeseriesexplorer':
state = {};
break;
case 'mlSelectInterval':
state = TABLE_INTERVAL_DEFAULT;
break;
}
return [state, jest.fn()];
});
4 changes: 3 additions & 1 deletion x-pack/plugins/ml/public/application/util/url_state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ export const urlStateStore = createContext<UrlState>({
searchString: '',
setUrlState: () => {},
});

const { Provider } = urlStateStore;

export const UrlStateProvider: FC = ({ children }) => {
const history = useHistory();
const { search: searchString } = useLocation();
Expand Down Expand Up @@ -164,7 +166,7 @@ export const useUrlState = (accessor: Accessor) => {

type LegacyUrlKeys = 'mlExplorerSwimlane';

type AppStateKey =
export type AppStateKey =
| 'mlSelectSeverity'
| 'mlSelectInterval'
| 'mlAnomaliesTable'
Expand Down

0 comments on commit 41562e1

Please sign in to comment.