diff --git a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.test.tsx b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.test.tsx
index 2a217215cc0..e6a68773f04 100644
--- a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.test.tsx
+++ b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.test.tsx
@@ -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(
+ ,
+ { 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/);
});
diff --git a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreviewByAlertManager.tsx b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreviewByAlertManager.tsx
index b9583a65e92..c99c14239cd 100644
--- a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreviewByAlertManager.tsx
+++ b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreviewByAlertManager.tsx
@@ -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 (
({
alertManagerRow: css`
diff --git a/public/app/features/alerting/unified/mockApi.ts b/public/app/features/alerting/unified/mockApi.ts
index 4607341af65..87e733494e6 100644
--- a/public/app/features/alerting/unified/mockApi.ts
+++ b/public/app/features/alerting/unified/mockApi.ts
@@ -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();