Skip to content

Commit

Permalink
[Metrics UI] Fix fatal error when no data is available for Metric Thr…
Browse files Browse the repository at this point in the history
…eshold Alerts (#68678) (#68758)

* [Metrics UI] Fix fatal error when no data is available for Metric
Threshold Alerts

* Adding i18n support for error message

* Adding test
  • Loading branch information
simianhacker committed Jun 10, 2020
1 parent 36379ed commit 8e3b5d9
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* 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 { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers';
import { actionTypeRegistryMock } from '../../../../../triggers_actions_ui/public/application/action_type_registry.mock';
import { alertTypeRegistryMock } from '../../../../../triggers_actions_ui/public/application/alert_type_registry.mock';
import { coreMock } from '../../../../../../../src/core/public/mocks';
import { AlertsContextValue } from '../../../../../triggers_actions_ui/public/application/context/alerts_context';
import { AlertContextMeta, MetricExpression } from '../types';
import { IIndexPattern } from 'src/plugins/data/public';
import { InfraSource } from '../../../../common/http_api/source_api';
import React from 'react';
import { ExpressionChart } from './expression_chart';
import { act } from 'react-dom/test-utils';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { Aggregators, Comparator } from '../../../../server/lib/alerting/metric_threshold/types';
import { MetricsExplorerResponse } from '../../../../common/http_api';

describe('ExpressionChart', () => {
async function setup(
expression: MetricExpression,
response: MetricsExplorerResponse | null,
filterQuery?: string,
groupBy?: string
) {
const mocks = coreMock.createSetup();
const [
{
application: { capabilities },
},
] = await mocks.getStartServices();

const context: AlertsContextValue<AlertContextMeta> = {
http: mocks.http,
toastNotifications: mocks.notifications.toasts,
actionTypeRegistry: actionTypeRegistryMock.create() as any,
alertTypeRegistry: alertTypeRegistryMock.create() as any,
docLinks: mocks.docLinks,
capabilities: {
...capabilities,
actions: {
delete: true,
save: true,
show: true,
},
},
};
const derivedIndexPattern: IIndexPattern = {
title: 'metricbeat-*',
fields: [],
};

const source: InfraSource = {
id: 'default',
origin: 'fallback',
configuration: {
name: 'default',
description: 'The default configuration',
logColumns: [],
metricAlias: 'metricbeat-*',
logAlias: 'filebeat-*',
fields: {
timestamp: '@timestamp',
message: ['message'],
container: 'container.id',
host: 'host.name',
pod: 'kubernetes.pod.uid',
tiebreaker: '_doc',
},
},
};

mocks.http.fetch.mockImplementation(() => Promise.resolve(response));

const wrapper = mountWithIntl(
<ExpressionChart
context={context}
expression={expression}
derivedIndexPattern={derivedIndexPattern}
source={source}
filterQuery={filterQuery}
groupBy={groupBy}
/>
);

const update = async () =>
await act(async () => {
await nextTick();
wrapper.update();
});

await update();

return { wrapper, update, fetchMock: mocks.http.fetch };
}

it('should display no data message', async () => {
const expression: MetricExpression = {
aggType: Aggregators.AVERAGE,
timeSize: 1,
timeUnit: 'm',
sourceId: 'default',
threshold: [1],
comparator: Comparator.GT_OR_EQ,
};
const response = {
pageInfo: {
afterKey: null,
total: 0,
},
series: [{ id: 'Everything', rows: [], columns: [] }],
};
const { wrapper } = await setup(expression, response);
expect(wrapper.find('[data-test-subj~="noChartData"]').exists()).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,15 @@ export const ExpressionChart: React.FC<Props> = ({
// Creating a custom series where the ID is changed to 0
// so that we can get a proper domian
const firstSeries = first(data.series);
if (!firstSeries) {
if (!firstSeries || !firstSeries.rows || firstSeries.rows.length === 0) {
return (
<EmptyContainer>
<EuiText color="subdued">Oops, no chart data available</EuiText>
<EuiText color="subdued" data-test-subj="noChartData">
<FormattedMessage
id="xpack.infra.metrics.alerts.noDataMessage"
defaultMessage="Oops, no chart data available"
/>
</EuiText>
</EmptyContainer>
);
}
Expand Down

0 comments on commit 8e3b5d9

Please sign in to comment.