diff --git a/src/main/js/app/directive/ngx-datatable-doubleclick.directive.spec.ts b/src/main/js/app/directive/ngx-datatable-doubleclick.directive.spec.ts new file mode 100644 index 0000000..9a1dff4 --- /dev/null +++ b/src/main/js/app/directive/ngx-datatable-doubleclick.directive.spec.ts @@ -0,0 +1,76 @@ +import {Component} from '@angular/core'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; +import {By} from '@angular/platform-browser'; +import {NgxDatatableDblClickDirective} from './ngx-datatable-doubleclick.directive'; +import {Model} from '@swimlane/ngx-datatable'; + +@Component({ + template: ` +
+
+ `, +}) +class TestComponent { + onRowDblClick = jasmine.createSpy('onRowDblClick'); +} + +describe('NgxDatatableDblClickDirective', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [NgxDatatableDblClickDirective], // Use `imports` for standalone directives + declarations: [TestComponent], + }); + fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + }); + + it('should add "onDblClick" class to the host element', () => { + const hostElement = fixture.debugElement.query(By.directive(NgxDatatableDblClickDirective)); + expect(hostElement.nativeElement.classList).toContain('onDblClick'); + }); + + it('should emit "dblClick" event when a dblclick event with a row is received', () => { + const hostElement = fixture.debugElement.query(By.directive(NgxDatatableDblClickDirective)); + const directive = hostElement.injector.get(NgxDatatableDblClickDirective); + + const testRow = {id: 1, name: 'Test Row'}; + const mockEvent: Model = { + type: 'dblclick', + row: testRow, + event: new MouseEvent('dblclick'), + rowElement: document.createElement('tr'), + cellElement: document.createElement('td'), + cellIndex: 0, + }; + + directive.onActivate(mockEvent); + + fixture.detectChanges(); + const testComponent = fixture.componentInstance; + expect(testComponent.onRowDblClick).toHaveBeenCalledWith(testRow); + }); + + it('should not emit "dblClick" event for non-dblclick events', () => { + const hostElement = fixture.debugElement.query(By.directive(NgxDatatableDblClickDirective)); + const directive = hostElement.injector.get(NgxDatatableDblClickDirective); + + const mockEvent: Model = { + type: 'click', + row: {id: 1, name: 'Test Row'}, + event: new MouseEvent('click'), + rowElement: document.createElement('tr'), + cellElement: document.createElement('td'), + cellIndex: 0, + }; + + directive.onActivate(mockEvent); + + fixture.detectChanges(); + const testComponent = fixture.componentInstance; + expect(testComponent.onRowDblClick).not.toHaveBeenCalled(); + }); +}); diff --git a/src/main/js/app/model/demo.mock.ts b/src/main/js/app/model/demo.mock.ts new file mode 100644 index 0000000..9d3b95c --- /dev/null +++ b/src/main/js/app/model/demo.mock.ts @@ -0,0 +1,16 @@ +import {Demo, DemoFilter} from './demo.model'; + +export const demoFilterMock : DemoFilter = { + eingangVon: '20241224', + eingangBis: '20241230', + system: 'ABC', + nachrichtentyp: 'BCD', + nummer1: '12345678', + nummer2: '23456789', +}; + +export const demoListMock : Demo[] = [{ + name: 'Name 1', + gender: 'Gender 1', + company: 'Company 1' +}]; diff --git a/src/main/js/app/model/problemdetail.mock.ts b/src/main/js/app/model/problemdetail.mock.ts new file mode 100644 index 0000000..18ccab5 --- /dev/null +++ b/src/main/js/app/model/problemdetail.mock.ts @@ -0,0 +1,5 @@ +import {ProblemDetail} from './problemdetail.model'; + +export const problemdetailMock : ProblemDetail = { + todo: 'TODO' +} diff --git a/src/main/js/app/providers/german-date.provider.spec.ts b/src/main/js/app/providers/german-date.provider.spec.ts new file mode 100644 index 0000000..95042c4 --- /dev/null +++ b/src/main/js/app/providers/german-date.provider.spec.ts @@ -0,0 +1,77 @@ +import {TestBed} from '@angular/core/testing'; +import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core'; +import {provideGermanDate} from './german-date.provider'; +import {GermanDateAdapter} from './german-date.provider'; + +describe('GermanDateAdapter', () => { + let adapter: GermanDateAdapter; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: provideGermanDate(), + }); + + adapter = TestBed.inject(DateAdapter) as GermanDateAdapter; + }); + + describe('parse', () => { + it('should parse a valid German date string', () => { + const date = adapter.parse('25.12.2024'); + expect(date).toEqual(new Date(2024, 11, 25)); // Months are 0-indexed in JavaScript + }); + + it('should return null for an invalid German date string', () => { + const date = adapter.parse('31.02.2024'); // Invalid date + expect(date).toBeNull(); + }); + + it('should parse a timestamp', () => { + const timestamp = new Date(2024, 11, 25).getTime(); + const date = adapter.parse(timestamp); + expect(date).toEqual(new Date(2024, 11, 25)); + }); + + it('should return null for an invalid value', () => { + const date = adapter.parse('invalid-date'); + expect(date).toBeNull(); + }); + }); + + describe('format', () => { + it('should format a date into German format', () => { + const date = new Date(2024, 11, 25); // December 25, 2024 + const formatted = adapter.format(date, {}); + expect(formatted).toBe('25.12.2024'); + }); + }); +}); + +describe('provideGermanDate', () => { + it('should provide the correct providers', () => { + const providers = provideGermanDate(); // This is an array of providers + const matDateLocaleProvider = providers.find( + (p): p is { provide: typeof MAT_DATE_LOCALE; useValue: string } => + (p as any).provide === MAT_DATE_LOCALE + ); + const dateAdapterProvider = providers.find( + (p): p is { provide: typeof DateAdapter; useClass: typeof GermanDateAdapter } => + (p as any).provide === DateAdapter + ); + const matDateFormatsProvider = providers.find( + (p): p is { provide: typeof MAT_DATE_FORMATS; useValue: any } => + (p as any).provide === MAT_DATE_FORMATS + ); + + expect(matDateLocaleProvider?.useValue).toBe('de-DE'); + expect(dateAdapterProvider?.useClass).toBe(GermanDateAdapter); + expect(matDateFormatsProvider?.useValue).toEqual({ + parse: { dateInput: ['dd.MM.yyyy'] }, + display: { + dateInput: 'dd.MM.yyyy', + monthYearLabel: 'DD.MM.yyyy', + dateA11yLabel: 'LL', + monthYearA11yLabel: 'MMMM yyyy', + }, + }); + }); +}); diff --git a/src/main/js/app/providers/german-date.provider.ts b/src/main/js/app/providers/german-date.provider.ts index 37f1ce3..b24a5b3 100644 --- a/src/main/js/app/providers/german-date.provider.ts +++ b/src/main/js/app/providers/german-date.provider.ts @@ -2,7 +2,7 @@ import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, NativeDateAdapter} from import {Provider} from '@angular/core'; import moment from 'moment'; -class GermanDateAdapter extends NativeDateAdapter { +export class GermanDateAdapter extends NativeDateAdapter { override parse(value: any): Date | null { if (typeof value === 'string' && value.indexOf('.') > -1) { const parsedDate = moment(value, 'DD.MM.YYYY', true); diff --git a/src/main/js/app/store/demo/demo.action.spec.ts b/src/main/js/app/store/demo/demo.action.spec.ts new file mode 100644 index 0000000..cd92399 --- /dev/null +++ b/src/main/js/app/store/demo/demo.action.spec.ts @@ -0,0 +1,29 @@ +import { searchDemosAction, searchDemosActionSuccess, searchDemosActionFail, DemoActionTypes } from './demo.actions'; +import {demoFilterMock, demoListMock} from '../../model/demo.mock'; +import {problemdetailMock} from '../../model/problemdetail.mock'; + +describe('Demo Actions', () => { + it('should create the SEARCH_DEMOS action with the correct payload', () => { + const filter = demoFilterMock; + const action = searchDemosAction({ filter }); + + expect(action.type).toBe(DemoActionTypes.SEARCH_DEMOS); + expect(action.filter).toEqual(filter); + }); + + it('should create the SEARCH_DEMOS_SUCCESS action with the correct payload', () => { + const demoList = demoListMock; + const action = searchDemosActionSuccess({ demoList }); + + expect(action.type).toBe(DemoActionTypes.SEARCH_DEMOS_SUCCESS); + expect(action.demoList).toEqual(demoList); + }); + + it('should create the SEARCH_DEMOS_FAIL action with the correct payload', () => { + const error = problemdetailMock; + const action = searchDemosActionFail({ error }); + + expect(action.type).toBe(DemoActionTypes.SEARCH_DEMOS_FAIL); + expect(action.error).toEqual(error); + }); +});