Jest and Storybook fixes for observability plugin (#106255)

* Get rid of all the Jest console warnings
* Make sure none of the observability storybook pages throw errors (whether they all work correctly or are useful is another matter, but they all load now.)
This commit is contained in:
Nathan L Smith 2021-08-03 09:15:36 -05:00 committed by GitHub
parent 6d145c807c
commit b1a0c7dd93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 255 additions and 149 deletions

View file

@ -47,6 +47,11 @@ export function WebCoreVitalsTitle({
const closePopover = () => setIsPopoverOpen(false);
const closeBrowserPopover = () => setIsBrowserPopoverOpen(false);
const helpAriaLabel = i18n.translate(
'xpack.observability.ux.dashboard.webCoreVitals.helpAriaLabel',
{ defaultMessage: 'help' }
);
return (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem>
@ -57,6 +62,7 @@ export function WebCoreVitalsTitle({
isOpen={isPopoverOpen}
button={
<EuiButtonIcon
aria-label={helpAriaLabel}
onClick={() => setIsPopoverOpen(true)}
color={'text'}
iconType={'questionInCircle'}
@ -99,6 +105,7 @@ export function WebCoreVitalsTitle({
isOpen={isBrowserPopoverOpen}
button={
<EuiButtonIcon
aria-label={helpAriaLabel}
onClick={() => setIsBrowserPopoverOpen(true)}
color={'text'}
iconType={'questionInCircle'}

View file

@ -5,8 +5,8 @@
* 2.0.
*/
import { fireEvent, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { getDefaultConfigs } from '../../configurations/default_configs';
import {
mockAppIndexPattern,
@ -29,14 +29,16 @@ describe('Series Builder ReportDefinitionCol', function () {
mockUseValuesList([{ label: 'elastic-co', count: 10 }]);
it('should render properly', async function () {
it('renders', async () => {
render(
<ReportDefinitionCol seriesConfig={seriesConfig} seriesId={seriesId} series={mockUxSeries} />
);
screen.getByText('Web Application');
screen.getByText('Environment');
screen.getByText('Search Environment');
await waitFor(() => {
expect(screen.getByText('Web Application')).toBeInTheDocument();
expect(screen.getByText('Environment')).toBeInTheDocument();
expect(screen.getByText('Search Environment')).toBeInTheDocument();
});
});
it('should render selected report definitions', async function () {

View file

@ -6,7 +6,7 @@
*/
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { FilterExpanded } from './filter_expanded';
import { mockUxSeries, mockAppIndexPattern, mockUseValuesList, render } from '../../rtl_helpers';
import { USER_AGENT_NAME } from '../../configurations/constants/elasticsearch_fieldnames';
@ -16,7 +16,7 @@ describe('FilterExpanded', function () {
const mockSeries = { ...mockUxSeries, filters };
it('should render properly', async function () {
it('render', async () => {
const initSeries = { filters };
mockAppIndexPattern();
@ -31,8 +31,11 @@ describe('FilterExpanded', function () {
{ initSeries }
);
screen.getByText('Browser Family');
await waitFor(() => {
screen.getByText('Browser Family');
});
});
it('should call go back on click', async function () {
const initSeries = { filters };
@ -47,10 +50,12 @@ describe('FilterExpanded', function () {
{ initSeries }
);
fireEvent.click(screen.getByText('Browser Family'));
await waitFor(() => {
fireEvent.click(screen.getByText('Browser Family'));
});
});
it('should call useValuesList on load', async function () {
it('calls useValuesList on load', async () => {
const initSeries = { filters };
const { spy } = mockUseValuesList([
@ -69,15 +74,18 @@ describe('FilterExpanded', function () {
{ initSeries }
);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toBeCalledWith(
expect.objectContaining({
time: { from: 'now-15m', to: 'now' },
sourceField: USER_AGENT_NAME,
})
);
await waitFor(() => {
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toBeCalledWith(
expect.objectContaining({
time: { from: 'now-15m', to: 'now' },
sourceField: USER_AGENT_NAME,
})
);
});
});
it('should filter display values', async function () {
it('filters display values', async () => {
const initSeries = { filters };
mockUseValuesList([
@ -96,13 +104,15 @@ describe('FilterExpanded', function () {
{ initSeries }
);
fireEvent.click(screen.getByText('Browser Family'));
await waitFor(() => {
fireEvent.click(screen.getByText('Browser Family'));
expect(screen.queryByText('Firefox')).toBeTruthy();
expect(screen.queryByText('Firefox')).toBeTruthy();
fireEvent.input(screen.getByRole('searchbox'), { target: { value: 'ch' } });
fireEvent.input(screen.getByRole('searchbox'), { target: { value: 'ch' } });
expect(screen.queryByText('Firefox')).toBeFalsy();
expect(screen.getByText('Chrome')).toBeTruthy();
expect(screen.queryByText('Firefox')).toBeFalsy();
expect(screen.getByText('Chrome')).toBeTruthy();
});
});
});

View file

@ -6,7 +6,7 @@
*/
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { FilterValueButton } from './filter_value_btn';
import { mockUxSeries, mockUseSeriesFilter, mockUseValuesList, render } from '../../rtl_helpers';
import {
@ -15,7 +15,7 @@ import {
} from '../../configurations/constants/elasticsearch_fieldnames';
describe('FilterValueButton', function () {
it('should render properly', async function () {
it('renders', async () => {
render(
<FilterValueButton
field={USER_AGENT_NAME}
@ -28,77 +28,90 @@ describe('FilterValueButton', function () {
/>
);
screen.getByText('Chrome');
});
it('should render display negate state', async function () {
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={true}
series={mockUxSeries}
/>
);
screen.getByText('Not Chrome');
screen.getByTitle('Not Chrome');
const btn = screen.getByRole('button');
expect(btn.classList).toContain('euiButtonEmpty--danger');
});
it('should call set filter on click', async function () {
const { setFilter, removeFilter } = mockUseSeriesFilter();
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={true}
allSelectedValues={['Firefox']}
series={mockUxSeries}
/>
);
fireEvent.click(screen.getByText('Not Chrome'));
expect(removeFilter).toHaveBeenCalledTimes(0);
expect(setFilter).toHaveBeenCalledTimes(1);
expect(setFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: true,
value: 'Chrome',
await waitFor(() => {
expect(screen.getByText('Chrome')).toBeInTheDocument();
});
});
it('should remove filter on click if already selected', async function () {
const { removeFilter } = mockUseSeriesFilter();
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={false}
allSelectedValues={['Chrome', 'Firefox']}
series={mockUxSeries}
/>
);
describe('when negate is true', () => {
it('displays negate stats', async () => {
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={true}
series={mockUxSeries}
/>
);
fireEvent.click(screen.getByText('Chrome'));
await waitFor(() => {
expect(screen.getByText('Not Chrome')).toBeInTheDocument();
expect(screen.getByTitle('Not Chrome')).toBeInTheDocument();
const btn = screen.getByRole('button');
expect(btn.classList).toContain('euiButtonEmpty--danger');
});
});
expect(removeFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: false,
value: 'Chrome',
it('calls setFilter on click', async () => {
const { setFilter, removeFilter } = mockUseSeriesFilter();
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={true}
allSelectedValues={['Firefox']}
series={mockUxSeries}
/>
);
fireEvent.click(screen.getByText('Not Chrome'));
await waitFor(() => {
expect(removeFilter).toHaveBeenCalledTimes(0);
expect(setFilter).toHaveBeenCalledTimes(1);
expect(setFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: true,
value: 'Chrome',
});
});
});
});
describe('when selected', () => {
it('removes the filter on click', async () => {
const { removeFilter } = mockUseSeriesFilter();
render(
<FilterValueButton
field={USER_AGENT_NAME}
seriesId={0}
value={'Chrome'}
isNestedOpen={{ value: '', negate: false }}
setIsNestedOpen={jest.fn()}
negate={false}
allSelectedValues={['Chrome', 'Firefox']}
series={mockUxSeries}
/>
);
fireEvent.click(screen.getByText('Chrome'));
await waitFor(() => {
expect(removeFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: false,
value: 'Chrome',
});
});
});
});
@ -120,10 +133,12 @@ describe('FilterValueButton', function () {
fireEvent.click(screen.getByText('Not Chrome'));
expect(removeFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: true,
value: 'Chrome',
await waitFor(() => {
expect(removeFilter).toHaveBeenCalledWith({
field: 'user_agent.name',
negate: true,
value: 'Chrome',
});
});
});
@ -145,19 +160,21 @@ describe('FilterValueButton', function () {
/>
);
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).toBeCalledWith(
expect.objectContaining({
filters: [
{
term: {
[USER_AGENT_NAME]: 'Chrome',
await waitFor(() => {
expect(spy).toHaveBeenCalledTimes(2);
expect(spy).toBeCalledWith(
expect.objectContaining({
filters: [
{
term: {
[USER_AGENT_NAME]: 'Chrome',
},
},
},
],
sourceField: 'user_agent.version',
})
);
],
sourceField: 'user_agent.version',
})
);
});
});
it('should set isNestedOpen on click', async function () {
mockUseSeriesFilter();
@ -177,19 +194,21 @@ describe('FilterValueButton', function () {
/>
);
expect(spy).toHaveBeenCalledTimes(6);
expect(spy).toBeCalledWith(
expect.objectContaining({
filters: [
{
term: {
[USER_AGENT_NAME]: 'Chrome',
await waitFor(() => {
expect(spy).toHaveBeenCalledTimes(6);
expect(spy).toBeCalledWith(
expect.objectContaining({
filters: [
{
term: {
[USER_AGENT_NAME]: 'Chrome',
},
},
},
],
sourceField: USER_AGENT_VERSION,
})
);
],
sourceField: USER_AGENT_VERSION,
})
);
});
});
it('should set call setIsNestedOpen on click selected', async function () {
@ -213,9 +232,10 @@ describe('FilterValueButton', function () {
);
fireEvent.click(screen.getByText('Chrome'));
expect(setIsNestedOpen).toHaveBeenCalledTimes(1);
expect(setIsNestedOpen).toHaveBeenCalledWith({ negate: false, value: '' });
await waitFor(() => {
expect(setIsNestedOpen).toHaveBeenCalledTimes(1);
expect(setIsNestedOpen).toHaveBeenCalledWith({ negate: false, value: '' });
});
});
it('should set call setIsNestedOpen on click not selected', async function () {
@ -239,8 +259,9 @@ describe('FilterValueButton', function () {
);
fireEvent.click(screen.getByText('Not Chrome'));
expect(setIsNestedOpen).toHaveBeenCalledTimes(1);
expect(setIsNestedOpen).toHaveBeenCalledWith({ negate: true, value: 'Chrome' });
await waitFor(() => {
expect(setIsNestedOpen).toHaveBeenCalledTimes(1);
expect(setIsNestedOpen).toHaveBeenCalledWith({ negate: true, value: 'Chrome' });
});
});
});

View file

@ -45,9 +45,12 @@ export default {
<IntlProvider locale="en">
<KibanaContextProvider
services={{
application: { getUrlForApp: () => '' },
data: { autocomplete: { hasQuerySuggestions: () => false }, query: {} },
chrome: { docTitle: { change: () => {} } },
docLinks: { links: { query: {} } },
storage: { get: () => {} },
timelines: { getTGrid: () => <></> },
uiSettings: {
get: (setting: string) => {
if (setting === 'dateFormat') {

View file

@ -5,7 +5,13 @@
* 2.0.
*/
import { EuiPageTemplate } from '@elastic/eui';
import React, { ComponentType } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { CoreStart } from '../../../../../../src/core/public';
import { createKibanaReactContext } from '../../../../../../src/plugins/kibana_react/public';
import { casesFeatureId } from '../../../common';
import { PluginContext, PluginContextValue } from '../../context/plugin_context';
import { AllCasesPage } from './all_cases';
export default {
@ -13,7 +19,33 @@ export default {
component: AllCasesPage,
decorators: [
(Story: ComponentType) => {
return <Story />;
const KibanaReactContext = createKibanaReactContext(({
application: {
capabilities: { [casesFeatureId]: { read_cases: true } },
getUrlForApp: () => '',
},
cases: { getAllCases: () => <></> },
chrome: { docTitle: { change: () => {} }, setBadge: () => {} },
docLinks: {
DOC_LINK_VERSION: '0',
ELASTIC_WEBSITE_URL: 'https://www.elastic.co/',
},
uiSettings: { get: () => true },
} as unknown) as Partial<CoreStart>);
const pluginContextValue = ({
ObservabilityPageTemplate: EuiPageTemplate,
} as unknown) as PluginContextValue;
return (
<MemoryRouter>
<KibanaReactContext.Provider>
<PluginContext.Provider value={pluginContextValue}>
<Story />
</PluginContext.Provider>
</KibanaReactContext.Provider>
</MemoryRouter>
);
},
],
};

View file

@ -5,7 +5,11 @@
* 2.0.
*/
import { EuiPageTemplate } from '@elastic/eui';
import React, { ComponentType } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { CoreStart } from '../../../../../../src/core/public';
import { createKibanaReactContext } from '../../../../../../src/plugins/kibana_react/public';
import { PluginContext, PluginContextValue } from '../../context/plugin_context';
import { LandingPage } from './';
@ -14,6 +18,13 @@ export default {
component: LandingPage,
decorators: [
(Story: ComponentType) => {
const KibanaReactContext = createKibanaReactContext(({
application: { getUrlForApp: () => '', navigateToUrl: () => {} },
chrome: { docTitle: { change: () => {} }, setBreadcrumbs: () => {} },
uiSettings: { get: () => true },
observability: { ObservabilityPageTemplate: EuiPageTemplate },
} as unknown) as Partial<CoreStart>);
const pluginContextValue = ({
appMountParameters: { setHeaderActionMenu: () => {} },
core: {
@ -23,11 +34,17 @@ export default {
},
},
},
ObservabilityPageTemplate: EuiPageTemplate,
} as unknown) as PluginContextValue;
return (
<PluginContext.Provider value={pluginContextValue}>
<Story />
</PluginContext.Provider>
<MemoryRouter>
<KibanaReactContext.Provider>
<PluginContext.Provider value={pluginContextValue}>
<Story />
</PluginContext.Provider>
</KibanaReactContext.Provider>
</MemoryRouter>
);
},
],

View file

@ -23,7 +23,10 @@ import { emptyResponse as emptyMetricsResponse, fetchMetricsData } from './mock/
import { newsFeedFetchData } from './mock/news_feed.mock';
import { emptyResponse as emptyUptimeResponse, fetchUptimeData } from './mock/uptime.mock';
import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock';
import { KibanaPageTemplate } from '../../../../../../src/plugins/kibana_react/public';
import {
createKibanaReactContext,
KibanaPageTemplate,
} from '../../../../../../src/plugins/kibana_react/public';
import { ApmIndicesConfig } from '../../../common/typings';
function unregisterAll() {
@ -44,28 +47,39 @@ const withCore = makeDecorator({
wrapper: (storyFn, context, { options }) => {
unregisterAll();
const KibanaReactContext = createKibanaReactContext(({
application: { getUrlForApp: () => '' },
chrome: { docTitle: { change: () => {} } },
uiSettings: { get: () => [] },
usageCollection: { reportUiCounter: () => {} },
} as unknown) as Partial<CoreStart>);
return (
<MemoryRouter>
<PluginContext.Provider
value={{
appMountParameters: ({
setHeaderActionMenu: () => {},
} as unknown) as AppMountParameters,
config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
core: options as CoreStart,
plugins: ({
data: {
query: {
timefilter: { timefilter: { setTime: () => {}, getTime: () => ({}) } },
},
<KibanaReactContext.Provider>
<PluginContext.Provider
value={{
appMountParameters: ({
setHeaderActionMenu: () => {},
} as unknown) as AppMountParameters,
config: {
unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } },
},
} as unknown) as ObservabilityPublicPluginsStart,
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
ObservabilityPageTemplate: KibanaPageTemplate,
}}
>
<HasDataContextProvider>{storyFn(context)}</HasDataContextProvider>
</PluginContext.Provider>
core: options as CoreStart,
plugins: ({
data: {
query: {
timefilter: { timefilter: { setTime: () => {}, getTime: () => ({}) } },
},
},
} as unknown) as ObservabilityPublicPluginsStart,
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
ObservabilityPageTemplate: KibanaPageTemplate,
}}
>
<HasDataContextProvider>{storyFn(context)}</HasDataContextProvider>
</PluginContext.Provider>
</KibanaReactContext.Provider>
</MemoryRouter>
);
},