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);
+ });
+});