mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fix saving telegram contact point to Cloud AM config (#89182)
* Add test for saving telegram contact point to AM config * Fix default value for select options in AM config
This commit is contained in:
parent
84590901e5
commit
26233e98a8
74
public/app/features/alerting/unified/Receivers.test.tsx
Normal file
74
public/app/features/alerting/unified/Receivers.test.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
||||
import { render, screen, waitFor, userEvent } from 'test/test-utils';
|
||||
|
||||
import {
|
||||
EXTERNAL_VANILLA_ALERTMANAGER_UID,
|
||||
setupVanillaAlertmanagerServer,
|
||||
} from 'app/features/alerting/unified/components/settings/__mocks__/server';
|
||||
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
|
||||
import { grantUserPermissions, mockDataSource } from 'app/features/alerting/unified/mocks';
|
||||
import { setupDataSources } from 'app/features/alerting/unified/testSetup/datasources';
|
||||
import { DataSourceType } from 'app/features/alerting/unified/utils/datasource';
|
||||
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import ContactPoints from './Receivers';
|
||||
|
||||
import 'core-js/stable/structured-clone';
|
||||
|
||||
const server = setupMswServer();
|
||||
|
||||
const mockDataSources = {
|
||||
[EXTERNAL_VANILLA_ALERTMANAGER_UID]: mockDataSource<AlertManagerDataSourceJsonData>({
|
||||
uid: EXTERNAL_VANILLA_ALERTMANAGER_UID,
|
||||
name: EXTERNAL_VANILLA_ALERTMANAGER_UID,
|
||||
type: DataSourceType.Alertmanager,
|
||||
jsonData: {
|
||||
implementation: AlertManagerImplementation.prometheus,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
grantUserPermissions([
|
||||
AccessControlAction.AlertingNotificationsRead,
|
||||
AccessControlAction.AlertingNotificationsWrite,
|
||||
AccessControlAction.AlertingNotificationsExternalRead,
|
||||
AccessControlAction.AlertingNotificationsExternalWrite,
|
||||
]);
|
||||
});
|
||||
|
||||
it('can save a contact point with a select dropdown', async () => {
|
||||
setupVanillaAlertmanagerServer(server);
|
||||
setupDataSources(mockDataSources[EXTERNAL_VANILLA_ALERTMANAGER_UID]);
|
||||
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<ContactPoints />, {
|
||||
historyOptions: {
|
||||
initialEntries: [`/alerting/notifications/receivers/new?alertmanager=${EXTERNAL_VANILLA_ALERTMANAGER_UID}`],
|
||||
},
|
||||
});
|
||||
|
||||
// Fill out contact point name
|
||||
const contactPointName = await screen.findByPlaceholderText(/name/i);
|
||||
await user.type(contactPointName, 'contact point with select');
|
||||
|
||||
// Select Telegram option (this is we expect the form to contain a dropdown)
|
||||
const integrationDropdown = screen.getByLabelText(/integration/i);
|
||||
await selectOptionInTest(integrationDropdown, /telegram/i);
|
||||
|
||||
// Fill out basic fields necessary for contact point to be saved
|
||||
const botToken = await screen.findByLabelText(/bot token/i);
|
||||
const chatId = await screen.findByLabelText(/chat id/i);
|
||||
|
||||
await user.type(botToken, 'sometoken');
|
||||
await user.type(chatId, '-123');
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: /save contact point/i }));
|
||||
|
||||
// TODO: Have a better way to assert that the contact point was saved. This is instead asserting on some
|
||||
// text that's present on the list page, as there's a lot of overlap in text between the form and the list page
|
||||
await waitFor(() => expect(screen.getByText(/search by name or type/i)).toBeInTheDocument(), { timeout: 2000 });
|
||||
});
|
@ -3,7 +3,6 @@ import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { withErrorBoundary } from '@grafana/ui';
|
||||
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
|
||||
import { AlertmanagerPageWrapper } from './components/AlertingPageWrapper';
|
||||
|
||||
@ -12,7 +11,7 @@ const EditContactPoint = SafeDynamicImport(() => import('./components/contact-po
|
||||
const NewContactPoint = SafeDynamicImport(() => import('./components/contact-points/NewContactPoint'));
|
||||
const GlobalConfig = SafeDynamicImport(() => import('./components/contact-points/components/GlobalConfig'));
|
||||
|
||||
const ContactPoints = (_props: GrafanaRouteComponentProps): JSX.Element => (
|
||||
const ContactPoints = (): JSX.Element => (
|
||||
<AlertmanagerPageWrapper navId="receivers" accessType="notification">
|
||||
<Switch>
|
||||
<Route exact={true} path="/alerting/notifications" component={ContactPointsV2} />
|
||||
|
@ -161,7 +161,7 @@ const OptionInput: FC<Props & { id: string; pathIndex?: string }> = ({
|
||||
)}
|
||||
control={control}
|
||||
name={name}
|
||||
defaultValue={option.defaultValue}
|
||||
defaultValue={option.defaultValue?.value}
|
||||
rules={{
|
||||
validate: {
|
||||
customValidator: (v) => (customValidator ? customValidator(v) : true),
|
||||
|
@ -2,7 +2,13 @@ import { delay, http, HttpResponse } from 'msw';
|
||||
import { SetupServerApi } from 'msw/lib/node';
|
||||
|
||||
import { setDataSourceSrv } from '@grafana/runtime';
|
||||
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
|
||||
import {
|
||||
AlertManagerCortexConfig,
|
||||
AlertManagerDataSourceJsonData,
|
||||
AlertManagerImplementation,
|
||||
AlertmanagerReceiver,
|
||||
Receiver,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
|
||||
import { mockDataSource, MockDataSourceSrv } from '../../../mocks';
|
||||
import * as config from '../../../utils/config';
|
||||
@ -70,7 +76,7 @@ export function setupVanillaAlertmanagerServer(server: SetupServerApi) {
|
||||
|
||||
server.use(
|
||||
createVanillaAlertmanagerConfigurationHandler(EXTERNAL_VANILLA_ALERTMANAGER_UID),
|
||||
...createAlertmanagerConfigurationHandlers(PROVISIONED_MIMIR_ALERTMANAGER_UID)
|
||||
...createAlertmanagerConfigurationHandlers()
|
||||
);
|
||||
|
||||
return server;
|
||||
@ -82,11 +88,33 @@ const createExternalAlertmanagersHandler = () => {
|
||||
return http.get('/api/v1/ngalert/alertmanagers', () => HttpResponse.json(alertmanagers));
|
||||
};
|
||||
|
||||
const createAlertmanagerConfigurationHandlers = (name = 'grafana') => {
|
||||
const createAlertmanagerConfigurationHandlers = () => {
|
||||
// Dirty check to type guard against us having a non-Grafana managed receiver
|
||||
const contactPointIsAMReceiver = (receiver: Receiver): receiver is AlertmanagerReceiver => {
|
||||
return !receiver.grafana_managed_receiver_configs;
|
||||
};
|
||||
|
||||
return [
|
||||
http.get(`/api/alertmanager/${name}/config/api/v1/alerts`, () => HttpResponse.json(internalAlertmanagerConfig)),
|
||||
http.post(`/api/alertmanager/${name}/config/api/v1/alerts`, async () => {
|
||||
http.get(`/api/alertmanager/:name/config/api/v1/alerts`, () => HttpResponse.json(internalAlertmanagerConfig)),
|
||||
http.post<never, AlertManagerCortexConfig>(`/api/alertmanager/:name/config/api/v1/alerts`, async ({ request }) => {
|
||||
await delay(1000); // simulate some time
|
||||
|
||||
// Specifically mock and check for the case of an invalid telegram config,
|
||||
// and return a 400 error in this case
|
||||
// This is to test against us accidentally sending a `{label, value}` object instead of a string
|
||||
const body = await request.json();
|
||||
const invalidConfig = body.alertmanager_config.receivers?.some((receiver) => {
|
||||
if (!contactPointIsAMReceiver(receiver)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (receiver.telegram_configs || []).some((config) => typeof config.parse_mode === 'object');
|
||||
});
|
||||
|
||||
if (invalidConfig) {
|
||||
return HttpResponse.json({ message: 'bad request data' }, { status: 400 });
|
||||
}
|
||||
|
||||
return HttpResponse.json({ message: 'configuration created' });
|
||||
}),
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user