[Uptime] Tests/uptime testing utils (#87650)

* add additional component test helpers

* add test examples

* uptime testing utils remove custom prefix from props and parameter options

* skip executed step tests

* adjust MlJobLink test

* add testing util interfaces

* update mock core

* combine wrappers into one custom render function

* split enzyme helpers and rtl helpers into different files and adjust types

* adjust types

* spread core on render function

* remove unnecessary items from MLJobLink test

* update use_monitor_breadcrumbs test

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dominique Clarke 2021-01-11 20:02:23 -05:00 committed by GitHub
parent f54f155305
commit ca31bd80b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 162 additions and 203 deletions

View file

@ -1,117 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ML JobLink renders without errors 1`] = `
<a
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small"
href="/app/ml#/explorer?_g=(ml:(jobIds:!(testmonitor_high_latency_by_geo)),refreshInterval:(pause:!t,value:0),time:(from:'',to:''))&_a=(mlExplorerFilter:(filterActive:!t,filteredFields:!(monitor.id,testMonitor)),mlExplorerSwimlane:(viewByFieldName:observer.geo.name))"
rel="noopener noreferrer"
target="_blank"
>
<span
class="euiButtonContent euiButtonEmpty__content"
>
<span
class="euiButtonEmpty__text"
/>
</span>
</a>
`;
exports[`ML JobLink shallow renders without errors 1`] = `
<ContextProvider
value={
Object {
"history": Object {
"action": "POP",
"block": [Function],
"canGo": [Function],
"createHref": [Function],
"entries": Array [
Object {
"hash": "",
"key": "TestKeyForTesting",
"pathname": "/",
"search": "",
"state": undefined,
},
],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"index": 0,
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"key": "TestKeyForTesting",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
"location": Object {
"hash": "",
"key": "TestKeyForTesting",
"pathname": "/",
"search": "",
"state": undefined,
},
"match": Object {
"isExact": true,
"params": Object {},
"path": "/",
"url": "/",
},
"staticContext": undefined,
}
}
>
<ContextProvider
value={
Object {
"action": "POP",
"block": [Function],
"canGo": [Function],
"createHref": [Function],
"entries": Array [
Object {
"hash": "",
"key": "TestKeyForTesting",
"pathname": "/",
"search": "",
"state": undefined,
},
],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"index": 0,
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"key": "TestKeyForTesting",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
}
}
>
<MLJobLink
basePath=""
dateRange={
Object {
"from": "",
"to": "",
}
}
monitorId="testMonitor"
/>
</ContextProvider>
</ContextProvider>
`;

View file

@ -5,28 +5,20 @@
*/
import React from 'react';
import { coreMock } from 'src/core/public/mocks';
import { renderWithRouter, shallowWithRouter } from '../../../lib';
import { render } from '../../../lib/helper/rtl_helpers';
import { MLJobLink } from './ml_job_link';
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
const core = coreMock.createStart();
describe('ML JobLink', () => {
it('shallow renders without errors', () => {
const wrapper = shallowWithRouter(
<MLJobLink dateRange={{ to: '', from: '' }} basePath="" monitorId="testMonitor" />
);
expect(wrapper).toMatchSnapshot();
});
it('renders without errors', () => {
const wrapper = renderWithRouter(
<KibanaContextProvider
services={{ ...core, triggersActionsUi: { getEditAlertFlyout: jest.fn() } }}
>
<MLJobLink dateRange={{ to: '', from: '' }} basePath="" monitorId="testMonitor" />
</KibanaContextProvider>
const expectedHref = `/app/ml#/explorer?_g=(ml:(jobIds:!(testmonitor_high_latency_by_geo)),refreshInterval:(pause:!t,value:0),time:(from:'',to:''))&_a=(mlExplorerFilter:(filterActive:!t,filteredFields:!(monitor.id,testMonitor)),mlExplorerSwimlane:(viewByFieldName:observer.geo.name))`;
const { getByRole, getByText } = render(
<MLJobLink dateRange={{ to: '', from: '' }} basePath="" monitorId="testMonitor">
<div>Test link</div>
</MLJobLink>
);
expect(wrapper).toMatchSnapshot();
const jobLink = getByRole('link');
expect(jobLink.getAttribute('href')).toBe(expectedHref);
expect(getByText('Test link'));
});
});

View file

@ -8,6 +8,7 @@ import React from 'react';
import { ExecutedStep } from './executed_step';
import { Ping } from '../../../../common/runtime_types';
import { mountWithRouter } from '../../../lib';
import { render } from '../../../lib/helper/rtl_helpers';
// FLAKY: https://github.com/elastic/kibana/issues/85899
describe.skip('ExecutedStep', () => {
@ -35,32 +36,9 @@ describe.skip('ExecutedStep', () => {
});
it('renders correct step heading', () => {
expect(
mountWithRouter(<ExecutedStep index={3} step={step} checkGroup={'fake-group'} />).find(
'EuiText'
)
).toMatchInlineSnapshot(`
<EuiText>
<div
className="euiText euiText--medium"
>
<strong>
<FormattedMessage
defaultMessage="{stepNumber}. {stepName}"
id="xpack.uptime.synthetics.executedStep.stepName"
values={
Object {
"stepName": "STEP_NAME",
"stepNumber": 4,
}
}
>
4. STEP_NAME
</FormattedMessage>
</strong>
</div>
</EuiText>
`);
const { getByText } = render(<ExecutedStep index={3} step={step} checkGroup={'fake-group'} />);
expect(getByText(`${step?.synthetics?.step?.index}. ${step?.synthetics?.step?.name}`));
});
it('renders a link to the step detail view', () => {

View file

@ -8,16 +8,37 @@ import { ChromeBreadcrumb } from 'kibana/public';
import React from 'react';
import { Route } from 'react-router-dom';
import { of } from 'rxjs';
import { MountWithReduxProvider, mountWithRouter } from '../../../../lib';
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
import { render } from '../../../../lib/helper/rtl_helpers';
import { useMonitorBreadcrumb } from './use_monitor_breadcrumb';
import { OVERVIEW_ROUTE } from '../../../../../common/constants';
import { Ping } from '../../../../../common/runtime_types/ping';
import { JourneyState } from '../../../../state/reducers/journey';
import { chromeServiceMock, uiSettingsServiceMock } from 'src/core/public/mocks';
describe('useMonitorBreadcrumbs', () => {
it('sets the given breadcrumbs', () => {
const [getBreadcrumbs, core] = mockCore();
let breadcrumbObj: ChromeBreadcrumb[] = [];
const getBreadcrumbs = () => {
return breadcrumbObj;
};
const core = {
chrome: {
...chromeServiceMock.createStartContract(),
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => {
breadcrumbObj = newBreadcrumbs;
},
},
uiSettings: {
...uiSettingsServiceMock.createSetupContract(),
get(key: string, defaultOverride?: any): any {
return `MMM D, YYYY @ HH:mm:ss.SSS` || defaultOverride;
},
get$(key: string, defaultOverride?: any): any {
return of(`MMM D, YYYY @ HH:mm:ss.SSS`) || of(defaultOverride);
},
},
};
const Component = () => {
useMonitorBreadcrumb({
@ -27,14 +48,11 @@ describe('useMonitorBreadcrumbs', () => {
return <>Step Water Fall</>;
};
mountWithRouter(
<MountWithReduxProvider>
<KibanaContextProvider services={{ ...core }}>
<Route path={OVERVIEW_ROUTE}>
<Component />
</Route>
</KibanaContextProvider>
</MountWithReduxProvider>
render(
<Route path={OVERVIEW_ROUTE}>
<Component />
</Route>,
{ core }
);
expect(getBreadcrumbs()).toMatchInlineSnapshot(`
@ -56,27 +74,3 @@ describe('useMonitorBreadcrumbs', () => {
`);
});
});
const mockCore: () => [() => ChromeBreadcrumb[], any] = () => {
let breadcrumbObj: ChromeBreadcrumb[] = [];
const get = () => {
return breadcrumbObj;
};
const core = {
application: {
getUrlForApp: () => '/app/uptime',
navigateToUrl: jest.fn(),
},
chrome: {
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => {
breadcrumbObj = newBreadcrumbs;
},
},
uiSettings: {
get: (key: string) => 'MMM D, YYYY @ HH:mm:ss.SSS',
get$: (key: string) => of('MMM D, YYYY @ HH:mm:ss.SSS'),
},
};
return [get, core];
};

View file

@ -5,12 +5,13 @@
*/
import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants';
import { AppState } from '../../state';
/**
* NOTE: This variable name MUST start with 'mock*' in order for
* Jest to accept its use within a jest.mock()
*/
export const mockStore = {
export const mockState: AppState = {
overviewFilters: {
filters: {
locations: [],
@ -111,8 +112,11 @@ export const mockStore = {
alerts: {
alertDeletion: { data: null, loading: false },
anomalyAlert: { data: null, loading: false },
anomalyAlertDeletion: { data: null, loading: false },
alerts: { data: null, loading: false },
connectors: { data: null, loading: false },
newAlert: { data: null, loading: false },
},
journeys: {},
networkEvents: {},
};

View file

@ -5,13 +5,12 @@
*/
import React, { ReactElement } from 'react';
import { Router } from 'react-router-dom';
import { MemoryHistory } from 'history/createMemoryHistory';
import { createMemoryHistory } from 'history';
import { mountWithIntl, renderWithIntl, shallowWithIntl } from '@kbn/test/jest';
import { AppState } from '../../state';
import { MountWithReduxProvider } from './helper_with_redux';
import { AppState } from '../../state';
const helperWithRouter: <R>(
helper: (node: ReactElement) => R,
@ -28,7 +27,7 @@ const helperWithRouter: <R>(
if (wrapReduxStore) {
return helper(
<MountWithReduxProvider store={storeState}>{routerWrapper}</MountWithReduxProvider>
<MountWithReduxProvider state={storeState}>{routerWrapper}</MountWithReduxProvider>
);
}

View file

@ -8,11 +8,11 @@ import React from 'react';
import { Provider as ReduxProvider } from 'react-redux';
import { AppState } from '../../state';
export const MountWithReduxProvider: React.FC<{ store?: AppState }> = ({ children, store }) => (
export const MountWithReduxProvider: React.FC<{ state?: AppState }> = ({ children, state }) => (
<ReduxProvider
store={{
dispatch: jest.fn(),
getState: jest.fn().mockReturnValue(store || { selectedFilters: null }),
getState: jest.fn().mockReturnValue(state || { selectedFilters: null }),
subscribe: jest.fn(),
replaceReducer: jest.fn(),
}}

View file

@ -0,0 +1,109 @@
/*
* 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, { ReactElement } from 'react';
import { render as reactTestLibRender, RenderOptions } from '@testing-library/react';
import { Router } from 'react-router-dom';
import { createMemoryHistory, History } from 'history';
import { CoreStart } from 'kibana/public';
import { I18nProvider } from '@kbn/i18n/react';
import { coreMock } from 'src/core/public/mocks';
import { mockState } from '../__mocks__/uptime_store.mock';
import {
KibanaContextProvider,
KibanaServices,
} from '../../../../../../src/plugins/kibana_react/public';
import { MountWithReduxProvider } from './helper_with_redux';
import { AppState } from '../../state';
interface KibanaProps {
services?: KibanaServices;
}
interface KibanaProviderOptions<ExtraCore> {
core?: Partial<CoreStart> & ExtraCore;
kibanaProps?: KibanaProps;
}
interface MockKibanaProviderProps<ExtraCore> extends KibanaProviderOptions<ExtraCore> {
children: ReactElement;
}
interface MockRouterProps<ExtraCore> extends MockKibanaProviderProps<ExtraCore> {
history?: History;
}
interface RenderRouterOptions<ExtraCore> extends KibanaProviderOptions<ExtraCore> {
history?: History;
renderOptions?: Omit<RenderOptions, 'queries'>;
state?: Partial<AppState>;
}
/* default mock core */
const defaultCore = coreMock.createStart();
const mockCore: () => any = () => {
const core = {
...defaultCore,
application: {
getUrlForApp: () => '/app/uptime',
navigateToUrl: jest.fn(),
},
};
return core;
};
/* Mock Provider Components */
export function MockKibanaProvider<ExtraCore>({
children,
core,
kibanaProps,
}: MockKibanaProviderProps<ExtraCore>) {
const coreOptions = {
...mockCore(),
...core,
};
return (
<KibanaContextProvider services={{ ...coreOptions }} {...kibanaProps}>
<I18nProvider>{children}</I18nProvider>
</KibanaContextProvider>
);
}
export function MockRouter<ExtraCore>({
children,
core,
history: customHistory,
kibanaProps,
}: MockRouterProps<ExtraCore>) {
const history = customHistory || createMemoryHistory();
return (
<Router history={history}>
<MockKibanaProvider core={core} kibanaProps={kibanaProps}>
{children}
</MockKibanaProvider>
</Router>
);
}
/* Custom react testing library render */
export function render<ExtraCore>(
ui: ReactElement,
{ history, core, kibanaProps, renderOptions, state }: RenderRouterOptions<ExtraCore> = {}
) {
const testState: AppState = {
...mockState,
...state,
};
return reactTestLibRender(
<MountWithReduxProvider state={testState}>
<MockRouter history={history} kibanaProps={kibanaProps} core={core}>
{ui}
</MockRouter>
</MountWithReduxProvider>,
renderOptions
);
}

View file

@ -5,4 +5,4 @@
*/
export { MountWithReduxProvider } from './helper';
export * from './helper/helper_with_router';
export * from './helper/enzyme_helpers';