mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `9.0`: - [[Synthetics] Fix issue when selecting monitor frequency (#215823)](https://github.com/elastic/kibana/pull/215823) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Francesco Fagnani","email":"fagnani.francesco@gmail.com"},"sourceCommit":{"committedDate":"2025-03-25T13:16:37Z","message":"[Synthetics] Fix issue when selecting monitor frequency (#215823)\n\nThis PR closes issue #209188.\n\nIf the frequency is set to seconds, when setting it back to minutes the\ntime unit is correctly changed.\n\n\n\nhttps://github.com/user-attachments/assets/1a65b130-9740-41f1-94dc-f97cf887ff1a\n\n---------\n\nCo-authored-by: Shahzad <shahzad31comp@gmail.com>","sha":"7429c29522579f9c3e9d5c76df8ea58dca583d97","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:obs-ux-management","backport:version","v9.1.0","v8.19.0","v8.18.1","v8.17.4","v9.0.1"],"title":"[Synthetics] Fix issue when selecting monitor frequency","number":215823,"url":"https://github.com/elastic/kibana/pull/215823","mergeCommit":{"message":"[Synthetics] Fix issue when selecting monitor frequency (#215823)\n\nThis PR closes issue #209188.\n\nIf the frequency is set to seconds, when setting it back to minutes the\ntime unit is correctly changed.\n\n\n\nhttps://github.com/user-attachments/assets/1a65b130-9740-41f1-94dc-f97cf887ff1a\n\n---------\n\nCo-authored-by: Shahzad <shahzad31comp@gmail.com>","sha":"7429c29522579f9c3e9d5c76df8ea58dca583d97"}},"sourceBranch":"main","suggestedTargetBranches":["8.x","8.18","8.17","9.0"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/215823","number":215823,"mergeCommit":{"message":"[Synthetics] Fix issue when selecting monitor frequency (#215823)\n\nThis PR closes issue #209188.\n\nIf the frequency is set to seconds, when setting it back to minutes the\ntime unit is correctly changed.\n\n\n\nhttps://github.com/user-attachments/assets/1a65b130-9740-41f1-94dc-f97cf887ff1a\n\n---------\n\nCo-authored-by: Shahzad <shahzad31comp@gmail.com>","sha":"7429c29522579f9c3e9d5c76df8ea58dca583d97"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.4","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.0","label":"v9.0.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Francesco Fagnani <fagnani.francesco@gmail.com>
This commit is contained in:
parent
dbf34e58ef
commit
e541bb29e5
6 changed files with 88 additions and 19 deletions
|
@ -380,4 +380,18 @@ describe('format', () => {
|
|||
}, {})
|
||||
);
|
||||
});
|
||||
|
||||
it('sets the schedule unit to seconds if the number ends with the letter s', () => {
|
||||
formValues.schedule = { number: '10s', unit: 'm' };
|
||||
expect(format(formValues)).toEqual(
|
||||
expect.objectContaining({ schedule: { number: '10', unit: 's' } })
|
||||
);
|
||||
});
|
||||
|
||||
it('changes schedule unit back to minutes when it is changed from seconds to minutes', () => {
|
||||
formValues.schedule = { number: '3', unit: 's' };
|
||||
expect(format(formValues)).toEqual(
|
||||
expect.objectContaining({ schedule: { number: '3', unit: 'm' } })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,13 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import { get, pick } from 'lodash';
|
||||
import {
|
||||
ConfigKey,
|
||||
MonitorTypeEnum,
|
||||
FormMonitorType,
|
||||
MonitorFields,
|
||||
SyntheticsMonitorSchedule,
|
||||
} from '../types';
|
||||
import { ConfigKey, MonitorTypeEnum, FormMonitorType, MonitorFields, ScheduleUnit } from '../types';
|
||||
import { DEFAULT_FIELDS } from '../constants';
|
||||
|
||||
export const serializeNestedFormField = (fields: Record<string, any>) => {
|
||||
|
@ -28,6 +22,14 @@ export const serializeNestedFormField = (fields: Record<string, any>) => {
|
|||
|
||||
export const ALLOWED_FIELDS = [ConfigKey.ENABLED, ConfigKey.ALERT_CONFIG];
|
||||
|
||||
const formatSchedule = (schedule: { number: string; unit: ScheduleUnit }) => {
|
||||
const isFrequencyInSeconds = schedule.number.endsWith('s');
|
||||
return {
|
||||
number: isFrequencyInSeconds ? schedule.number.slice(0, -1) : schedule.number,
|
||||
unit: isFrequencyInSeconds ? ScheduleUnit.SECONDS : ScheduleUnit.MINUTES,
|
||||
};
|
||||
};
|
||||
|
||||
export const format = (fields: Record<string, unknown>, readOnly: boolean = false) => {
|
||||
const formattedFields = serializeNestedFormField(fields) as MonitorFields;
|
||||
const textAssertion = formattedFields[ConfigKey.TEXT_ASSERTION]
|
||||
|
@ -35,13 +37,7 @@ export const format = (fields: Record<string, unknown>, readOnly: boolean = fals
|
|||
await page.getByText('${formattedFields[ConfigKey.TEXT_ASSERTION]}').first().waitFor();`
|
||||
: ``;
|
||||
|
||||
const schedule = formattedFields[ConfigKey.SCHEDULE];
|
||||
if (schedule.number.endsWith('s')) {
|
||||
formattedFields[ConfigKey.SCHEDULE] = {
|
||||
number: `${schedule.number.slice(0, -1)}`,
|
||||
unit: 's' as SyntheticsMonitorSchedule['unit'],
|
||||
};
|
||||
}
|
||||
formattedFields[ConfigKey.SCHEDULE] = formatSchedule(formattedFields[ConfigKey.SCHEDULE]);
|
||||
|
||||
const formattedMap = {
|
||||
[FormMonitorType.SINGLE]: {
|
||||
|
|
|
@ -8,7 +8,10 @@ import { schema } from '@kbn/config-schema';
|
|||
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { validatePermissions } from './edit_monitor';
|
||||
import { InvalidLocationError } from '../../synthetics_service/project_monitor/normalizers/common_fields';
|
||||
import {
|
||||
InvalidLocationError,
|
||||
InvalidScheduleError,
|
||||
} from '../../synthetics_service/project_monitor/normalizers/common_fields';
|
||||
import { AddEditMonitorAPI, CreateMonitorPayLoad } from './add_monitor/add_monitor_api';
|
||||
import { SyntheticsRestApiRouteFactory } from '../types';
|
||||
import { SYNTHETICS_API_URLS } from '../../../common/constants';
|
||||
|
@ -121,7 +124,7 @@ export const addSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () => ({
|
|||
return mapSavedObjectToMonitor({ monitor: newMonitor, internal });
|
||||
} catch (getErr) {
|
||||
server.logger.error(getErr);
|
||||
if (getErr instanceof InvalidLocationError) {
|
||||
if (getErr instanceof InvalidLocationError || getErr instanceof InvalidScheduleError) {
|
||||
return response.badRequest({ body: { message: getErr.message } });
|
||||
}
|
||||
if (SavedObjectsErrorHelpers.isForbiddenError(getErr)) {
|
||||
|
|
|
@ -9,7 +9,10 @@ import { SavedObjectsUpdateResponse, SavedObject } from '@kbn/core/server';
|
|||
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { invalidOriginError } from './add_monitor';
|
||||
import { InvalidLocationError } from '../../synthetics_service/project_monitor/normalizers/common_fields';
|
||||
import {
|
||||
InvalidLocationError,
|
||||
InvalidScheduleError,
|
||||
} from '../../synthetics_service/project_monitor/normalizers/common_fields';
|
||||
import { AddEditMonitorAPI, CreateMonitorPayLoad } from './add_monitor/add_monitor_api';
|
||||
import { ELASTIC_MANAGED_LOCATIONS_DISABLED } from './project_monitor/add_monitor_project';
|
||||
import { getDecryptedMonitor } from '../../saved_objects/synthetics_monitor';
|
||||
|
@ -185,7 +188,7 @@ export const editSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () => (
|
|||
if (SavedObjectsErrorHelpers.isNotFoundError(updateErr)) {
|
||||
return getMonitorNotFoundResponse(response, monitorId);
|
||||
}
|
||||
if (updateErr instanceof InvalidLocationError) {
|
||||
if (updateErr instanceof InvalidLocationError || updateErr instanceof InvalidScheduleError) {
|
||||
return response.badRequest({ body: { message: updateErr.message } });
|
||||
}
|
||||
if (updateErr instanceof MonitorValidationError) {
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ScheduleUnit } from '../../../../common/runtime_types';
|
||||
import {
|
||||
flattenAndFormatObject,
|
||||
getMonitorSchedule,
|
||||
getNormalizeCommonFields,
|
||||
getUrlsField,
|
||||
InvalidScheduleError,
|
||||
isValidURL,
|
||||
NormalizedProjectProps,
|
||||
} from './common_fields';
|
||||
|
@ -242,3 +245,33 @@ describe('getNormalizeCommonFields', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMonitorSchedule', () => {
|
||||
it('should return default value if schedule is falsy', () => {
|
||||
const defaultValue = { number: '5', unit: ScheduleUnit.MINUTES };
|
||||
expect(getMonitorSchedule(null as any, defaultValue)).toEqual(defaultValue);
|
||||
expect(getMonitorSchedule(undefined as any, defaultValue)).toEqual(defaultValue);
|
||||
});
|
||||
|
||||
it('should return a schedule object with minutes if schedule is a number', () => {
|
||||
expect(getMonitorSchedule(5)).toEqual({ number: '5', unit: ScheduleUnit.MINUTES });
|
||||
});
|
||||
|
||||
it('should return a schedule object with minutes if schedule is a string without seconds', () => {
|
||||
expect(getMonitorSchedule('10')).toEqual({ number: '10', unit: ScheduleUnit.MINUTES });
|
||||
});
|
||||
|
||||
it('should return a schedule object with seconds if schedule is allowed', () => {
|
||||
expect(getMonitorSchedule('10s')).toEqual({ number: '10', unit: ScheduleUnit.SECONDS });
|
||||
expect(getMonitorSchedule('30s')).toEqual({ number: '30', unit: ScheduleUnit.SECONDS });
|
||||
});
|
||||
|
||||
it('should throw InvalidScheduleError if schedule in seconds is not allowed', () => {
|
||||
expect(() => getMonitorSchedule('20s')).toThrow(InvalidScheduleError);
|
||||
});
|
||||
|
||||
it('should return the schedule object if schedule is already in the correct format', () => {
|
||||
const existingSchedule = { number: '15', unit: ScheduleUnit.MINUTES };
|
||||
expect(getMonitorSchedule(existingSchedule)).toEqual(existingSchedule);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { omit, uniqBy } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isValidNamespace } from '@kbn/fleet-plugin/common';
|
||||
|
@ -22,7 +24,10 @@ import {
|
|||
MonitorFields,
|
||||
type SyntheticsPrivateLocations,
|
||||
} from '../../../../common/runtime_types';
|
||||
import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults';
|
||||
import {
|
||||
ALLOWED_SCHEDULES_IN_SECONDS,
|
||||
DEFAULT_FIELDS,
|
||||
} from '../../../../common/constants/monitor_defaults';
|
||||
import { DEFAULT_COMMON_FIELDS } from '../../../../common/constants/monitor_defaults';
|
||||
import { formatKibanaNamespace } from '../../formatters/private_formatters';
|
||||
|
||||
|
@ -165,6 +170,14 @@ export const getMonitorSchedule = (
|
|||
};
|
||||
}
|
||||
if (schedule.includes('s')) {
|
||||
if (!ALLOWED_SCHEDULES_IN_SECONDS.includes(schedule)) {
|
||||
throw new InvalidScheduleError(
|
||||
i18n.translate('xpack.synthetics.projectMonitorApi.validation.invalidSchedule', {
|
||||
defaultMessage: 'Invalid schedule. Allowed schedules in seconds are {allowedSchedules}',
|
||||
values: { allowedSchedules: ALLOWED_SCHEDULES_IN_SECONDS.join(', ') },
|
||||
})
|
||||
);
|
||||
}
|
||||
return {
|
||||
number: schedule.replace('s', ''),
|
||||
unit: ScheduleUnit.SECONDS,
|
||||
|
@ -257,6 +270,13 @@ export class InvalidLocationError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class InvalidScheduleError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'InvalidScheduleError';
|
||||
}
|
||||
}
|
||||
|
||||
const UNSUPPORTED_OPTION_TITLE = i18n.translate(
|
||||
'xpack.synthetics.projectMonitorApi.validation.unsupportedOption.title',
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue