From 03a52dc10fc22f97e3d0317f682a47cfde9e9333 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 11 Oct 2023 12:01:58 +0100 Subject: [PATCH] [APPS-2108] migrate form field validators to date-fns (#8988) * migrate test * migrate datetime validator * date validator * min/max date validators * migrate form-field validators to date-fns * [ci:force] update docs * form-field-model date * field model: datetime * migrate form field model, extra tests and fixes --- .../lib/common/utils/date-fns-utils.spec.ts | 86 +++++++++++--- .../src/lib/common/utils/date-fns-utils.ts | 110 ++++++++++++------ .../widgets/core/form-field-validator.spec.ts | 16 ++- .../widgets/core/form-field-validator.ts | 105 ++++++++--------- .../widgets/core/form-field.model.ts | 37 +++--- ...dit-process-filter-cloud.component.spec.ts | 8 +- 6 files changed, 232 insertions(+), 130 deletions(-) diff --git a/lib/core/src/lib/common/utils/date-fns-utils.spec.ts b/lib/core/src/lib/common/utils/date-fns-utils.spec.ts index 59f21e2c377..e7b228fb068 100644 --- a/lib/core/src/lib/common/utils/date-fns-utils.spec.ts +++ b/lib/core/src/lib/common/utils/date-fns-utils.spec.ts @@ -15,26 +15,27 @@ * limitations under the License. */ +import { isValid } from 'date-fns'; import { DateFnsUtils } from './date-fns-utils'; -describe('Date Format Translations', () => { - it('should convert moment to date-fns format correctly', () => { - const momentFormat = 'YYYY-MM-DD'; - const expectedDateFnsFormat = 'yyyy-MM-dd'; +describe('DateFnsUtils', () => { + describe('convertMomentToDateFnsFormat', () => { + it('should convert moment date format', () => { + const dateFnsFormat = DateFnsUtils.convertMomentToDateFnsFormat('YYYY-MM-DD'); + expect(dateFnsFormat).toBe('yyyy-MM-dd'); + }); - const result = DateFnsUtils.convertMomentToDateFnsFormat(momentFormat); + it('should convert moment datetime format', () => { + const dateFnsFormat = DateFnsUtils.convertMomentToDateFnsFormat('YYYY-MM-DDTHH:mm:ssZ'); + expect(dateFnsFormat).toBe(`yyyy-MM-dd'T'HH:mm:ss'Z'`); + }); - expect(result).toBe(expectedDateFnsFormat); + it('should convert custom moment datetime format', () => { + const dateFnsFormat = DateFnsUtils.convertMomentToDateFnsFormat('D-M-YYYY hh:mm A'); + expect(dateFnsFormat).toBe('d-M-yyyy hh:mm a'); + }); }); - it('should convert date-fns to moment format correctly', () => { - const dateFnsFormat = 'yyyy-MM-dd'; - const expectedMomentFormat = 'YYYY-MM-DD'; - - const result = DateFnsUtils.convertDateFnsToMomentFormat(dateFnsFormat); - - expect(result).toBe(expectedMomentFormat); - }); it('should format a date correctly', () => { const date = new Date('2023-09-22T12:00:00Z'); @@ -46,13 +47,68 @@ describe('Date Format Translations', () => { expect(result).toBe(expectedFormattedDate); }); + it('should parse datetime', () => { + const parsed = DateFnsUtils.parseDate( + '09-02-9999 09:10 AM', + 'dd-MM-yyyy hh:mm aa' + ); + expect(isValid(parsed)); + expect(parsed.toISOString()).toBe('9999-02-09T09:10:00.000Z'); + }); + + it('should format datetime with custom moment format', () => { + const parsed = DateFnsUtils.formatDate( + new Date('9999-12-30T10:30:00.000Z'), + 'MM-DD-YYYY HH:mm A' + ); + expect(parsed).toBe('12-30-9999 10:30 AM'); + }); + + it('should parse moment datetime ISO', () => { + const parsed = DateFnsUtils.parseDate( + '1982-03-13T10:00:00Z', + 'YYYY-MM-DDTHH:mm:ssZ' + ); + expect(parsed.toISOString()).toBe('1982-03-13T10:00:00.000Z'); + }); + it('should parse a date correctly', () => { const dateString = '2023-09-22'; const dateFormat = 'yyyy-MM-dd'; const expectedParsedDate = new Date('2023-09-22T00:00:00Z'); const result = DateFnsUtils.parseDate(dateString, dateFormat); - expect(result).toEqual(expectedParsedDate); }); + + it('should format ISO datetime from date', () => { + const result = DateFnsUtils.formatDate( + new Date('2023-10-10T18:28:50.082Z'), + `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` + ); + expect(result).toBe('2023-10-10T18:28:50.082Z'); + }); + + it('should format ISO datetime from string', () => { + const result = DateFnsUtils.formatDate( + '2023-10-10T18:28:50.082Z', + `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` + ); + expect(result).toBe('2023-10-10T18:28:50.082Z'); + }); + + it('should validate datetime with moment format', () => { + const result = DateFnsUtils.isValidDate('2021-06-09 14:10', 'YYYY-MM-DD HH:mm'); + expect(result).toBeTrue(); + }); + + it('should validate datetime with date-fns format', () => { + const result = DateFnsUtils.isValidDate('2021-06-09 14:10', 'yyyy-MM-dd HH:mm'); + expect(result).toBeTrue(); + }); + + it('should not validate datetime with custom moment format', () => { + const result = DateFnsUtils.isValidDate('2021-06-09 14:10', 'D-M-YYYY hh:mm A'); + expect(result).toBeFalse(); + }); }); diff --git a/lib/core/src/lib/common/utils/date-fns-utils.ts b/lib/core/src/lib/common/utils/date-fns-utils.ts index 15937cdae62..77676341476 100644 --- a/lib/core/src/lib/common/utils/date-fns-utils.ts +++ b/lib/core/src/lib/common/utils/date-fns-utils.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { format, parse, parseISO } from 'date-fns'; +import { format, parse, parseISO, isValid, isBefore, isAfter } from 'date-fns'; import { ar, cs, da, de, enUS, es, fi, fr, it, ja, nb, nl, pl, ptBR, ru, sv, zhCN } from 'date-fns/locale'; export class DateFnsUtils { @@ -80,24 +80,14 @@ export class DateFnsUtils { return dateFnsLocale; } - /** - * A mapping of Moment.js format tokens to date-fns format tokens. - */ - static momentToDateFnsMap = { + private static momentToDateFnsMap = { D: 'd', Y: 'y', + AZ: 'aa', A: 'a', - ll: 'PP' - }; - - /** - * A mapping of date-fns format tokens to Moment.js format tokens. - */ - static dateFnsToMomentMap = { - d: 'D', - y: 'Y', - a: 'A', - PP: 'll' + ll: 'PP', + T: `'T'`, + Z: `'Z'` }; /** @@ -108,23 +98,12 @@ export class DateFnsUtils { */ static convertMomentToDateFnsFormat(dateDisplayFormat: string): string { if (dateDisplayFormat && dateDisplayFormat.trim() !== '') { - for (const [search, replace] of Object.entries(this.momentToDateFnsMap)) { - dateDisplayFormat = dateDisplayFormat.replace(new RegExp(search, 'g'), replace); - } - return dateDisplayFormat; - } - return ''; - } + // normalise the input to support double conversion of the same string + dateDisplayFormat = dateDisplayFormat + .replace(`'T'`, 'T') + .replace(`'Z'`, 'Z'); - /** - * Converts a date-fns date format string to the equivalent Moment.js format string. - * - * @param dateDisplayFormat - The date-fns date format string to convert. - * @returns The equivalent Moment.js format string. - */ - static convertDateFnsToMomentFormat(dateDisplayFormat: string): string { - if (dateDisplayFormat && dateDisplayFormat.trim() !== '') { - for (const [search, replace] of Object.entries(this.dateFnsToMomentMap)) { + for (const [search, replace] of Object.entries(this.momentToDateFnsMap)) { dateDisplayFormat = dateDisplayFormat.replace(new RegExp(search, 'g'), replace); } return dateDisplayFormat; @@ -137,7 +116,7 @@ export class DateFnsUtils { * * @param date - The date to format, can be a number or a Date object. * @param dateFormat - The date format string to use for formatting. - * @returns The formatted date as a string. + * @returns The formatted date as a string */ static formatDate(date: number | Date | string, dateFormat: string): string { if (typeof date === 'string') { @@ -149,11 +128,70 @@ export class DateFnsUtils { /** * Parses a date string using the specified date format. * - * @param value - The date string to parse. + * @param value - The date value to parse. Can be a string or a Date (for generic calls) * @param dateFormat - The date format string to use for parsing. + * @param options - Additional options + * @param options.dateOnly - Strip the time and zone * @returns The parsed Date object. */ - static parseDate(value: string, dateFormat: string): Date { - return parse(value, this.convertMomentToDateFnsFormat(dateFormat), new Date()); + static parseDate(value: string | Date, dateFormat: string, options?: { dateOnly?: boolean }): Date { + if (value) { + if (typeof value === 'string') { + if (options?.dateOnly && value.includes('T')) { + value = value.split('T')[0]; + } + + return parse(value, this.convertMomentToDateFnsFormat(dateFormat), new Date()); + } + return value; + } + return new Date('error'); + } + + /** + * Parses a datetime string using the ISO format + * + * @param value - The date and time string to parse + * @returns returns the parsed Date object + */ + static parseDateTime(value: string): Date { + return parseISO(value); + } + + /** + * Checks if the date string is a valid date according to the specified format + * + * @param dateValue Date value + * @param dateFormat The date format + * @returns `true` if the date is valid, otherwise `false` + */ + static isValidDate(dateValue: string, dateFormat: string): boolean { + if (dateValue) { + const date = this.parseDate(dateValue, dateFormat); + return isValid(date); + } + return false; + } + + /** + * Validates a date is before another one + * + * @param source source date to compare + * @param target target date to compare + * @returns `true` if the source date is before the target one, otherwise `false` + */ + static isBeforeDate(source: Date, target: Date): boolean { + return isBefore(source, target); + } + + /** + * Validates a date is after another one + * + * @param source source date to compare + * @param target target date to compare + * @returns `true` if the source date is after the target one, otherwise `false` + */ + static isAfterDate(source: Date, target: Date): boolean { + return isAfter(source, target); } } diff --git a/lib/core/src/lib/form/components/widgets/core/form-field-validator.spec.ts b/lib/core/src/lib/form/components/widgets/core/form-field-validator.spec.ts index 4e990d9a5b3..036fb4b8722 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field-validator.spec.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field-validator.spec.ts @@ -1113,9 +1113,21 @@ describe('FormFieldValidator', () => { it('should validate dateTime format with default format', () => { const field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.DATETIME, - value: '2021-06-09 14:10' + value: '9-6-2021 11:10 AM' }); - expect(validator.validate(field)).toBeTruthy(); + expect(field.value).toBe('9-6-2021 11:10 AM'); + expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A'); + expect(validator.validate(field)).toBeTrue(); + }); + + it('should not validate dateTime format with default format', () => { + const field = new FormFieldModel(new FormModel(), { + type: FormFieldTypes.DATETIME, + value: '2021-06-09 14:10' // 14:10 does not conform to A + }); + expect(field.value).toBe('2021-06-09 14:10'); + expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A'); + expect(validator.validate(field)).toBeFalse(); }); }); }); diff --git a/lib/core/src/lib/form/components/widgets/core/form-field-validator.ts b/lib/core/src/lib/form/components/widgets/core/form-field-validator.ts index cf63d348a0c..dd663280a4f 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field-validator.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field-validator.ts @@ -17,10 +17,10 @@ /* eslint-disable @angular-eslint/component-selector */ -import moment from 'moment'; import { FormFieldTypes } from './form-field-types'; import { isNumberValue } from './form-field-utils'; import { FormFieldModel } from './form-field.model'; +import { DateFnsUtils } from '../../../../common/utils/date-fns-utils'; export interface FormFieldValidator { @@ -146,12 +146,7 @@ export class DateFieldValidator implements FormFieldValidator { // Validates that the input string is a valid date formatted as (default D-M-YYYY) static isValidDate(inputDate: string, dateFormat: string = 'D-M-YYYY'): boolean { - if (inputDate) { - const d = moment(inputDate, dateFormat, true); - return d.isValid(); - } - - return false; + return DateFnsUtils.isValidDate(inputDate, dateFormat); } isSupported(field: FormFieldModel): boolean { @@ -178,12 +173,7 @@ export class DateTimeFieldValidator implements FormFieldValidator { // Validates that the input string is a valid date formatted as (default D-M-YYYY) static isValidDate(inputDate: string, dateFormat: string = 'YYYY-MM-DD HH:mm'): boolean { - if (inputDate) { - const d = moment(inputDate, dateFormat, true); - return d.isValid(); - } - - return false; + return DateFnsUtils.isValidDate(inputDate, dateFormat); } isSupported(field: FormFieldModel): boolean { @@ -239,22 +229,17 @@ export abstract class BoundaryDateFieldValidator implements FormFieldValidator { export class MinDateFieldValidator extends BoundaryDateFieldValidator { checkDate(field: FormFieldModel, dateFormat: string): boolean { - let isValid = true; - // remove time and timezone info - let fieldValueData; - if (typeof field.value === 'string') { - fieldValueData = moment(field.value.split('T')[0], dateFormat); - } else { - fieldValueData = field.value; - } - + const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true }); const minValueDateFormat = this.extractDateFormat(field.minValue); - const min = moment(field.minValue, minValueDateFormat); + const min = DateFnsUtils.parseDate(field.minValue, minValueDateFormat); - if (fieldValueData.isBefore(min)) { + if (DateFnsUtils.isBeforeDate(fieldValueData, min)) { field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`; - field.validationSummary.attributes.set('minValue', min.format(field.dateDisplayFormat).toLocaleUpperCase()); + field.validationSummary.attributes.set( + 'minValue', + DateFnsUtils.formatDate(min, field.dateDisplayFormat).toLocaleUpperCase() + ); isValid = false; } return isValid; @@ -269,22 +254,17 @@ export class MinDateFieldValidator extends BoundaryDateFieldValidator { export class MaxDateFieldValidator extends BoundaryDateFieldValidator { checkDate(field: FormFieldModel, dateFormat: string): boolean { - let isValid = true; - // remove time and timezone info - let fieldValueData; - if (typeof field.value === 'string') { - fieldValueData = moment(field.value.split('T')[0], dateFormat); - } else { - fieldValueData = field.value; - } - + const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true }); const maxValueDateFormat = this.extractDateFormat(field.maxValue); - const max = moment(field.maxValue, maxValueDateFormat); + const max = DateFnsUtils.parseDate(field.maxValue, maxValueDateFormat); - if (fieldValueData.isAfter(max)) { + if (DateFnsUtils.isAfterDate(fieldValueData, max)) { field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`; - field.validationSummary.attributes.set('maxValue', max.format(field.dateDisplayFormat).toLocaleUpperCase()); + field.validationSummary.attributes.set( + 'maxValue', + DateFnsUtils.formatDate(max, field.dateDisplayFormat).toLocaleUpperCase() + ); isValid = false; } return isValid; @@ -296,12 +276,19 @@ export class MaxDateFieldValidator extends BoundaryDateFieldValidator { } } +/** + * Validates the min constraint for the datetime value. + * + * Notes for developers: + * the format of the min/max values is always the ISO datetime: i.e. 2023-10-01T15:21:00.000Z. + * Min/Max values can be parsed with standard `new Date(value)` calls. + * + */ export class MinDateTimeFieldValidator implements FormFieldValidator { private supportedTypes = [ FormFieldTypes.DATETIME ]; - MIN_DATETIME_FORMAT = 'YYYY-MM-DD hh:mm AZ'; isSupported(field: FormFieldModel): boolean { return field && @@ -325,29 +312,34 @@ export class MinDateTimeFieldValidator implements FormFieldValidator { private checkDateTime(field: FormFieldModel, dateFormat: string): boolean { let isValid = true; - let fieldValueDate; - if (typeof field.value === 'string') { - fieldValueDate = moment(field.value, dateFormat); - } else { - fieldValueDate = field.value; - } - const min = moment(field.minValue, this.MIN_DATETIME_FORMAT); + const fieldValueDate = DateFnsUtils.parseDate(field.value, dateFormat); + const min = new Date(field.minValue); - if (fieldValueDate.isBefore(min)) { + if (DateFnsUtils.isBeforeDate(fieldValueDate, min)) { field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`; - field.validationSummary.attributes.set('minValue', min.format(field.dateDisplayFormat).replace(':', '-')); + field.validationSummary.attributes.set( + 'minValue', + DateFnsUtils.formatDate(min, field.dateDisplayFormat).replace(':', '-') + ); isValid = false; } return isValid; } } +/** + * Validates the max constraint for the datetime value. + * + * Notes for developers: + * the format of the min/max values is always the ISO datetime: i.e. 2023-10-01T15:21:00.000Z. + * Min/Max values can be parsed with standard `new Date(value)` calls. + * + */ export class MaxDateTimeFieldValidator implements FormFieldValidator { private supportedTypes = [ FormFieldTypes.DATETIME ]; - MAX_DATETIME_FORMAT = 'YYYY-MM-DD hh:mm AZ'; isSupported(field: FormFieldModel): boolean { return field && @@ -371,18 +363,15 @@ export class MaxDateTimeFieldValidator implements FormFieldValidator { private checkDateTime(field: FormFieldModel, dateFormat: string): boolean { let isValid = true; - let fieldValueDate; - - if (typeof field.value === 'string') { - fieldValueDate = moment(field.value, dateFormat); - } else { - fieldValueDate = field.value; - } - const max = moment(field.maxValue, this.MAX_DATETIME_FORMAT); + const fieldValueDate = DateFnsUtils.parseDate(field.value, dateFormat); + const max = new Date(field.maxValue); - if (fieldValueDate.isAfter(max)) { + if (DateFnsUtils.isAfterDate(fieldValueDate, max)) { field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`; - field.validationSummary.attributes.set('maxValue', max.format(field.dateDisplayFormat).replace(':', '-')); + field.validationSummary.attributes.set( + 'maxValue', + DateFnsUtils.formatDate(max, field.dateDisplayFormat).replace(':', '-') + ); isValid = false; } return isValid; diff --git a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts index dd2c0b2f95a..118e7ea069b 100644 --- a/lib/core/src/lib/form/components/widgets/core/form-field.model.ts +++ b/lib/core/src/lib/form/components/widgets/core/form-field.model.ts @@ -16,7 +16,6 @@ */ /* eslint-disable @angular-eslint/component-selector */ -import moment from 'moment'; import { WidgetVisibilityModel } from '../../../models/widget-visibility.model'; import { ContainerColumnModel } from './container-column.model'; import { ErrorMessageModel } from './error-message.model'; @@ -29,6 +28,8 @@ import { ProcessFormModel } from './process-form-model.interface'; import { isNumberValue } from './form-field-utils'; import { VariableConfig } from './form-field-variable-options'; import { DataColumn } from '../../../../datatable/data/data-column.model'; +import { DateFnsUtils } from '../../../../common'; +import { isValid as isValidDate } from 'date-fns'; // Maps to FormFieldRepresentation export class FormFieldModel extends FormWidgetModel { @@ -337,14 +338,18 @@ export class FormFieldModel extends FormWidgetModel { */ if (this.isDateField(json) || this.isDateTimeField(json)) { if (value) { - let dateValue; + let dateValue: Date; + if (isNumberValue(value)) { - dateValue = moment(value); + dateValue = new Date(value); } else { - dateValue = this.isDateTimeField(json) ? moment.utc(value, 'YYYY-MM-DD hh:mm A') : moment.utc(value.split('T')[0], 'YYYY-M-D'); + dateValue = this.isDateTimeField(json) + ? DateFnsUtils.parseDate(value, 'YYYY-MM-DD hh:mm A') + : DateFnsUtils.parseDate(value.split('T')[0], 'YYYY-M-D'); } - if (dateValue?.isValid()) { - value = dateValue.utc().format(this.dateDisplayFormat); + + if (isValidDate(dateValue)) { + value = DateFnsUtils.formatDate(dateValue, this.dateDisplayFormat); } } } @@ -417,12 +422,14 @@ export class FormFieldModel extends FormWidgetModel { } case FormFieldTypes.DATE: { if (typeof this.value === 'string' && this.value === 'today') { - this.value = moment(new Date()).format(this.dateDisplayFormat); + this.value = DateFnsUtils.formatDate(new Date(), this.dateDisplayFormat); } - const dateValue = moment(this.value, this.dateDisplayFormat, true); - if (dateValue?.isValid()) { - this.form.values[this.id] = `${dateValue.format('YYYY-MM-DD')}T00:00:00.000Z`; + const dateValue = DateFnsUtils.parseDate(this.value, this.dateDisplayFormat); + + if (isValidDate(dateValue)) { + const datePart = DateFnsUtils.formatDate(dateValue, 'yyyy-MM-dd'); + this.form.values[this.id] = `${datePart}T00:00:00.000Z`; } else { this.form.values[this.id] = null; this._value = this.value; @@ -431,13 +438,13 @@ export class FormFieldModel extends FormWidgetModel { } case FormFieldTypes.DATETIME: { if (typeof this.value === 'string' && this.value === 'now') { - this.value = moment(new Date()).utc().format(this.dateDisplayFormat); + this.value = DateFnsUtils.formatDate(new Date(), this.dateDisplayFormat); } - const dateTimeValue = moment.utc(this.value, this.dateDisplayFormat, true); - if (dateTimeValue?.isValid()) { - /* cspell:disable-next-line */ - this.form.values[this.id] = `${dateTimeValue.utc().format('YYYY-MM-DDTHH:mm:ss')}.000Z`; + const dateTimeValue = new Date(this.value); + + if (isValidDate(dateTimeValue)) { + this.form.values[this.id] = dateTimeValue.toISOString(); } else { this.form.values[this.id] = null; this._value = this.value; diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts index 580cc383b7c..2fa3e0d04c7 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts @@ -39,9 +39,8 @@ import { DateCloudFilterType } from '../../../models/date-cloud-filter.model'; import { MatIconTestingModule } from '@angular/material/icon/testing'; import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model'; import { mockAppVersions } from '../mock/process-filters-cloud.mock'; -import { DATE_FORMAT_CLOUD } from '../../../models/date-format-cloud.model'; import { fakeEnvironmentList } from '../../../common/mock/environment.mock'; -import { endOfDay, startOfDay } from 'date-fns'; +import { endOfDay, format, startOfDay, subYears } from 'date-fns'; describe('EditProcessFilterCloudComponent', () => { let component: EditProcessFilterCloudComponent; @@ -491,8 +490,9 @@ describe('EditProcessFilterCloudComponent', () => { priority: '12', suspendedDateType: DateCloudFilterType.RANGE }); - const oneYearAgoDate = moment().add(-1, 'years').format(DATE_FORMAT_CLOUD); - const todayDate = moment().format(DATE_FORMAT_CLOUD); + + const oneYearAgoDate = format(subYears(new Date(), 1), 'yyyy-MM-dd'); + const todayDate = format(new Date(),'yyyy-MM-dd'); filter.suspendedFrom = oneYearAgoDate.toString(); filter.suspendedTo = todayDate.toString(); getProcessFilterByIdSpy.and.returnValue(of(filter));