diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx index 0d9d0a44f1d..84c35a27d93 100644 --- a/public/app/features/alerting/unified/Silences.test.tsx +++ b/public/app/features/alerting/unified/Silences.test.tsx @@ -12,7 +12,7 @@ import { MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; import { AccessControlAction } from 'app/types'; import Silences from './Silences'; -import { grantUserPermissions, mockDataSource, MockDataSourceSrv } from './mocks'; +import { grantUserPermissions, MOCK_SILENCE_ID_EXISTING, mockDataSource, MockDataSourceSrv } from './mocks'; import { AlertmanagerProvider } from './state/AlertmanagerContext'; import { setupDataSources } from './testSetup/datasources'; import { DataSourceType } from './utils/datasource'; @@ -51,6 +51,7 @@ const ui = { silencedAlertCell: byTestId('alerts'), addSilenceButton: byRole('link', { name: /add silence/i }), queryBar: byPlaceholderText('Search'), + existingSilenceNotFound: byRole('alert', { name: /existing silence .* not found/i }), editor: { timeRange: byTestId(selectors.components.TimePicker.openButton), durationField: byLabelText('Duration'), @@ -290,6 +291,22 @@ describe('Silence create/edit', () => { TEST_TIMEOUT ); + it('shows an error when existing silence cannot be found', async () => { + renderSilences('/alerting/silence/foo-bar/edit'); + + expect(await ui.existingSilenceNotFound.find()).toBeInTheDocument(); + }); + + it('populates form with existing silence information', async () => { + renderSilences(`/alerting/silence/${MOCK_SILENCE_ID_EXISTING}/edit`); + + // Await the first value to be populated, after which we can expect that all of the other + // existing fields have been filled out as well + await waitFor(() => expect(ui.editor.matcherName.get()).toHaveValue('foo')); + expect(ui.editor.matcherValue.get()).toHaveValue('bar'); + expect(ui.editor.comment.get()).toHaveValue('Silence noisy alerts'); + }); + it( 'silences page should contain alertmanager parameter after creating a silence', async () => { diff --git a/public/app/features/alerting/unified/mocks.ts b/public/app/features/alerting/unified/mocks.ts index 978cf70a859..7ac3c3dfb13 100644 --- a/public/app/features/alerting/unified/mocks.ts +++ b/public/app/features/alerting/unified/mocks.ts @@ -307,10 +307,16 @@ export const mockSilence = (partial: Partial = {}): Silence => { }; }; +export const MOCK_SILENCE_ID_EXISTING = 'f209e273-0e4e-434f-9f66-e72f092025a2'; + export const mockSilences = [ - mockSilence({ id: '12345' }), - mockSilence({ id: '67890', matchers: parseMatchers('foo!=bar'), comment: 'Catch all' }), - mockSilence({ id: '1111', status: { state: SilenceState.Expired } }), + mockSilence({ id: MOCK_SILENCE_ID_EXISTING }), + mockSilence({ + id: 'ce031625-61c7-47cd-9beb-8760bccf0ed7', + matchers: parseMatchers('foo!=bar'), + comment: 'Catch all', + }), + mockSilence({ id: '145884a8-ee20-4864-9f84-661305fb7d82', status: { state: SilenceState.Expired } }), ]; export const mockNotifiersState = (partial: Partial = {}): NotifiersState => { diff --git a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts index b5ad61cc0b1..9c30d8ef699 100644 --- a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts +++ b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts @@ -1,7 +1,7 @@ import { http, HttpResponse } from 'msw'; import { SetupServer } from 'msw/node'; -import { mockAlertmanagerAlert } from 'app/features/alerting/unified/mocks'; +import { MOCK_SILENCE_ID_EXISTING, mockAlertmanagerAlert } from 'app/features/alerting/unified/mocks'; import { AlertmanagerChoice, @@ -51,11 +51,11 @@ export const alertmanagerAlertsListHandler = () => HttpResponse.json([ mockAlertmanagerAlert({ labels: { foo: 'bar', buzz: 'bazz' }, - status: { state: AlertState.Suppressed, silencedBy: ['12345'], inhibitedBy: [] }, + status: { state: AlertState.Suppressed, silencedBy: [MOCK_SILENCE_ID_EXISTING], inhibitedBy: [] }, }), mockAlertmanagerAlert({ labels: { foo: 'bar', buzz: 'bazz' }, - status: { state: AlertState.Suppressed, silencedBy: ['12345'], inhibitedBy: [] }, + status: { state: AlertState.Suppressed, silencedBy: [MOCK_SILENCE_ID_EXISTING], inhibitedBy: [] }, }), ]) ); diff --git a/public/app/features/alerting/unified/mocks/server/handlers.ts b/public/app/features/alerting/unified/mocks/server/handlers.ts index 78bc9baa86c..7fa5949fdc7 100644 --- a/public/app/features/alerting/unified/mocks/server/handlers.ts +++ b/public/app/features/alerting/unified/mocks/server/handlers.ts @@ -7,16 +7,23 @@ import { alertmanagerChoiceHandler, } from 'app/features/alerting/unified/mocks/alertmanagerApi'; import { datasourceBuildInfoHandler } from 'app/features/alerting/unified/mocks/datasources'; -import { silenceCreateHandler, silencesListHandler } from 'app/features/alerting/unified/mocks/silences'; +import { + silenceCreateHandler, + silenceGetHandler, + silencesListHandler, +} from 'app/features/alerting/unified/mocks/silences'; /** * All mock handlers that are required across Alerting tests */ const allHandlers = [ alertmanagerChoiceHandler(), - silencesListHandler(), - silenceCreateHandler(), alertmanagerAlertsListHandler(), + + silencesListHandler(), + silenceGetHandler(), + silenceCreateHandler(), + datasourceBuildInfoHandler(), ]; diff --git a/public/app/features/alerting/unified/mocks/silences.ts b/public/app/features/alerting/unified/mocks/silences.ts index e23e6ea9ded..75bf988ed28 100644 --- a/public/app/features/alerting/unified/mocks/silences.ts +++ b/public/app/features/alerting/unified/mocks/silences.ts @@ -9,6 +9,17 @@ import { mockSilences } from 'app/features/alerting/unified/mocks'; export const silencesListHandler = (silences = mockSilences) => http.get('/api/alertmanager/:datasourceUid/api/v2/silences', () => HttpResponse.json(silences)); +export const silenceGetHandler = () => + http.get<{ uuid: string }>('/api/alertmanager/:datasourceUid/api/v2/silence/:uuid', ({ params }) => { + const { uuid } = params; + const matchingMockSilence = mockSilences.find((silence) => silence.id === uuid); + if (matchingMockSilence) { + return HttpResponse.json(matchingMockSilence); + } + + return HttpResponse.json({ message: 'silence not found' }, { status: 404 }); + }); + export const silenceCreateHandler = () => http.post('/api/alertmanager/:datasourceUid/api/v2/silences', () => HttpResponse.json({ silenceId: '4bda5b38-7939-4887-9ec2-16323b8e3b4e' })