Alerting: Display error if repeat interval is lower than group interval (#69413)

* Display error if repeat interval is lower than group interval

* Small change

* Update tests
This commit is contained in:
Virginia Cepeda
2023-06-02 11:18:26 -03:00
committed by GitHub
parent 4db6056090
commit e6e88aa528
5 changed files with 93 additions and 4 deletions

View File

@@ -78,6 +78,32 @@ describe('EditDefaultPolicyForm', function () {
});
});
it('should show an error if repeat interval is lower than group interval', async function () {
const user = userEvent.setup();
const onSubmit = jest.fn();
renderRouteForm(
{
id: '0',
receiver: 'default',
},
[{ value: 'default', label: 'Default' }],
onSubmit
);
await user.click(ui.timingOptionsBtn.get());
await user.type(ui.groupWaitInput.get(), '5m25s');
await user.type(ui.groupIntervalInput.get(), '35m40s');
await user.type(ui.repeatIntervalInput.get(), '30m');
await user.click(ui.submitBtn.get());
expect(ui.error.getAll()).toHaveLength(1);
expect(ui.error.get().textContent).toBe('Repeat interval should be higher or equal to Group interval');
expect(onSubmit).not.toHaveBeenCalled();
});
it('should allow resetting existing timing options', async function () {
const user = userEvent.setup();

View File

@@ -10,6 +10,7 @@ import {
mapMultiSelectValueToStrings,
mapSelectValueToString,
promDurationValidator,
repeatIntervalValidator,
stringsToSelectableValues,
stringToSelectableValue,
} from '../../utils/amroutes';
@@ -43,7 +44,7 @@ export const AmRootRouteForm = ({
return (
<Form defaultValues={{ ...defaultValues, overrideTimings: true, overrideGrouping: true }} onSubmit={onSubmit}>
{({ register, control, errors, setValue }) => (
{({ register, control, errors, setValue, getValues }) => (
<>
<Field label="Default contact point" invalid={!!errors.receiver} error={errors.receiver?.message}>
<>
@@ -143,7 +144,12 @@ export const AmRootRouteForm = ({
data-testid="am-repeat-interval"
>
<PromDurationInput
{...register('repeatIntervalValue', { validate: promDurationValidator })}
{...register('repeatIntervalValue', {
validate: (value: string) => {
const groupInterval = getValues('groupIntervalValue');
return repeatIntervalValidator(value, groupInterval);
},
})}
placeholder={TIMING_OPTIONS_DEFAULTS.repeat_interval}
className={styles.promDurationInput}
aria-label="Repeat interval"

View File

@@ -76,6 +76,32 @@ describe('EditNotificationPolicyForm', function () {
});
});
it('should show an error if repeat interval is lower than group interval', async function () {
const user = userEvent.setup();
const onSubmit = jest.fn();
renderRouteForm(
{
id: '1',
receiver: 'default',
},
[{ value: 'default', label: 'Default' }],
onSubmit
);
await user.click(ui.overrideTimingsCheckbox.get());
await user.type(ui.groupWaitInput.get(), '5m25s');
await user.type(ui.groupIntervalInput.get(), '35m40s');
await user.type(ui.repeatIntervalInput.get(), '30m');
await user.click(ui.submitBtn.get());
expect(ui.error.getAll()).toHaveLength(1);
expect(ui.error.get().textContent).toBe('Repeat interval should be higher or equal to Group interval');
expect(onSubmit).not.toHaveBeenCalled();
});
it('should allow resetting existing timing options', async function () {
const user = userEvent.setup();

View File

@@ -32,6 +32,7 @@ import {
commonGroupByOptions,
amRouteToFormAmRoute,
promDurationValidator,
repeatIntervalValidator,
} from '../../utils/amroutes';
import { AmRouteReceiver } from '../receivers/grafanaAppReceivers/types';
@@ -74,7 +75,7 @@ export const AmRoutesExpandedForm = ({
return (
<Form defaultValues={defaultValues} onSubmit={onSubmit} maxWidth="none">
{({ control, register, errors, setValue, watch }) => (
{({ control, register, errors, setValue, watch, getValues }) => (
<>
<input type="hidden" {...register('id')} />
{/* @ts-ignore-check: react-hook-form made me do this */}
@@ -247,7 +248,12 @@ export const AmRoutesExpandedForm = ({
error={errors.repeatIntervalValue?.message}
>
<PromDurationInput
{...register('repeatIntervalValue', { validate: promDurationValidator })}
{...register('repeatIntervalValue', {
validate: (value: string) => {
const groupInterval = getValues('groupIntervalValue');
return repeatIntervalValidator(value, groupInterval);
},
})}
aria-label="Repeat interval value"
className={formStyles.promDurationInput}
/>

View File

@@ -3,6 +3,7 @@ import { uniqueId } from 'lodash';
import { SelectableValue } from '@grafana/data';
import { MatcherOperator, ObjectMatcher, Route, RouteWithID } from 'app/plugins/datasource/alertmanager/types';
import { safeParseDurationstr } from '../components/rules/EditRuleGroupModal';
import { FormAmRoute } from '../types/amroutes';
import { MatcherFieldValue } from '../types/silence-form';
@@ -225,3 +226,27 @@ export function promDurationValidator(duration: string) {
return isValidPrometheusDuration(duration) || 'Invalid duration format. Must be {number}{time_unit}';
}
export const repeatIntervalValidator = (repeatInterval: string, groupInterval: string) => {
if (repeatInterval.length === 0) {
return true;
}
const validRepeatInterval = promDurationValidator(repeatInterval);
const validGroupInterval = promDurationValidator(groupInterval);
if (validRepeatInterval !== true) {
return validRepeatInterval;
}
if (validGroupInterval !== true) {
return validGroupInterval;
}
const repeatDuration = safeParseDurationstr(repeatInterval);
const groupDuration = safeParseDurationstr(groupInterval);
const isRepeatLowerThanGroupDuration = groupDuration !== 0 && repeatDuration < groupDuration;
return isRepeatLowerThanGroupDuration ? 'Repeat interval should be higher or equal to Group interval' : true;
};