[v11.3.x] Alerting: Fix templates editing validation (#94963)

* Alerting: Fix templates editing validation (#94960)

Fix title validation when editing template files

(cherry picked from commit 5548e5976b)

* Adjust tests

---------

Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com>
This commit is contained in:
grafana-delivery-bot[bot]
2024-10-21 10:52:10 +02:00
committed by GitHub
co-authored by Konrad Lalik
parent 48d083d495
commit aa8c58abd0
3 changed files with 55 additions and 4 deletions
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Props } from 'react-virtualized-auto-sizer';
import { render, screen, within } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { render, screen, waitFor, within } from 'test/test-utils';
import { byLabelText, byRole } from 'testing-library-selector';
import { CodeEditorProps } from '@grafana/ui/src/components/Monaco/types';
import { AppNotificationList } from 'app/core/components/AppNotifications/AppNotificationList';
@@ -40,6 +40,10 @@ jest.mock('@grafana/ui', () => ({
const ui = {
templateForm: byRole('form', { name: 'Template form' }),
form: {
title: byLabelText(/Template name/),
saveButton: byRole('button', { name: 'Save' }),
},
};
const navUrl = {
@@ -77,6 +81,40 @@ describe('Templates routes', () => {
expect(form).toBeInTheDocument();
expect(within(form).getByRole('textbox', { name: /Template name/ })).toHaveValue('');
});
it('should pass name validation when editing existing template', async () => {
const { user } = render(
<>
<AppNotificationList />
<Templates />
</>,
{ historyOptions: { initialEntries: [navUrl.edit('custom-email')] } }
);
const titleElement = await ui.form.title.find();
await waitFor(() => {
expect(titleElement).toHaveValue('custom-email');
});
await user.click(ui.form.saveButton.get());
// No error message should be displayed for a unique name
expect(screen.queryByText('Another template with this name already exists')).not.toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('Template saved')).toBeInTheDocument();
});
});
it('should display error message when creating new template with duplicate name', async () => {
const { user } = render(<Templates />, { historyOptions: { initialEntries: [navUrl.new] } });
const titleElement = await ui.form.title.find();
await user.type(titleElement, 'custom-email');
await user.click(ui.form.saveButton.get());
expect(screen.getByText('Another template with this name already exists')).toBeInTheDocument();
});
});
describe('Templates K8s API', () => {
@@ -281,7 +281,15 @@ export function useDeleteNotificationTemplate({ alertmanager }: BaseAlertmanager
return k8sApiSupported ? deleteUsingK8sApi : deleteUsingConfigFileApi;
}
export function useValidateNotificationTemplate({ alertmanager }: BaseAlertmanagerArgs) {
interface ValidateNotificationTemplateParams {
alertmanager: string;
originalTemplate?: NotificationTemplate;
}
export function useValidateNotificationTemplate({
alertmanager,
originalTemplate,
}: ValidateNotificationTemplateParams) {
const { useLazyGetAlertmanagerConfigurationQuery } = alertmanagerApi;
const [fetchAmConfig] = useLazyGetAlertmanagerConfigurationQuery();
@@ -294,6 +302,11 @@ export function useValidateNotificationTemplate({ alertmanager }: BaseAlertmanag
return true;
}
if (originalTemplate?.title === name) {
// If original template is defined we update existing template so name will not be unique but it's ok
return true;
}
const amConfig = await fetchAmConfig(alertmanager).unwrap();
const templates = amConfigToTemplates(amConfig);
const templateOfThisNameExists = templates.some((t) => t.title === name);
@@ -93,7 +93,7 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
const createNewTemplate = useCreateNotificationTemplate({ alertmanager });
const updateTemplate = useUpdateNotificationTemplate({ alertmanager });
const { titleIsUnique } = useValidateNotificationTemplate({ alertmanager });
const { titleIsUnique } = useValidateNotificationTemplate({ alertmanager, originalTemplate });
useCleanup((state) => (state.unifiedAlerting.saveAMConfig = initialAsyncRequestState));
const formRef = useRef<HTMLFormElement>(null);