diff --git a/alfa-client/libs/tech-shared/src/lib/date.util.spec.ts b/alfa-client/libs/tech-shared/src/lib/date.util.spec.ts index 6a30b34fafdeb786e45347c1da6be75b25674e4c..fc5bc2c029bbaa651be5cbf7eac39bf2700a7a94 100644 --- a/alfa-client/libs/tech-shared/src/lib/date.util.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/date.util.spec.ts @@ -24,6 +24,7 @@ import { formatDate, registerLocaleData } from '@angular/common'; import localeDe from '@angular/common/locales/de'; import { + fixPartialYear, formatDateWithoutYearWithTime, formatForDatabase, formatFullDate, @@ -207,4 +208,23 @@ describe('Date Util', () => { dateStrField: string; } }); + + describe('fixPartialYear', () => { + it('should return Date in the 2000 millennium for 2 digit year value', () => { + const dateInput: Date = new Date('0023-10-22'); + const yearExpected: number = 2023; + + const result: Date = fixPartialYear(dateInput); + + expect(result.getFullYear()).toBe(yearExpected); + }); + + it('should return Date unchanged for non 2 digit year value', () => { + const dateInput: Date = new Date('2023-10-22'); + + const result: Date = fixPartialYear(dateInput); + + expect(result).toBe(dateInput); + }); + }); }); diff --git a/alfa-client/libs/tech-shared/src/lib/date.util.ts b/alfa-client/libs/tech-shared/src/lib/date.util.ts index 0d1cbfed27ae543a464047f2f7964b8638aeefb0..da5fe02a94d107c9c74e3b2b578da130aaf89fd9 100644 --- a/alfa-client/libs/tech-shared/src/lib/date.util.ts +++ b/alfa-client/libs/tech-shared/src/lib/date.util.ts @@ -101,3 +101,12 @@ export function sortByGermanDateStr<T>(entries: T[], getCompareField: (entry: T) function convertGermanDateString(dateStr: string): Date { return new Date(dateStr.replace(/(.*)\.(.*)\.(.*)/, '$3-$2-$1')); } + +export function fixPartialYear(date: Date) { + const year: number = date.getFullYear(); + if (year.toString().length !== 2) { + return date; + } + + return dateFns.addYears(date, 2000); +} diff --git a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.html b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.html index 4d9a6cd7f6c56983ce65590fcae495e88c34e42d..386a0b17284bb98e7120cada4ef904f37d2e56d5 100644 --- a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.html +++ b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.html @@ -32,6 +32,7 @@ (blur)="touch()" [attr.data-test-id]="(label | convertForDataTest) + '-date-input'" (dateInput)="inputEvent($event)" + (blur)="onBlur()" /> <mat-datepicker-toggle matSuffix [for]="picker"> <mat-icon matDatepickerToggleIcon attr.aria-label="xxx">update</mat-icon> diff --git a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.spec.ts b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.spec.ts index 0bfe30ef97c28aa38ac80510a09def0f312841c6..af091ae59f8bb7dd15807ee95bc512cdd02379ce 100644 --- a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.spec.ts +++ b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.spec.ts @@ -21,19 +21,22 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { MatNativeDateModule } from '@angular/material/core'; import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatIconModule } from '@angular/material/icon'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; +import faker from '@faker-js/faker'; import { MockComponent } from 'ng-mocks'; import { ValidationErrorComponent } from '../../validation-error/validation-error.component'; import { DateEditorComponent } from './date-editor.component'; +import * as dateUtil from '../../../../../../tech-shared/src/lib/date.util'; + describe('DateEditorComponent', () => { let component: DateEditorComponent; let fixture: ComponentFixture<DateEditorComponent>; @@ -79,4 +82,48 @@ describe('DateEditorComponent', () => { expect(element).toBeInstanceOf(HTMLElement); }); }); + + describe('onBlur', () => { + it('should not call fixPartialYear if input value is not Date object', () => { + const inputValue: string = '12.12.2024'; + component.fieldControl.setValue(inputValue); + const fixPartialYear = jest.spyOn(dateUtil, 'fixPartialYear'); + + component.onBlur(); + + expect(fixPartialYear).not.toHaveBeenCalled(); + }); + + describe('if input value is Date object', () => { + const inputValue: Date = faker.date.recent(); + + beforeEach(() => { + component.fieldControl.setValue(inputValue); + }); + + it('should call fixPartialYear', () => { + const fixPartialYear = jest.spyOn(dateUtil, 'fixPartialYear'); + + component.onBlur(); + + expect(fixPartialYear).toHaveBeenCalledWith(inputValue); + }); + + it('should call fieldControl.patchValue', () => { + const patchValue = jest.spyOn(component.fieldControl, 'patchValue'); + + component.onBlur(); + + expect(patchValue).toHaveBeenCalled(); + }); + + it('should call onChange', () => { + const onChange = jest.spyOn(component, 'onChange'); + + component.onBlur(); + + expect(onChange).toHaveBeenCalled(); + }); + }); + }); }); diff --git a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.ts b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.ts index d3288eabcb3db70e110084e9a8ed3e26f47dde5d..a2f0076e75436e58d9538642cc00c6fe9bb6b7b9 100644 --- a/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.ts +++ b/alfa-client/libs/ui/src/lib/ui/editor/date-editor/date-editor.component.ts @@ -21,8 +21,10 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { fixPartialYear } from '@alfa-client/tech-shared'; import { Component, Input } from '@angular/core'; import { MatDatepickerInputEvent } from '@angular/material/datepicker'; +import { isDate } from 'date-fns'; import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstract.component'; @Component({ @@ -36,4 +38,15 @@ export class DateEditorComponent extends FormControlEditorAbstractComponent { inputEvent(event: MatDatepickerInputEvent<Date>): void { this.onChange(event.value); } + + onBlur(): void { + if (!isDate(this.fieldControl.value)) { + return; + } + + const value: Date = fixPartialYear(this.fieldControl.value); + + this.fieldControl.patchValue(value); + this.onChange(value); + } }