mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 01:53:33 -06:00
* Add RBAC section to settings * Default to RBAC enabled settings to true * Update tests to respect RBAC Co-authored-by: Karl Persson <kalle.persson@grafana.com>
296 lines
8.7 KiB
TypeScript
296 lines
8.7 KiB
TypeScript
import { render, waitFor, fireEvent } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import React from 'react';
|
|
import { Provider } from 'react-redux';
|
|
import { Router } from 'react-router-dom';
|
|
import { byRole, byTestId, byText } from 'testing-library-selector';
|
|
|
|
import { locationService, setDataSourceSrv } from '@grafana/runtime';
|
|
import { AlertManagerCortexConfig, MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types';
|
|
import { configureStore } from 'app/store/configureStore';
|
|
|
|
import MuteTimings from './MuteTimings';
|
|
import { fetchAlertManagerConfig, updateAlertManagerConfig } from './api/alertmanager';
|
|
import { disableRBAC, mockDataSource, MockDataSourceSrv } from './mocks';
|
|
import { DataSourceType } from './utils/datasource';
|
|
|
|
jest.mock('./api/alertmanager');
|
|
|
|
const mocks = {
|
|
api: {
|
|
fetchAlertManagerConfig: jest.mocked(fetchAlertManagerConfig),
|
|
updateAlertManagerConfig: jest.mocked(updateAlertManagerConfig),
|
|
},
|
|
};
|
|
|
|
const renderMuteTimings = (location = '/alerting/routes/mute-timing/new') => {
|
|
const store = configureStore();
|
|
locationService.push(location);
|
|
|
|
return render(
|
|
<Provider store={store}>
|
|
<Router history={locationService.getHistory()}>
|
|
<MuteTimings />
|
|
</Router>
|
|
</Provider>
|
|
);
|
|
};
|
|
|
|
const dataSources = {
|
|
am: mockDataSource({
|
|
name: 'Alertmanager',
|
|
type: DataSourceType.Alertmanager,
|
|
}),
|
|
};
|
|
|
|
const ui = {
|
|
form: byTestId('mute-timing-form'),
|
|
nameField: byTestId('mute-timing-name'),
|
|
|
|
startsAt: byTestId('mute-timing-starts-at'),
|
|
endsAt: byTestId('mute-timing-ends-at'),
|
|
addTimeRange: byRole('button', { name: /add another time range/i }),
|
|
|
|
weekdays: byTestId('mute-timing-weekdays'),
|
|
days: byTestId('mute-timing-days'),
|
|
months: byTestId('mute-timing-months'),
|
|
years: byTestId('mute-timing-years'),
|
|
|
|
addInterval: byRole('button', { name: /add another time interval/i }),
|
|
submitButton: byText(/submit/i),
|
|
};
|
|
|
|
const muteTimeInterval: MuteTimeInterval = {
|
|
name: 'default-mute',
|
|
time_intervals: [
|
|
{
|
|
times: [
|
|
{
|
|
start_time: '12:00',
|
|
end_time: '24:00',
|
|
},
|
|
],
|
|
days_of_month: ['15', '-1'],
|
|
months: ['august:december', 'march'],
|
|
},
|
|
],
|
|
};
|
|
|
|
const defaultConfig: AlertManagerCortexConfig = {
|
|
alertmanager_config: {
|
|
receivers: [{ name: 'default' }, { name: 'critical' }],
|
|
route: {
|
|
receiver: 'default',
|
|
group_by: ['alertname'],
|
|
routes: [
|
|
{
|
|
matchers: ['env=prod', 'region!=EU'],
|
|
mute_time_intervals: [muteTimeInterval.name],
|
|
},
|
|
],
|
|
},
|
|
templates: [],
|
|
mute_time_intervals: [muteTimeInterval],
|
|
},
|
|
template_files: {},
|
|
};
|
|
|
|
const resetMocks = () => {
|
|
jest.resetAllMocks();
|
|
|
|
mocks.api.fetchAlertManagerConfig.mockImplementation(() => {
|
|
return Promise.resolve({ ...defaultConfig });
|
|
});
|
|
mocks.api.updateAlertManagerConfig.mockImplementation(() => {
|
|
return Promise.resolve();
|
|
});
|
|
};
|
|
|
|
describe('Mute timings', () => {
|
|
beforeEach(() => {
|
|
setDataSourceSrv(new MockDataSourceSrv(dataSources));
|
|
resetMocks();
|
|
});
|
|
|
|
it('creates a new mute timing', async () => {
|
|
disableRBAC();
|
|
await renderMuteTimings();
|
|
|
|
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
|
expect(ui.nameField.get()).toBeInTheDocument();
|
|
|
|
await userEvent.type(ui.nameField.get(), 'maintenance period');
|
|
await userEvent.type(ui.startsAt.get(), '22:00');
|
|
await userEvent.type(ui.endsAt.get(), '24:00');
|
|
await userEvent.type(ui.days.get(), '-1');
|
|
await userEvent.type(ui.months.get(), 'january, july');
|
|
|
|
fireEvent.submit(ui.form.get());
|
|
|
|
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
|
|
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith('grafana', {
|
|
...defaultConfig,
|
|
alertmanager_config: {
|
|
...defaultConfig.alertmanager_config,
|
|
mute_time_intervals: [
|
|
muteTimeInterval,
|
|
{
|
|
name: 'maintenance period',
|
|
time_intervals: [
|
|
{
|
|
days_of_month: ['-1'],
|
|
months: ['january', 'july'],
|
|
times: [
|
|
{
|
|
start_time: '22:00',
|
|
end_time: '24:00',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
});
|
|
});
|
|
|
|
it('prepoluates the form when editing a mute timing', async () => {
|
|
await renderMuteTimings(
|
|
'/alerting/routes/mute-timing/edit' + `?muteName=${encodeURIComponent(muteTimeInterval.name)}`
|
|
);
|
|
|
|
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
|
expect(ui.nameField.get()).toBeInTheDocument();
|
|
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
|
expect(ui.months.get()).toHaveValue(muteTimeInterval.time_intervals[0].months?.join(', '));
|
|
|
|
await userEvent.clear(ui.startsAt.getAll()?.[0]);
|
|
await userEvent.clear(ui.endsAt.getAll()?.[0]);
|
|
await userEvent.clear(ui.weekdays.get());
|
|
await userEvent.clear(ui.days.get());
|
|
await userEvent.clear(ui.months.get());
|
|
await userEvent.clear(ui.years.get());
|
|
|
|
await userEvent.type(ui.weekdays.get(), 'monday');
|
|
await userEvent.type(ui.days.get(), '-7:-1');
|
|
await userEvent.type(ui.months.get(), '3, 6, 9, 12');
|
|
await userEvent.type(ui.years.get(), '2021:2024');
|
|
|
|
fireEvent.submit(ui.form.get());
|
|
|
|
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
|
|
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith('grafana', {
|
|
alertmanager_config: {
|
|
receivers: [
|
|
{
|
|
name: 'default',
|
|
},
|
|
{
|
|
name: 'critical',
|
|
},
|
|
],
|
|
route: {
|
|
receiver: 'default',
|
|
group_by: ['alertname'],
|
|
routes: [
|
|
{
|
|
matchers: ['env=prod', 'region!=EU'],
|
|
mute_time_intervals: ['default-mute'],
|
|
},
|
|
],
|
|
},
|
|
templates: [],
|
|
mute_time_intervals: [
|
|
{
|
|
name: 'default-mute',
|
|
time_intervals: [
|
|
{
|
|
times: [],
|
|
weekdays: ['monday'],
|
|
days_of_month: ['-7:-1'],
|
|
months: ['3', '6', '9', '12'],
|
|
years: ['2021:2024'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
template_files: {},
|
|
});
|
|
});
|
|
|
|
it('form is invalid with duplicate mute timing name', async () => {
|
|
await renderMuteTimings();
|
|
|
|
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
|
await waitFor(() => expect(ui.nameField.get()).toBeInTheDocument());
|
|
await userEvent.type(ui.nameField.get(), 'default-mute');
|
|
await userEvent.type(ui.days.get(), '1');
|
|
await waitFor(() => expect(ui.nameField.get()).toHaveValue('default-mute'));
|
|
|
|
fireEvent.submit(ui.form.get());
|
|
|
|
// Form state should be invalid and prevent firing of update action
|
|
await waitFor(() => expect(byRole('alert').get()).toBeInTheDocument());
|
|
expect(mocks.api.updateAlertManagerConfig).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('replaces mute timings in routes when the mute timing name is changed', async () => {
|
|
await renderMuteTimings(
|
|
'/alerting/routes/mute-timing/edit' + `?muteName=${encodeURIComponent(muteTimeInterval.name)}`
|
|
);
|
|
|
|
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
|
expect(ui.nameField.get()).toBeInTheDocument();
|
|
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
|
|
|
await userEvent.clear(ui.nameField.get());
|
|
await userEvent.type(ui.nameField.get(), 'Lunch breaks');
|
|
|
|
fireEvent.submit(ui.form.get());
|
|
|
|
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
|
|
expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalledWith('grafana', {
|
|
alertmanager_config: {
|
|
receivers: [
|
|
{
|
|
name: 'default',
|
|
},
|
|
{
|
|
name: 'critical',
|
|
},
|
|
],
|
|
route: {
|
|
receiver: 'default',
|
|
group_by: ['alertname'],
|
|
routes: [
|
|
{
|
|
matchers: ['env=prod', 'region!=EU'],
|
|
mute_time_intervals: ['Lunch breaks'],
|
|
},
|
|
],
|
|
},
|
|
templates: [],
|
|
mute_time_intervals: [
|
|
{
|
|
name: 'Lunch breaks',
|
|
time_intervals: [
|
|
{
|
|
times: [
|
|
{
|
|
start_time: '12:00',
|
|
end_time: '24:00',
|
|
},
|
|
],
|
|
days_of_month: ['15', '-1'],
|
|
months: ['august:december', 'march'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
template_files: {},
|
|
});
|
|
});
|
|
});
|