Throw error in case of not having receiver in routesByIdMap and add test for the use case of inheriting receiver from parent to check UI throws no errors
This commit is contained in:
+55
@@ -303,6 +303,61 @@ describe('NotificationPreviewByAlertmanager', () => {
|
||||
expect(matchingInstances0).toHaveTextContent(/severity=critical/);
|
||||
expect(matchingInstances0).toHaveTextContent(/foo=bar/);
|
||||
|
||||
expect(matchingInstances1).toHaveTextContent(/job=prometheus/);
|
||||
expect(matchingInstances1).toHaveTextContent(/severity=warning/);
|
||||
});
|
||||
it('should render route matching preview for alertmanager without errors if receiver is inherited from parent route ', async () => {
|
||||
const potentialInstances: Labels[] = [
|
||||
{ foo: 'bar', severity: 'critical' },
|
||||
{ job: 'prometheus', severity: 'warning' },
|
||||
];
|
||||
|
||||
mockApi(server).getAlertmanagerConfig(GRAFANA_RULES_SOURCE_NAME, (amConfigBuilder) =>
|
||||
amConfigBuilder
|
||||
.withRoute((routeBuilder) =>
|
||||
routeBuilder
|
||||
.withReceiver('email')
|
||||
.addRoute((rb) => {
|
||||
rb.addRoute((rb) => rb.withoutReceiver().addMatcher('foo', MatcherOperator.equal, 'bar'));
|
||||
return rb.withReceiver('slack').addMatcher('severity', MatcherOperator.equal, 'critical');
|
||||
})
|
||||
.addRoute((rb) => rb.withReceiver('opsgenie').addMatcher('team', MatcherOperator.equal, 'operations'))
|
||||
)
|
||||
.addReceivers((b) => b.withName('email').addEmailConfig((eb) => eb.withTo('test@example.com')))
|
||||
.addReceivers((b) => b.withName('slack'))
|
||||
.addReceivers((b) => b.withName('opsgenie'))
|
||||
);
|
||||
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(
|
||||
<NotificationPreviewByAlertManager
|
||||
alertManagerSource={{ name: GRAFANA_RULES_SOURCE_NAME, img: '' }}
|
||||
potentialInstances={potentialInstances}
|
||||
onlyOneAM={true}
|
||||
/>,
|
||||
{ wrapper: TestProvider }
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.loadingIndicator.query()).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
const routeElements = ui.route.getAll();
|
||||
|
||||
expect(routeElements).toHaveLength(2);
|
||||
expect(routeElements[0]).toHaveTextContent(/slack/);
|
||||
expect(routeElements[1]).toHaveTextContent(/email/);
|
||||
|
||||
await user.click(ui.routeButton.get(routeElements[0]));
|
||||
await user.click(ui.routeButton.get(routeElements[1]));
|
||||
|
||||
const matchingInstances0 = ui.routeMatchingInstances.get(routeElements[0]);
|
||||
const matchingInstances1 = ui.routeMatchingInstances.get(routeElements[1]);
|
||||
|
||||
expect(matchingInstances0).toHaveTextContent(/severity=critical/);
|
||||
expect(matchingInstances0).toHaveTextContent(/foo=bar/);
|
||||
|
||||
expect(matchingInstances1).toHaveTextContent(/job=prometheus/);
|
||||
expect(matchingInstances1).toHaveTextContent(/severity=warning/);
|
||||
});
|
||||
|
||||
+7
-3
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
|
||||
import { Alert, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui';
|
||||
|
||||
import { Stack } from '../../../../../../plugins/datasource/parca/QueryEditor/Stack';
|
||||
import { Labels } from '../../../../../../types/unified-alerting-dto';
|
||||
@@ -59,9 +59,13 @@ function NotificationPreviewByAlertManager({
|
||||
{Array.from(matchingMap.entries()).map(([routeId, instanceMatches]) => {
|
||||
const route = routesByIdMap.get(routeId);
|
||||
const receiver = route?.receiver && receiversByName.get(route.receiver);
|
||||
if (!route || !receiver) {
|
||||
|
||||
if (!route) {
|
||||
return null;
|
||||
}
|
||||
if (!receiver) {
|
||||
throw new Error('Receiver not found');
|
||||
}
|
||||
return (
|
||||
<NotificationRoute
|
||||
instanceMatches={instanceMatches}
|
||||
@@ -80,7 +84,7 @@ function NotificationPreviewByAlertManager({
|
||||
|
||||
// export default because we want to load the component dynamically using React.lazy
|
||||
// Due to loading of the web worker we don't want to load this component when not necessary
|
||||
export default NotificationPreviewByAlertManager;
|
||||
export default withErrorBoundary(NotificationPreviewByAlertManager);
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
alertManagerRow: css`
|
||||
|
||||
@@ -45,6 +45,9 @@ class AlertmanagerRouteBuilder {
|
||||
this.route.receiver = receiver;
|
||||
return this;
|
||||
}
|
||||
withoutReceiver(): AlertmanagerRouteBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
addRoute(configure: (builder: AlertmanagerRouteBuilder) => void): AlertmanagerRouteBuilder {
|
||||
const routeBuilder = new AlertmanagerRouteBuilder();
|
||||
|
||||
Reference in New Issue
Block a user