Jest and Storybook fixes (#104991)

This commit is contained in:
Nathan L Smith 2021-07-20 16:07:50 -05:00 committed by GitHub
parent 5bd4762561
commit 88ac1f9761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 149 additions and 139 deletions

View file

@ -5,6 +5,7 @@
* 2.0. * 2.0.
*/ */
import { Story } from '@storybook/react';
import { cloneDeep, merge } from 'lodash'; import { cloneDeep, merge } from 'lodash';
import React, { ComponentType } from 'react'; import React, { ComponentType } from 'react';
import { MemoryRouter, Route } from 'react-router-dom'; import { MemoryRouter, Route } from 'react-router-dom';
@ -14,13 +15,14 @@ import {
mockApmPluginContextValue, mockApmPluginContextValue,
MockApmPluginContextWrapper, MockApmPluginContextWrapper,
} from '../../../context/apm_plugin/mock_apm_plugin_context'; } from '../../../context/apm_plugin/mock_apm_plugin_context';
import { ApmServiceContextProvider } from '../../../context/apm_service/apm_service_context';
import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider'; import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider';
export default { export default {
title: 'alerting/TransactionDurationAlertTrigger', title: 'alerting/TransactionDurationAlertTrigger',
component: TransactionDurationAlertTrigger, component: TransactionDurationAlertTrigger,
decorators: [ decorators: [
(Story: ComponentType) => { (StoryComponent: ComponentType) => {
const contextMock = (merge(cloneDeep(mockApmPluginContextValue), { const contextMock = (merge(cloneDeep(mockApmPluginContextValue), {
core: { core: {
http: { http: {
@ -39,11 +41,13 @@ export default {
return ( return (
<div style={{ width: 400 }}> <div style={{ width: 400 }}>
<MemoryRouter initialEntries={['/transactions/test-service-name']}> <MemoryRouter initialEntries={['/services/test-service-name']}>
<Route path="/transactions/:serviceName"> <Route path="/services/:serviceName">
<MockApmPluginContextWrapper value={contextMock}> <MockApmPluginContextWrapper value={contextMock}>
<MockUrlParamsContextProvider> <MockUrlParamsContextProvider>
<Story /> <ApmServiceContextProvider>
<StoryComponent />
</ApmServiceContextProvider>
</MockUrlParamsContextProvider> </MockUrlParamsContextProvider>
</MockApmPluginContextWrapper> </MockApmPluginContextWrapper>
</Route> </Route>
@ -54,7 +58,7 @@ export default {
], ],
}; };
export function Example() { export const Example: Story = () => {
const params = { const params = {
threshold: 1500, threshold: 1500,
aggregationType: 'avg' as const, aggregationType: 'avg' as const,
@ -67,4 +71,4 @@ export function Example() {
setAlertProperty={() => undefined} setAlertProperty={() => undefined}
/> />
); );
} };

View file

@ -49,7 +49,7 @@ export function CustomLinkTable({ items = [], onCustomLinkSelected }: Props) {
truncateText: true, truncateText: true,
}, },
{ {
width: 160, width: '160px',
align: 'right', align: 'right',
field: '@timestamp', field: '@timestamp',
name: i18n.translate( name: i18n.translate(

View file

@ -12,6 +12,7 @@ import { CoreStart } from '../../../../../../../../src/core/public';
import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context'; import { MockApmPluginContextWrapper } from '../../../../context/apm_plugin/mock_apm_plugin_context';
import { createCallApmApi } from '../../../../services/rest/createCallApmApi'; import { createCallApmApi } from '../../../../services/rest/createCallApmApi';
import { Schema } from './'; import { Schema } from './';
import { ConfirmSwitchModal } from './confirm_switch_modal';
interface Args { interface Args {
hasCloudAgentPolicy: boolean; hasCloudAgentPolicy: boolean;
@ -107,3 +108,18 @@ export default {
export const Example: Story = () => { export const Example: Story = () => {
return <Schema />; return <Schema />;
}; };
interface ModalArgs {
unsupportedConfigs: Array<{ key: string; value: string }>;
}
export const Modal: Story<ModalArgs> = ({ unsupportedConfigs }) => {
return (
<ConfirmSwitchModal
onCancel={() => {}}
onConfirm={() => {}}
unsupportedConfigs={unsupportedConfigs}
/>
);
};
Modal.args = { unsupportedConfigs: [{ key: 'test', value: '123' }] };

View file

@ -79,7 +79,7 @@ function ErrorGroupList({ items, serviceName }: Props) {
), ),
field: 'groupId', field: 'groupId',
sortable: false, sortable: false,
width: unit * 6, width: `${unit * 6}px`,
render: (groupId: string) => { render: (groupId: string) => {
return ( return (
<GroupIdLink serviceName={serviceName} errorGroupId={groupId}> <GroupIdLink serviceName={serviceName} errorGroupId={groupId}>

View file

@ -84,7 +84,7 @@ export function getServiceColumns({
name: i18n.translate('xpack.apm.servicesTable.healthColumnLabel', { name: i18n.translate('xpack.apm.servicesTable.healthColumnLabel', {
defaultMessage: 'Health', defaultMessage: 'Health',
}), }),
width: unit * 6, width: `${unit * 6}px`,
sortable: true, sortable: true,
render: (_, { healthStatus }) => { render: (_, { healthStatus }) => {
return ( return (
@ -135,7 +135,7 @@ export function getServiceColumns({
name: i18n.translate('xpack.apm.servicesTable.environmentColumnLabel', { name: i18n.translate('xpack.apm.servicesTable.environmentColumnLabel', {
defaultMessage: 'Environment', defaultMessage: 'Environment',
}), }),
width: unit * 10, width: `${unit * 10}px`,
sortable: true, sortable: true,
render: (_, { environments }) => ( render: (_, { environments }) => (
<EnvironmentBadge environments={environments ?? []} /> <EnvironmentBadge environments={environments ?? []} />
@ -149,7 +149,7 @@ export function getServiceColumns({
'xpack.apm.servicesTable.transactionColumnLabel', 'xpack.apm.servicesTable.transactionColumnLabel',
{ defaultMessage: 'Transaction type' } { defaultMessage: 'Transaction type' }
), ),
width: unit * 10, width: `${unit * 10}px`,
sortable: true, sortable: true,
}, },
] ]
@ -169,7 +169,7 @@ export function getServiceColumns({
/> />
), ),
align: 'left', align: 'left',
width: unit * 10, width: `${unit * 10}px`,
}, },
{ {
field: 'transactionsPerMinute', field: 'transactionsPerMinute',
@ -186,7 +186,7 @@ export function getServiceColumns({
/> />
), ),
align: 'left', align: 'left',
width: unit * 10, width: `${unit * 10}px`,
}, },
{ {
field: 'transactionErrorRate', field: 'transactionErrorRate',
@ -209,7 +209,7 @@ export function getServiceColumns({
); );
}, },
align: 'left', align: 'left',
width: unit * 10, width: `${unit * 10}px`,
}, },
]; ];
} }

View file

@ -32,9 +32,10 @@ import { fromQuery } from '../../shared/Links/url_helpers';
import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider'; import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider';
import { uiSettingsServiceMock } from '../../../../../../../src/core/public/mocks'; import { uiSettingsServiceMock } from '../../../../../../../src/core/public/mocks';
const KibanaReactContext = createKibanaReactContext({ const KibanaReactContext = createKibanaReactContext(({
uiSettings: { get: () => true },
usageCollection: { reportUiCounter: () => {} }, usageCollection: { reportUiCounter: () => {} },
} as Partial<CoreStart>); } as unknown) as Partial<CoreStart>);
const mockParams = { const mockParams = {
rangeFrom: 'now-15m', rangeFrom: 'now-15m',

View file

@ -24,9 +24,10 @@ import {
import { fromQuery } from '../../shared/Links/url_helpers'; import { fromQuery } from '../../shared/Links/url_helpers';
import { TransactionOverview } from './'; import { TransactionOverview } from './';
const KibanaReactContext = createKibanaReactContext({ const KibanaReactContext = createKibanaReactContext(({
uiSettings: { get: () => true },
usageCollection: { reportUiCounter: () => {} }, usageCollection: { reportUiCounter: () => {} },
} as Partial<CoreStart>); } as unknown) as Partial<CoreStart>);
const history = createMemoryHistory(); const history = createMemoryHistory();
jest.spyOn(history, 'push'); jest.spyOn(history, 'push');

View file

@ -7,73 +7,63 @@
import { import {
EuiCard, EuiCard,
EuiCodeBlock,
EuiFlexGroup, EuiFlexGroup,
EuiFlexItem, EuiFlexItem,
EuiImage, EuiImage,
EuiSpacer,
EuiToolTip, EuiToolTip,
} from '@elastic/eui'; } from '@elastic/eui';
import type { Story } from '@storybook/react';
import React from 'react'; import React from 'react';
import { AGENT_NAMES } from '../../../../common/agent_name'; import { AGENT_NAMES } from '../../../../common/agent_name';
import { useTheme } from '../../../hooks/use_theme';
import { getAgentIcon } from './get_agent_icon'; import { getAgentIcon } from './get_agent_icon';
import { AgentIcon } from './index'; import { AgentIcon } from './index';
export default { export default {
title: 'shared/icons', title: 'shared/AgentIcon',
component: AgentIcon, component: AgentIcon,
}; };
export function AgentIcons() { export const List: Story = (_args, { globals }) => {
const theme = useTheme(); const darkMode = globals.euiTheme.includes('dark');
return ( return (
<> <EuiFlexGroup gutterSize="l" wrap={true}>
<EuiCodeBlock language="html" isCopyable paddingSize="m"> {AGENT_NAMES.map((agentName) => {
{'<AgentIcon agentName="dotnet" />'} return (
</EuiCodeBlock> <EuiFlexItem key={agentName} grow={false}>
<EuiCard
<EuiSpacer /> icon={
<>
<EuiFlexGroup gutterSize="l" wrap={true}> <p>
{AGENT_NAMES.map((agentName) => {
return (
<EuiFlexItem key={agentName} grow={false}>
<EuiCard
icon={
<>
<p>
<EuiToolTip
position="top"
content="Icon rendered with `EuiImage`"
>
<EuiImage
size="s"
hasShadow
alt={agentName}
src={getAgentIcon(agentName, theme.darkMode)}
/>
</EuiToolTip>
</p>
</>
}
title={agentName}
description={
<div>
<EuiToolTip <EuiToolTip
position="bottom" position="top"
content="Icon rendered with `AgentIcon`" content="Icon rendered with `EuiImage`"
> >
<AgentIcon agentName={agentName} /> <EuiImage
size="s"
hasShadow
alt={agentName}
src={getAgentIcon(agentName, darkMode)}
/>
</EuiToolTip> </EuiToolTip>
</div> </p>
} </>
/> }
</EuiFlexItem> title={agentName}
); description={
})} <div>
</EuiFlexGroup> <EuiToolTip
</> position="bottom"
content="Icon rendered with `AgentIcon`"
>
<AgentIcon agentName={agentName} />
</EuiToolTip>
</div>
}
/>
</EuiFlexItem>
);
})}
</EuiFlexGroup>
); );
} };

View file

@ -14,7 +14,7 @@ import {
ApmPluginContext, ApmPluginContext,
ApmPluginContextValue, ApmPluginContextValue,
} from '../../../../context/apm_plugin/apm_plugin_context'; } from '../../../../context/apm_plugin/apm_plugin_context';
import { ApmServiceContextProvider } from '../../../../context/apm_service/apm_service_context'; import { APMServiceContext } from '../../../../context/apm_service/apm_service_context';
import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context'; import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context';
import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider'; import { MockUrlParamsContextProvider } from '../../../../context/url_params_context/mock_url_params_context_provider';
import { import {
@ -41,6 +41,7 @@ export default {
decorators: [ decorators: [
(Story: ComponentType, { args }: StoryContext) => { (Story: ComponentType, { args }: StoryContext) => {
const { alertsResponse, latencyChartResponse } = args as Args; const { alertsResponse, latencyChartResponse } = args as Args;
const serviceName = 'testService';
const apmPluginContextMock = ({ const apmPluginContextMock = ({
core: { core: {
@ -51,10 +52,8 @@ export default {
basePath: { prepend: () => {} }, basePath: { prepend: () => {} },
get: (endpoint: string) => { get: (endpoint: string) => {
switch (endpoint) { switch (endpoint) {
case '/api/apm/services/test-service/transactions/charts/latency': case `/api/apm/services/${serviceName}/transactions/charts/latency`:
return latencyChartResponse; return latencyChartResponse;
case '/api/apm/services/test-service/alerts':
return alertsResponse;
default: default:
return {}; return {};
} }
@ -68,24 +67,32 @@ export default {
createCallApmApi(apmPluginContextMock.core); createCallApmApi(apmPluginContextMock.core);
const transactionType = `${Math.random()}`; // So we don't memoize
return ( return (
<ApmPluginContext.Provider value={apmPluginContextMock}> <ApmPluginContext.Provider value={apmPluginContextMock}>
<MemoryRouter initialEntries={[`/app/apm/services/test-service`]}> <MemoryRouter initialEntries={[`/services/${serviceName}`]}>
<Route path="/app/apm/services/:serviceName"> <Route path="/services/:serviceName">
<KibanaContextProvider <KibanaContextProvider
services={{ ...apmPluginContextMock.core }} services={{ ...apmPluginContextMock.core }}
> >
<MockUrlParamsContextProvider <MockUrlParamsContextProvider
params={{ params={{
latencyAggregationType: LatencyAggregationType.avg, latencyAggregationType: LatencyAggregationType.avg,
transactionType: `${Math.random()}`, // So we don't memoize
}} }}
> >
<ApmServiceContextProvider> <APMServiceContext.Provider
value={{
alerts: alertsResponse.alerts,
serviceName,
transactionType,
transactionTypes: [],
}}
>
<ChartPointerEventContextProvider> <ChartPointerEventContextProvider>
<Story /> <Story />
</ChartPointerEventContextProvider> </ChartPointerEventContextProvider>
</ApmServiceContextProvider> </APMServiceContext.Provider>
</MockUrlParamsContextProvider> </MockUrlParamsContextProvider>
</KibanaContextProvider> </KibanaContextProvider>
</Route> </Route>

View file

@ -19,7 +19,7 @@ export interface ITableColumn<T> {
field?: string; field?: string;
dataType?: string; dataType?: string;
align?: string; align?: string;
width?: string | number; width?: string;
sortable?: boolean; sortable?: boolean;
render?: (value: any, item: T) => unknown; render?: (value: any, item: T) => unknown;
} }

View file

@ -7,13 +7,12 @@
import { import {
EuiCard, EuiCard,
EuiCodeBlock,
EuiFlexGroup, EuiFlexGroup,
EuiFlexItem, EuiFlexItem,
EuiImage, EuiImage,
EuiSpacer,
EuiToolTip, EuiToolTip,
} from '@elastic/eui'; } from '@elastic/eui';
import type { Story } from '@storybook/react';
import React from 'react'; import React from 'react';
import { getSpanIcon, spanTypeIcons } from './get_span_icon'; import { getSpanIcon, spanTypeIcons } from './get_span_icon';
import { SpanIcon } from './index'; import { SpanIcon } from './index';
@ -21,72 +20,64 @@ import { SpanIcon } from './index';
const spanTypes = Object.keys(spanTypeIcons); const spanTypes = Object.keys(spanTypeIcons);
export default { export default {
title: 'shared/icons', title: 'shared/SpanIcon',
component: SpanIcon, component: SpanIcon,
}; };
export function SpanIcons() { export const List: Story = () => {
return ( return (
<> <EuiFlexGroup gutterSize="l" wrap={true}>
<EuiCodeBlock language="html" isCopyable paddingSize="m"> {spanTypes.map((type) => {
{'<SpanIcon type="db" subtype="cassandra" />'} const subTypes = Object.keys(spanTypeIcons[type]);
</EuiCodeBlock> return subTypes.map((subType) => {
const id = `${type}.${subType}`;
<EuiSpacer /> return (
<EuiFlexItem key={id}>
<EuiFlexGroup gutterSize="l" wrap={true}> <EuiCard
{spanTypes.map((type) => { icon={
const subTypes = Object.keys(spanTypeIcons[type]); <p>
return subTypes.map((subType) => { <EuiToolTip
const id = `${type}.${subType}`; position="top"
content="Icon rendered with `EuiImage`"
return ( >
<EuiFlexItem key={id}> <EuiImage
<EuiCard size="s"
icon={ hasShadow
<p> alt={id}
src={getSpanIcon(type, subType)}
/>
</EuiToolTip>
</p>
}
title={id}
description={
<>
<div>
<EuiToolTip <EuiToolTip
position="top" position="bottom"
content="Icon rendered with `EuiImage`" content="Icon rendered with `SpanIcon`"
> >
<EuiImage <SpanIcon type={type} subType={subType} />
size="s"
hasShadow
alt={id}
src={getSpanIcon(type, subType)}
/>
</EuiToolTip> </EuiToolTip>
</p> </div>
}
title={id}
description={
<>
<div>
<EuiToolTip
position="bottom"
content="Icon rendered with `SpanIcon`"
>
<SpanIcon type={type} subType={subType} />
</EuiToolTip>
</div>
<code <code
style={{ style={{
textAlign: 'left', textAlign: 'left',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
}} }}
> >
<div>span.type: {type}</div> <div>span.type: {type}</div>
<div>span.subtype: {subType}</div> <div>span.subtype: {subType}</div>
</code> </code>
</> </>
} }
/> />
</EuiFlexItem> </EuiFlexItem>
); );
}); });
})} })}
</EuiFlexGroup> </EuiFlexGroup>
</>
); );
} };