[Uptime] [Overview Page] Only render up/down drawer badges when items > 1 (#88524)
* Only render location status badge when there are actually locations to display. * Add aria-label to describe location section. * Update test data to reflect real-world data better. Refactor enzyme tests. * Refactor component test. * Fix test names. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
5f53b649c6
commit
4af5c117fa
|
@ -1,97 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`MonitorStatusList component renders checks 1`] = `
|
||||
<Fragment>
|
||||
<EuiFlexGroup
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": 1000,
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow
|
||||
locationNames={
|
||||
Set {
|
||||
"Unnamed-location",
|
||||
}
|
||||
}
|
||||
status="down"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow
|
||||
locationNames={Set {}}
|
||||
status="up"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Some heartbeat instances do not have a location defined. {link} to your heartbeat configuration."
|
||||
id="xpack.uptime.monitorList.drawer.missingLocation"
|
||||
values={
|
||||
Object {
|
||||
"link": <LocationLink />,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`MonitorStatusList component renders null in place of child status with missing ip 1`] = `
|
||||
<Fragment>
|
||||
<EuiFlexGroup
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": 1000,
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow
|
||||
locationNames={
|
||||
Set {
|
||||
"Unnamed-location",
|
||||
}
|
||||
}
|
||||
status="down"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow
|
||||
locationNames={Set {}}
|
||||
status="up"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Some heartbeat instances do not have a location defined. {link} to your heartbeat configuration."
|
||||
id="xpack.uptime.monitorList.drawer.missingLocation"
|
||||
values={
|
||||
Object {
|
||||
"link": <LocationLink />,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
|
@ -1,31 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`MonitorStatusRow component renders status row when status is down 1`] = `
|
||||
<span>
|
||||
<EuiBadge
|
||||
color="danger"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
Berlin, Islamabad, London
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`MonitorStatusRow component renders status row when status is up 1`] = `
|
||||
<span>
|
||||
<EuiBadge
|
||||
color="danger"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
Berlin, Islamabad, London
|
||||
<EuiSpacer
|
||||
size="xs"
|
||||
/>
|
||||
</span>
|
||||
`;
|
|
@ -4,11 +4,11 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallowWithIntl } from '@kbn/test/jest';
|
||||
import React from 'react';
|
||||
import { MonitorStatusList } from './monitor_status_list';
|
||||
import { Ping } from '../../../../../common/runtime_types';
|
||||
import { mockMoment } from '../../../../lib/helper/test_helpers';
|
||||
import { render } from '../../../../lib/helper/rtl_helpers';
|
||||
|
||||
describe('MonitorStatusList component', () => {
|
||||
let pings: Ping[];
|
||||
|
@ -34,51 +34,6 @@ describe('MonitorStatusList component', () => {
|
|||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '2',
|
||||
monitor: {
|
||||
ip: '151.101.194.217',
|
||||
name: 'elastic',
|
||||
status: 'up',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '3',
|
||||
monitor: {
|
||||
ip: '151.101.2.217',
|
||||
name: 'elastic',
|
||||
status: 'up',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '4',
|
||||
monitor: {
|
||||
ip: '151.101.66.217',
|
||||
name: 'elastic',
|
||||
status: 'up',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '4',
|
||||
monitor: {
|
||||
|
@ -95,60 +50,168 @@ describe('MonitorStatusList component', () => {
|
|||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '5',
|
||||
docId: '8',
|
||||
monitor: {
|
||||
ip: '2a04:4e42:400::729',
|
||||
name: 'elastic',
|
||||
status: 'down',
|
||||
id: 'myMonitor',
|
||||
ip: '8c94:2b92::132',
|
||||
name: 'upMonitor',
|
||||
status: 'up',
|
||||
id: 'myUpMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
duration: { us: 234 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
geo: {
|
||||
name: 'fairbanks',
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '6',
|
||||
monitor: {
|
||||
ip: '2a04:4e42:600::729',
|
||||
name: 'elastic',
|
||||
status: 'down',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
},
|
||||
{
|
||||
docId: '5',
|
||||
monitor: {
|
||||
ip: '2a04:4e42::729',
|
||||
name: 'elastic',
|
||||
status: 'down',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 123 },
|
||||
},
|
||||
observer: {
|
||||
geo: {},
|
||||
},
|
||||
timestamp: '1570538236414',
|
||||
timestamp: '1570538235890',
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
it('renders checks', () => {
|
||||
const component = shallowWithIntl(<MonitorStatusList summaryPings={pings} />);
|
||||
expect(component).toMatchSnapshot();
|
||||
it.each(['up', 'down'])(
|
||||
'renders call out for monitor location if monitors have no location',
|
||||
(status) => {
|
||||
const { getByRole, getByText } = render(
|
||||
<MonitorStatusList
|
||||
summaryPings={pings.map((ping) => {
|
||||
// test only up, only down
|
||||
ping.monitor.status = status;
|
||||
return ping;
|
||||
})}
|
||||
/>
|
||||
);
|
||||
|
||||
getByText('Some heartbeat instances do not have a location defined.', {
|
||||
// contains other elements/text
|
||||
exact: false,
|
||||
});
|
||||
const docsLink = getByRole('link');
|
||||
expect(docsLink.getAttribute('href')).toContain('https://www.elastic.co');
|
||||
}
|
||||
);
|
||||
|
||||
it('does not render call out for monitor location if all monitors have location', () => {
|
||||
const { queryByRole, queryByText } = render(
|
||||
<MonitorStatusList
|
||||
summaryPings={pings.map((ping) => ({
|
||||
...ping,
|
||||
...{ observer: { geo: { name: 'test-name' } } },
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
queryByText('Some heartbeat instances do not have a location defined.', { exact: false })
|
||||
).toBeNull();
|
||||
expect(queryByRole('link')).toBeNull();
|
||||
});
|
||||
|
||||
it('renders null in place of child status with missing ip', () => {
|
||||
const component = shallowWithIntl(<MonitorStatusList summaryPings={pings} />);
|
||||
expect(component).toMatchSnapshot();
|
||||
it.each([
|
||||
[
|
||||
'up',
|
||||
'Up',
|
||||
'A list of locations with "up" status when last checked.',
|
||||
'Down',
|
||||
'A list of locations with "down" status when last checked.',
|
||||
],
|
||||
[
|
||||
'down',
|
||||
'Down',
|
||||
'A list of locations with "down" status when last checked.',
|
||||
'Up',
|
||||
'A list of locations with "up" status when last checked.',
|
||||
],
|
||||
])(
|
||||
'renders only up badge when there are no down checks',
|
||||
(
|
||||
statusToFilter,
|
||||
statusText,
|
||||
expectedLabel,
|
||||
expectedMissingStatusText,
|
||||
expectedMissingLabel
|
||||
) => {
|
||||
const { getByText, getByLabelText, queryByText, queryByLabelText } = render(
|
||||
<MonitorStatusList
|
||||
summaryPings={pings.filter(({ monitor: { status } }) => status === statusToFilter)}
|
||||
/>
|
||||
);
|
||||
expect(getByText(statusText));
|
||||
expect(getByLabelText(expectedLabel));
|
||||
expect(queryByText(expectedMissingStatusText)).toBeNull();
|
||||
expect(queryByLabelText(expectedMissingLabel)).toBeNull();
|
||||
}
|
||||
);
|
||||
|
||||
it('displays badges for up and down locations when the results are mixed', () => {
|
||||
const { getByText, getByLabelText } = render(<MonitorStatusList summaryPings={pings} />);
|
||||
expect(getByText('Up'));
|
||||
expect(getByLabelText('A list of locations with "up" status when last checked.'));
|
||||
expect(getByText('fairbanks'));
|
||||
expect(getByText('Down'));
|
||||
expect(getByLabelText('A list of locations with "down" status when last checked.'));
|
||||
expect(getByText('Unnamed-location'));
|
||||
});
|
||||
|
||||
it('displays a location as "down" if any summary checks are down', () => {
|
||||
const newlyUpPings = [
|
||||
{
|
||||
docId: '100',
|
||||
monitor: {
|
||||
ip: '8c94:2b92::132',
|
||||
name: 'monitor',
|
||||
status: 'down',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 234 },
|
||||
},
|
||||
observer: {
|
||||
geo: {
|
||||
name: 'fairbanks',
|
||||
},
|
||||
},
|
||||
timestamp: '1570538235890',
|
||||
},
|
||||
{
|
||||
docId: '101',
|
||||
monitor: {
|
||||
ip: '8c94:2b92::132',
|
||||
name: 'monitor',
|
||||
status: 'down',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 234 },
|
||||
},
|
||||
observer: {
|
||||
geo: {
|
||||
name: 'fairbanks',
|
||||
},
|
||||
},
|
||||
timestamp: '1570538236890',
|
||||
},
|
||||
{
|
||||
docId: '101',
|
||||
monitor: {
|
||||
ip: '8c94:2b92::132',
|
||||
name: 'monitor',
|
||||
status: 'up',
|
||||
id: 'myMonitor',
|
||||
type: 'icmp',
|
||||
duration: { us: 234 },
|
||||
},
|
||||
observer: {
|
||||
geo: {
|
||||
name: 'fairbanks',
|
||||
},
|
||||
},
|
||||
timestamp: '1570538237890',
|
||||
},
|
||||
];
|
||||
const { getByText, getByLabelText } = render(<MonitorStatusList summaryPings={newlyUpPings} />);
|
||||
expect(getByText('Down'));
|
||||
const locationContainer = getByLabelText(
|
||||
'A list of locations with "down" status when last checked.'
|
||||
);
|
||||
expect(locationContainer.innerHTML).toBe('fairbanks');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,12 +40,16 @@ export const MonitorStatusList = ({ summaryPings }: MonitorStatusListProps) => {
|
|||
return (
|
||||
<>
|
||||
<EuiFlexGroup style={{ maxWidth: 1000 }}>
|
||||
{downChecks.size > 0 && (
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow locationNames={downChecks} status={STATUS.DOWN} />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{absUpChecks.size > 0 && (
|
||||
<EuiFlexItem>
|
||||
<MonitorStatusRow locationNames={absUpChecks} status={STATUS.UP} />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
{(downChecks.has(UNNAMED_LOCATION) || upChecks.has(UNNAMED_LOCATION)) && (
|
||||
<>
|
||||
|
|
|
@ -4,28 +4,27 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallowWithIntl } from '@kbn/test/jest';
|
||||
import React from 'react';
|
||||
import { render } from '../../../../lib/helper/rtl_helpers';
|
||||
import { MonitorStatusRow } from './monitor_status_row';
|
||||
|
||||
describe('MonitorStatusRow component', () => {
|
||||
let locationNames: Set<string>;
|
||||
it.each(['Up'])('renders status row when status is up', (expectedStatus) => {
|
||||
const locationNames = new Set(['Berlin', 'Islamabad', 'London']);
|
||||
const { getByLabelText } = render(
|
||||
<MonitorStatusRow locationNames={locationNames} status={expectedStatus} />
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
locationNames = new Set(['Berlin', 'Islamabad', 'London']);
|
||||
const locationElement = getByLabelText(
|
||||
`A list of locations with "${expectedStatus}" status when last checked.`
|
||||
);
|
||||
|
||||
expect(locationElement.innerHTML).toBe('Berlin, Islamabad, London');
|
||||
});
|
||||
|
||||
it('renders status row when status is up', () => {
|
||||
const component = shallowWithIntl(
|
||||
<MonitorStatusRow locationNames={locationNames} status={'Up'} />
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
it('renders an empty set string', () => {
|
||||
const { getByText } = render(<MonitorStatusRow locationNames={new Set()} status="Down" />);
|
||||
|
||||
it('renders status row when status is down', () => {
|
||||
const component = shallowWithIntl(
|
||||
<MonitorStatusRow locationNames={locationNames} status={'Down'} />
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
expect(getByText('--'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiBadge, EuiSpacer } from '@elastic/eui';
|
||||
import { UNNAMED_LOCATION, STATUS } from '../../../../../common/constants';
|
||||
import { getHealthMessage } from '../columns/monitor_status_column';
|
||||
|
@ -35,7 +36,14 @@ export const MonitorStatusRow = ({ locationNames, status }: MonitorStatusRowProp
|
|||
<span>
|
||||
<EuiBadge color={color}>{getHealthMessage(status)}</EuiBadge>
|
||||
<EuiSpacer size="xs" />
|
||||
<span
|
||||
aria-label={i18n.translate('xpack.uptime.monitorList.drawer.statusRowLocationList', {
|
||||
defaultMessage: 'A list of locations with "{status}" status when last checked.',
|
||||
values: { status },
|
||||
})}
|
||||
>
|
||||
{locations || '--'}
|
||||
</span>
|
||||
<EuiSpacer size="xs" />
|
||||
</span>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue