Enhancement 530168 - Dialog "create/edit" notification: Create possibility to remove an date. +
Test refactoring
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index a96c64d..5cfdafe 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -58,6 +58,7 @@
 import { HttpResponseInterceptorService } from './services/http-response-interceptor.service';
 import { MessageBannerComponent } from './common-components/message-banner/message-banner.component';
 import { LogoutPageComponent } from './pages/logout/logout.component';
+import { RemoveButtonComponent } from './common-components/remove-button/remove-button.component';
 
 @NgModule({
   declarations: [
@@ -93,7 +94,8 @@
     SortingComponent,
     FileImportComponent,
     MessageBannerComponent,
-    LogoutPageComponent      
+    LogoutPageComponent,
+    RemoveButtonComponent      
   ],
   imports: [
     BrowserAnimationsModule,
diff --git a/src/app/common-components/remove-button/remove-button.component.css b/src/app/common-components/remove-button/remove-button.component.css
new file mode 100644
index 0000000..7746397
--- /dev/null
+++ b/src/app/common-components/remove-button/remove-button.component.css
@@ -0,0 +1,7 @@
+.remove-btn {
+    vertical-align: middle;
+}
+
+.remove-btn:hover{
+    cursor: pointer;
+  }    
diff --git a/src/app/common-components/remove-button/remove-button.component.html b/src/app/common-components/remove-button/remove-button.component.html
new file mode 100644
index 0000000..b2b3ad7
--- /dev/null
+++ b/src/app/common-components/remove-button/remove-button.component.html
@@ -0,0 +1 @@
+<i *ngIf="nullableAttribute" class="glyphicon glyphicon-remove remove-btn" (click)="clear()"></i>
diff --git a/src/app/common-components/remove-button/remove-button.component.spec.ts b/src/app/common-components/remove-button/remove-button.component.spec.ts
new file mode 100644
index 0000000..b5981f4
--- /dev/null
+++ b/src/app/common-components/remove-button/remove-button.component.spec.ts
@@ -0,0 +1,36 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RemoveButtonComponent } from './remove-button.component';
+
+describe('RemoveButtonComponent', () => {
+  let component: RemoveButtonComponent;
+  let fixture: ComponentFixture<RemoveButtonComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ RemoveButtonComponent ],
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(RemoveButtonComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  fit('should set the bound model to null', async(() => {
+    let emit = false;
+    expect(component).toBeTruthy();
+    fixture.detectChanges();
+    component.nullableAttribute = 'INIT TEXT';
+    component.nullableAttributeChange.subscribe( changedText => emit = ( changedText === null));
+
+    component.clear();
+
+    fixture.whenStable().then( () => {
+      expect( emit ).toBeTruthy();
+
+    });
+  }));
+});
diff --git a/src/app/common-components/remove-button/remove-button.component.ts b/src/app/common-components/remove-button/remove-button.component.ts
new file mode 100644
index 0000000..1adf9bc
--- /dev/null
+++ b/src/app/common-components/remove-button/remove-button.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit, Input, Output, EventEmitter  } from '@angular/core';
+
+@Component({
+  selector: 'app-remove-button',
+  templateUrl: './remove-button.component.html',
+  styleUrls: ['./remove-button.component.css']
+})
+export class RemoveButtonComponent implements OnInit {
+  @Input()
+  public nullableAttribute: any;
+
+  @Output()
+  public nullableAttributeChange: EventEmitter<any> = new EventEmitter<any>();
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+  public clear() {
+    this.nullableAttribute = null;
+    this.nullableAttributeChange.emit(this.nullableAttribute);
+  }
+
+}
diff --git a/src/app/dialogs/entry/entry.component.css b/src/app/dialogs/entry/entry.component.css
index 3d64af2..2732be4 100644
--- a/src/app/dialogs/entry/entry.component.css
+++ b/src/app/dialogs/entry/entry.component.css
@@ -11,6 +11,7 @@
 .dateRangePickerIcon:hover{
   cursor: pointer;
 }
+
 input{
   min-width: 200px;
 }
\ No newline at end of file
diff --git a/src/app/dialogs/entry/entry.component.html b/src/app/dialogs/entry/entry.component.html
index 5c68ad2..116d91a 100644
--- a/src/app/dialogs/entry/entry.component.html
+++ b/src/app/dialogs/entry/entry.component.html
@@ -126,6 +126,7 @@
                   <input id="expectedFinishDateFormControl" [disabled]="isReadOnlyDialog" class="form-control entry-input" *ngIf="!notification.expectedFinishDate"
                     type="text" daterangepicker (applyDaterangepicker)="notification.expectedFinishDate=$event.picker.startDate "
                     [options]="{ autoUpdateInput: false, singleDatePicker: true, parentEl: 'md-dialog-container' }" />
+                  <app-remove-button [(nullableAttribute)]="notification.expectedFinishDate" class="removeBtn" *ngIf="!isReadOnlyDialog"></app-remove-button>
                 </div>
               </td>
             </tr>
@@ -168,6 +169,7 @@
                   <input name="reminderDateFormControl" id="reminderDateFormControl" [disabled]="isReadOnlyDialog" class="form-control entry-input" *ngIf="!notification.reminderDate"
                     type="text" daterangepicker (applyDaterangepicker)="notification.reminderDate=$event.picker.startDate"
                     [options]="{ autoUpdateInput: false, singleDatePicker: true, parentEl: 'md-dialog-container' }" />
+                    <app-remove-button [(nullableAttribute)]="notification.reminderDate" class="entry-input" *ngIf="!isReadOnlyDialog"></app-remove-button>
                 </div>
               </td>
               <td style="width: 2%"></td>
diff --git a/src/app/dialogs/entry/entry.component.spec.ts b/src/app/dialogs/entry/entry.component.spec.ts
index 45e4b56..d259917 100644
--- a/src/app/dialogs/entry/entry.component.spec.ts
+++ b/src/app/dialogs/entry/entry.component.spec.ts
@@ -2,7 +2,7 @@
 import { FormsModule } from '@angular/forms';
 import { async, fakeAsync, ComponentFixture, TestBed, tick, inject } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
-import { Injectable, DebugElement } from '@angular/core';
+import { Injectable, DebugElement, Component } from '@angular/core';
 import { click, newEvent } from '../../testing';
 import { DaterangepickerConfig, Daterangepicker } from 'ng2-daterangepicker';
 import { AbstractMockObservableService } from '../../common/abstract-mock-observable.service';
@@ -27,6 +27,23 @@
 import { FILTER_MATRIX_UNIQUE_GRIDTERRITORY } from '../../test-data/filter-matrix';
 
 import { MessageService } from '../../services/message.service';
+
+
+export class EntryComponentMocker {
+  public static getComponentMocks() {
+    return [
+      MockComponent({ selector: 'app-entry' }),      
+      MockComponent({ selector: 'app-remove-button', inputs: ['nullableAttribute'], outputs: ['nullableAttribute'] }),
+      MockComponent({
+        selector: 'app-autocomplete',
+        inputs: ['responsibilityForwarding'],
+        outputs: ['responsibilityForwarding']
+      }),
+    ];
+
+  }
+}
+
 describe('EntryComponent', () => {
 let component: EntryComponent;
 let fixture: ComponentFixture<EntryComponent>;
@@ -74,6 +91,11 @@
           selector: 'app-autocomplete',
           inputs: ['responsibilityForwarding'],
           outputs: ['responsibilityForwarding']
+        }),
+        MockComponent({ 
+          selector: 'app-remove-button',
+          inputs: ['nullableAttribute'],
+          outputs: ['nullableAttribute']
         })
       ],
       providers: [
diff --git a/src/app/dialogs/shift-change-protocol/shift-change-protocol.component.spec.ts b/src/app/dialogs/shift-change-protocol/shift-change-protocol.component.spec.ts
index b74812d..ed5c95f 100644
--- a/src/app/dialogs/shift-change-protocol/shift-change-protocol.component.spec.ts
+++ b/src/app/dialogs/shift-change-protocol/shift-change-protocol.component.spec.ts
@@ -24,9 +24,11 @@
 import { BannerMessage } from '../../common/banner-message';
 import { BannerMessageStatusEn } from '../../common/enums';
 import { EntryComponent } from '../../dialogs/entry/entry.component';
+import { EntryComponentMocker } from '../../dialogs/entry/entry.component.spec';
 import { DaterangepickerConfig } from 'ng2-daterangepicker';
 import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
 import { FormattedTimestampPipe } from '../../common-components/pipes/formatted-timestamp.pipe';
+import { FutureNotificationsMocker } from '../../lists/future-notifications/future-notifications.component.spec';
 
 @NgModule({
   declarations: [EntryComponent, ShiftChangeProtocolComponent],
@@ -103,16 +105,11 @@
         ShiftChangeProtocolComponent,
         EntryComponent,
         MockComponent({ selector: 'input', inputs: ['options'] }),
-        MockComponent({ selector: 'app-entry' }),
+        EntryComponentMocker.getComponentMocks(),
         MockComponent({
           selector: 'app-message-banner'
         }),
         MockComponent({
-          selector: 'app-autocomplete',
-          inputs: ['responsibilityForwarding'],
-          outputs: ['responsibilityForwarding']
-        }),
-        MockComponent({
           selector: 'app-responsibility',
           inputs: [
             'responsiblitySelection',
@@ -120,18 +117,7 @@
             'withEditButtons',
             'isCollapsible']
         }),
-        MockComponent({
-          selector: 'app-future-notifications',
-          inputs: [
-            'responsiblitySelection',
-            'withCheckboxes',
-            'withEditButtons',
-            'isCollapsible',
-            'stayHidden',
-            'enforceShowReadOnly',
-            'gridId'
-          ]
-        }),
+        FutureNotificationsMocker.getComponentMocks(),
         MockComponent({
           selector: 'app-open-notifications',
           inputs: [
@@ -155,7 +141,8 @@
             'enforceShowReadOnly',
             'gridId'
           ]
-        })],
+        }),
+      ],
       providers: [
         { provide: MdDialogRef, useClass: MockDialogRef },
         { provide: Overlay, useClass: Overlay },
diff --git a/src/app/dialogs/shift-change/shift-change.component.spec.ts b/src/app/dialogs/shift-change/shift-change.component.spec.ts
index 5e37623..b0b2337 100644
--- a/src/app/dialogs/shift-change/shift-change.component.spec.ts
+++ b/src/app/dialogs/shift-change/shift-change.component.spec.ts
@@ -56,7 +56,8 @@
     TestBed.configureTestingModule({
       imports: [FormsModule],
       declarations: [ShiftChangeComponent,
-        MockComponent({ selector: 'multiselect', inputs: ['data', 'settings'] })],
+        MockComponent({ selector: 'multiselect', inputs: ['data', 'settings'] })
+      ],
       providers: [
       { provide: MdDialogRef, useClass: MockDialogRef },
       { provide: UserService, useValue: mockUserService },
diff --git a/src/app/filter/filter.component.spec.ts b/src/app/filter/filter.component.spec.ts
index eabedfa..3ae234c 100644
--- a/src/app/filter/filter.component.spec.ts
+++ b/src/app/filter/filter.component.spec.ts
@@ -15,6 +15,14 @@
 import { MessageService } from '../services/message.service';
 import { FilterMatrix } from '../model/controller-model/filter-matrix';
 
+export class FilterMocker {
+  public static getComponentMocks() {
+    return [
+      MockComponent({ selector: 'app-filter', inputs: ['shiftChangeProtocolConfirmed', 
+      'shiftChangeProtocolOpened', 'filterExpanded'] })     
+    ];
+  }
+}
 
 describe('FilterComponent', () => {
   let component: FilterComponent;
diff --git a/src/app/lists/abstract-list/abstract-list.component.spec.ts b/src/app/lists/abstract-list/abstract-list.component.spec.ts
index 877f59a..fabd5a7 100644
--- a/src/app/lists/abstract-list/abstract-list.component.spec.ts
+++ b/src/app/lists/abstract-list/abstract-list.component.spec.ts
@@ -24,6 +24,17 @@
 import { ResponsibilityService } from '../../services/responsibility.service';
 import { MessageService } from '../../services/message.service';
 
+
+export class AbstractListMocker {
+  public static getComponentMocks() {
+    return [
+        MockComponent({
+          selector: 'app-abstract-list', 
+          inputs: [ 'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
+        })      
+    ];
+  }
+}
 describe('AbstractListComponent', () => {
   let component: AbstractListComponent;
   let fixture: ComponentFixture<AbstractListComponent>;
diff --git a/src/app/lists/current-reminders/current-reminders.component.spec.ts b/src/app/lists/current-reminders/current-reminders.component.spec.ts
index 6141727..04e165d 100644
--- a/src/app/lists/current-reminders/current-reminders.component.spec.ts
+++ b/src/app/lists/current-reminders/current-reminders.component.spec.ts
@@ -24,6 +24,7 @@
 import { FILTER_MATRIX_NONE_SELECTED } from '../../test-data/filter-matrix';
 import { FILTER_MATRIX_ALL_SELECTED } from '../../test-data/filter-matrix';
 import { LoadingSpinnerComponent } from '../../dialogs/loading-spinner/loading-spinner.component';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
 
 describe('CurrentRemindersComponent', () => {
   let component: CurrentRemindersComponent;
@@ -62,7 +63,7 @@
         CurrentRemindersComponent, StringToDatePipe,
         FormattedTimestampPipe,
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']})
+        SortingComponentMocker.getComponentMocks(),
       ],
       providers: [
         { provide: ReminderService, useValue: mockReminderService },
diff --git a/src/app/lists/finished-notifications/finished-notifications.component.spec.ts b/src/app/lists/finished-notifications/finished-notifications.component.spec.ts
index 547d18b..0ef146a 100644
--- a/src/app/lists/finished-notifications/finished-notifications.component.spec.ts
+++ b/src/app/lists/finished-notifications/finished-notifications.component.spec.ts
@@ -27,6 +27,20 @@
 import { Globals } from '../../common/globals';
 import { DateRange } from '../../model/date-range';
 import { LoadingSpinnerComponent } from '../../dialogs/loading-spinner/loading-spinner.component';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
+
+export class FinishedNotificationsMocker {
+  public static getComponentMocks() {
+    return [
+        MockComponent({
+          selector: 'app-finished-notifications', inputs: [ 'responsiblitySelection',
+            'withCheckboxes', 'withEditButtons', 'isCollapsible', 
+            'stayHidden', 'gridId', 'enforceShowReadOnly', 'shiftChangeTransactionId',
+            'withDatePicker']
+        })      
+    ];
+  }
+}
 
 describe('FinishedNotificationsComponent', () => {
   let component: FinishedNotificationsComponent;
@@ -68,7 +82,7 @@
         FormattedDatePipe,
         FormattedTimestampPipe,
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({ selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState'] }),
+        SortingComponentMocker.getComponentMocks(),
         MockComponent({ selector: 'input', inputs: ['options'] })
       ],
       providers: [
diff --git a/src/app/lists/future-notifications/future-notifications.component.spec.ts b/src/app/lists/future-notifications/future-notifications.component.spec.ts
index ac1afa9..eafdecb 100644
--- a/src/app/lists/future-notifications/future-notifications.component.spec.ts
+++ b/src/app/lists/future-notifications/future-notifications.component.spec.ts
@@ -26,7 +26,29 @@
 import { Globals } from '../../common/globals';
 import { DateRange } from '../../model/date-range';
 import { LoadingSpinnerComponent } from '../../dialogs/loading-spinner/loading-spinner.component';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
 
+export class FutureNotificationsMocker {
+  public static getComponentMocks() {
+    return [
+      MockComponent({
+        selector: 'app-future-notifications',
+        inputs: [
+          'responsiblitySelection',
+          'withCheckboxes',
+          'withEditButtons',
+          'isCollapsible',
+          'stayHidden',
+          'enforceShowReadOnly',
+          'gridId',
+          'shiftChangeTransactionId',
+          'withDatePicker'
+        ]
+      }),      
+    ];
+
+  }
+}
 
 describe('FutureNotificationsComponent', () => {
   let component: FutureNotificationsComponent;
@@ -67,7 +89,7 @@
         FormattedDatePipe,
         FormattedTimestampPipe,
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({ selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState'] }),
+        SortingComponentMocker.getComponentMocks(),
         MockComponent({ selector: 'input', inputs: ['options'] })
       ],
       providers: [
diff --git a/src/app/lists/open-notifications/open-notifications.component.spec.ts b/src/app/lists/open-notifications/open-notifications.component.spec.ts
index 6d0e432..8fe1864 100644
--- a/src/app/lists/open-notifications/open-notifications.component.spec.ts
+++ b/src/app/lists/open-notifications/open-notifications.component.spec.ts
@@ -23,6 +23,33 @@
 import { MessageService } from '../../services/message.service';
 import { LoadingSpinnerComponent } from '../../dialogs/loading-spinner/loading-spinner.component';
 import { StatusEn } from '../../common/enums';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
+
+export class OpenNotificationsMocker {
+  public static getComponentMocks(sortingYN: boolean = false) {
+    const ret: any[] =  [
+      MockComponent({
+        selector: 'app-open-notifications',
+        inputs: [
+          'responsiblitySelection',
+          'withCheckboxes',
+          'withEditButtons',
+          'isCollapsible',
+          'stayHidden',
+          'enforceShowReadOnly',
+          'gridId',
+          'shiftChangeTransactionId',
+          'withDatePicker'          
+        ]
+      }), 
+          
+    ];
+    if ( sortingYN ) {
+      ret.push(SortingComponentMocker.getComponentMocks());
+    }
+    return ret;
+  }
+}
 
 describe('OpenNotificationsComponent', () => {
   let component: OpenNotificationsComponent;
@@ -63,8 +90,7 @@
         StringToDatePipe,
         FormattedTimestampPipe,
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({ selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState'] })
-
+        SortingComponentMocker.getComponentMocks(),
       ],
       providers: [
         { provide: ReminderService, useValue: mockService },
diff --git a/src/app/lists/search-result-list/search-result-list.component.spec.ts b/src/app/lists/search-result-list/search-result-list.component.spec.ts
index 6ab7638..353ec64 100644
--- a/src/app/lists/search-result-list/search-result-list.component.spec.ts
+++ b/src/app/lists/search-result-list/search-result-list.component.spec.ts
@@ -27,6 +27,7 @@
 import { BRANCHES } from '../../test-data/branches';
 import { GRIDTERRITORIES } from '../../test-data/gridterritories';
 import { STATUSES } from '../../test-data/statuses';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
 
 describe('SearchResultListComponent', () => {
   let component: SearchResultListComponent;
@@ -64,7 +65,7 @@
         SearchResultListComponent,
         StringToDatePipe,
         FormattedTimestampPipe,
-        MockComponent({ selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState'] }),
+        SortingComponentMocker.getComponentMocks(),
         MockComponent({ selector: 'app-loading-spinner' })
       ],
       providers: [
diff --git a/src/app/lists/sorting/sorting.component.spec.ts b/src/app/lists/sorting/sorting.component.spec.ts
index e69de29..e925899 100644
--- a/src/app/lists/sorting/sorting.component.spec.ts
+++ b/src/app/lists/sorting/sorting.component.spec.ts
@@ -0,0 +1,12 @@
+import { MockComponent } from '../../testing/mock.component';
+
+export class SortingComponentMocker {
+    public static getComponentMocks() {
+      return [
+        MockComponent({
+            selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']
+          })
+      ];
+  
+    }
+  }
\ No newline at end of file
diff --git a/src/app/pages/overview/overview.component.spec.ts b/src/app/pages/overview/overview.component.spec.ts
index bb3e688..92140aa 100644
--- a/src/app/pages/overview/overview.component.spec.ts
+++ b/src/app/pages/overview/overview.component.spec.ts
@@ -6,6 +6,7 @@
 import { DebugElement, EventEmitter } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import { EntryComponent } from '../../dialogs/entry/entry.component';
+import { EntryComponentMocker } from '../../dialogs/entry/entry.component.spec';
 import { MainNavigationComponent } from '../../common-components/main-navigation/main-navigation.component';
 import { ShiftChangeProtocolComponent } from '../../dialogs/shift-change-protocol/shift-change-protocol.component';
 import { AbstractListComponent } from '../../lists/abstract-list/abstract-list.component';
@@ -35,6 +36,12 @@
 import { OPEN_NOTIFICATIONS } from '../../test-data/notifications';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { MessageService } from '../../services/message.service';
+import { FutureNotificationsMocker } from '../../lists/future-notifications/future-notifications.component.spec';
+import { OpenNotificationsMocker } from '../../lists/open-notifications/open-notifications.component.spec';
+import { FinishedNotificationsMocker } from '../../lists/finished-notifications/finished-notifications.component.spec';
+import { AbstractListMocker } from '../../lists/abstract-list/abstract-list.component.spec';
+import { FilterMocker } from '../../filter/filter.component.spec';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
 
 class FakeRouter {
   navigate(commands: any[]) {
@@ -127,46 +134,20 @@
         MainNavigationComponent,
         ShiftChangeProtocolComponent,
         MockComponent({ selector: 'app-reminder-caller-job-component' }),        
-        MockComponent({ selector: 'app-entry' }),
-        MockComponent({ selector: 'app-filter', inputs: ['shiftChangeProtocolConfirmed', 
-                      'shiftChangeProtocolOpened', 'filterExpanded'] }),
+        EntryComponentMocker.getComponentMocks(),
+        FilterMocker.getComponentMocks(),
         MockComponent({ selector: 'input', inputs: ['options'] }),
-        MockComponent({
-          selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']
-        }),
-        MockComponent({
-          selector: 'app-abstract-list', inputs: [
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-finished-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-open-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-future-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-
+        AbstractListMocker.getComponentMocks(),
+        OpenNotificationsMocker.getComponentMocks(true),
+        FinishedNotificationsMocker.getComponentMocks(),
+        FutureNotificationsMocker.getComponentMocks(),
         // TODO: the following are only needed because we do not mock away "ShiftChangeProtocolComponent"
         MockComponent({
-          selector: 'app-current-information', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible']
-        }),
-        MockComponent({
           selector: 'app-responsibility', inputs: [
             'responsiblitySelection']
         }),
         MockComponent({
-          selector: 'app-autocomplete',
-                        inputs: ['responsibilityForwarding'], 
-          outputs: ['responsibilityForwarding']
-        }),
-        MockComponent({
-          selector: 'app-message-banner'})
+          selector: 'app-message-banner'}),
       ],
       providers: [
         { provide: NotificationService, useValue: mockNotificationService },
diff --git a/src/app/pages/reminder/reminder.component.spec.ts b/src/app/pages/reminder/reminder.component.spec.ts
index 09a4317..58317be 100644
--- a/src/app/pages/reminder/reminder.component.spec.ts
+++ b/src/app/pages/reminder/reminder.component.spec.ts
@@ -21,6 +21,7 @@
 import { REMINDER_NOTIFICATIONS } from '../../test-data/reminder-notifications';
 import { AppModule } from '../../app.module';
 import { EntryComponent } from '../../dialogs/entry/entry.component';
+import { EntryComponentMocker } from '../../dialogs/entry/entry.component.spec';
 import { MainNavigationComponent } from '../../common-components/main-navigation/main-navigation.component';
 import { CurrentRemindersComponent } from '../../lists/current-reminders/current-reminders.component';
 import { ReminderComponent } from './reminder.component';
@@ -30,6 +31,11 @@
 import { ShiftChangeProtocolComponent } from '../../dialogs/shift-change-protocol/shift-change-protocol.component';
 import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
 import { FilterComponent } from '../../filter/filter.component';
+import { FutureNotificationsMocker } from 'app/lists/future-notifications/future-notifications.component.spec';
+import { OpenNotificationsMocker } from 'app/lists/open-notifications/open-notifications.component.spec';
+import { FinishedNotificationsMocker } from 'app/lists/finished-notifications/finished-notifications.component.spec';
+import { AbstractListMocker } from 'app/lists/abstract-list/abstract-list.component.spec';
+import { SortingComponentMocker } from 'app/lists/sorting/sorting.component.spec';
 
 class FakeRouter {
   navigate(commands: any[]) {
@@ -150,7 +156,7 @@
           ]
         }),
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({ selector: 'app-entry' }),
+        EntryComponentMocker.getComponentMocks(),
         MockComponent({ selector: 'input', inputs: ['options'] }),
         MockComponent({
           selector: 'app-reminder',
@@ -162,33 +168,13 @@
           selector: 'app-responsibility', inputs: [
             'responsiblitySelection']
         }),
-        MockComponent({
-          selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']
-        }),
-        MockComponent({
-          selector: 'app-autocomplete',
-          inputs: ['responsibilityForwarding'],
-          outputs: ['responsibilityForwarding']
-        }),
-        MockComponent({
-          selector: 'app-abstract-list', inputs: [
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-finished-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-open-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-future-notifications', inputs: [ 'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
+        AbstractListMocker.getComponentMocks(),
+        FinishedNotificationsMocker.getComponentMocks(),
+        OpenNotificationsMocker.getComponentMocks(true),
+        FutureNotificationsMocker.getComponentMocks(),
         MockComponent({
           selector: 'app-message-banner'
-        })
+        }),
       ],
       providers: [
         { provide: Router, useValue: router },
diff --git a/src/app/pages/search/search.component.spec.ts b/src/app/pages/search/search.component.spec.ts
index a5ad5aa..2ddd98f 100644
--- a/src/app/pages/search/search.component.spec.ts
+++ b/src/app/pages/search/search.component.spec.ts
@@ -41,6 +41,11 @@
 import { ResponsibilityService } from '../../services/responsibility.service';
 import { ShiftChangeProtocolComponent } from '../../dialogs/shift-change-protocol/shift-change-protocol.component';
 import { USERS } from '../../test-data/users';
+import { FutureNotificationsMocker } from '../../lists/future-notifications/future-notifications.component.spec';
+import { OpenNotificationsMocker } from '../../lists/open-notifications/open-notifications.component.spec';
+import { FinishedNotificationsMocker } from '../../lists/finished-notifications/finished-notifications.component.spec';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
+import { AbstractListMocker } from '../../lists/abstract-list/abstract-list.component.spec';
 
 class FakeRouter {
   navigate(commands: any[]) {
@@ -153,30 +158,18 @@
           selector: 'app-responsibility', inputs: [
             'responsiblitySelection']
         }),
-        MockComponent({ selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState'] }),
         MockComponent({ selector: 'input', inputs: ['options'] }),
         MockComponent({ selector: 'app-search', inputs: ['withCheckboxes', 'withEditButtons', 'isCollapsible'] }),
         MockComponent({ selector: 'app-autocomplete', inputs: ['responsibilityForwarding'], outputs: ['responsibilityForwarding'] }),
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({
-          selector: 'app-abstract-list', inputs: [
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-finished-notifications', inputs: ['responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-open-notifications', inputs: ['responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-future-notifications', inputs: ['responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
+        AbstractListMocker.getComponentMocks(),
+        FinishedNotificationsMocker.getComponentMocks(),
+        OpenNotificationsMocker.getComponentMocks(true),
+        FutureNotificationsMocker.getComponentMocks(),
         MockComponent({
           selector: 'app-message-banner'
-        })
+        }),
+        MockComponent({ selector: 'app-remove-button', inputs: ['nullableAttribute'], outputs: ['nullableAttribute'] })        
       ],
       providers: [
         { provide: Router, useValue: routerStub },
diff --git a/src/app/pages/shift-change-overview/shift-change-overview.component.spec.ts b/src/app/pages/shift-change-overview/shift-change-overview.component.spec.ts
index e5b72c2..88d9968 100644
--- a/src/app/pages/shift-change-overview/shift-change-overview.component.spec.ts
+++ b/src/app/pages/shift-change-overview/shift-change-overview.component.spec.ts
@@ -20,11 +20,17 @@
 import { ResponsibilityService } from '../../services/responsibility.service';
 import { MessageService } from '../../services/message.service';
 import { EntryComponent } from '../../dialogs/entry/entry.component';
+import { EntryComponentMocker } from '../../dialogs/entry/entry.component.spec';
 import { MainNavigationComponent } from '../../common-components/main-navigation/main-navigation.component';
 import { ShiftChangeOverviewComponent } from './shift-change-overview.component';
 import { RESPONSIBILITIES_SHIFT_CHANGE } from '../../test-data/responsibilities';
 import { HISTORICAL_SCHIFTCHANGES } from '../../test-data/historical-shiftchanges';
 import { USERS } from '../../test-data/users';
+import { FutureNotificationsMocker } from '../../lists/future-notifications/future-notifications.component.spec';
+import { OpenNotificationsMocker } from '../../lists/open-notifications/open-notifications.component.spec';
+import { FinishedNotificationsMocker } from '../../lists/finished-notifications/finished-notifications.component.spec';
+import { SortingComponentMocker } from '../../lists/sorting/sorting.component.spec';
+import { AbstractListMocker } from '../../lists/abstract-list/abstract-list.component.spec';
 
 class FakeRouter {
   navigate(commands: any[]) {
@@ -121,47 +127,21 @@
         FormattedTimestampPipe,
         StringToDatePipe,
         MockComponent({ selector: 'app-loading-spinner' }),
-        MockComponent({ selector: 'app-entry' }),
-        MockComponent({ selector: 'input', inputs: ['options'] }),
+
         MockComponent({ selector: 'app-historical-shift-changes' }),
         MockComponent({
           selector: 'app-responsibility', 
           inputs: ['withButtons', 'withNames', 'responsiblitySelection']
         }),
-        MockComponent({
-          selector: 'app-sorting', inputs: ['columnName', 'initColumnName', 'isDesc', 'defaultState']
-        }),
-        MockComponent({
-          selector: 'app-autocomplete',
-          inputs: ['responsibilityForwarding'],
-          outputs: ['responsibilityForwarding']
-        }),
-        MockComponent({
-          selector: 'app-abstract-list', inputs: [
-            'withCheckboxes', 'withEditButtons', 'isCollapsible', 'stayHidden', 'gridId', 'enforceShowReadOnly']
-        }),
-        MockComponent({
-          selector: 'app-finished-notifications', inputs: [ 
-            'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'withDatePicker', 'isCollapsible', 'stayHidden', 
-            'gridId', 'enforceShowReadOnly', 'shiftChangeTransactionId'
-          ]
-        }),
-        MockComponent({
-          selector: 'app-open-notifications', inputs: [ 
-            'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'withDatePicker', 'isCollapsible', 'stayHidden', 
-            'gridId', 'enforceShowReadOnly', 'shiftChangeTransactionId']
-        }),
-        MockComponent({
-          selector: 'app-future-notifications', inputs: [ 
-            'responsiblitySelection',
-            'withCheckboxes', 'withEditButtons', 'withDatePicker', 'isCollapsible', 'stayHidden', 
-            'gridId', 'enforceShowReadOnly', 'shiftChangeTransactionId']
-        }),
+        AbstractListMocker.getComponentMocks(),
+        MockComponent({ selector: 'input', inputs: ['options'] }),           
+        FinishedNotificationsMocker.getComponentMocks(),
+        OpenNotificationsMocker.getComponentMocks(true),
+        FutureNotificationsMocker.getComponentMocks(),
         MockComponent({
           selector: 'app-message-banner'
-        })
+        }),
+        EntryComponentMocker.getComponentMocks()
       ],
       providers: [
         { provide: Router, useValue: routerStub },
diff --git a/src/styles.css b/src/styles.css
index 76f5b5e..66c4a6c 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -163,6 +163,7 @@
 
 .input-group {
     width: 100%;
+    white-space: nowrap;
 }
 
 .entry-input {