Merge branch 'DEVELOP_FE' of ssh://git.eclipse.org:29418/elogbook/elogbookFE into DEVELOP_FE
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index 5aaaddb..ab3bc79 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -1,30 +1,116 @@
 /* tslint:disable:no-unused-variable */
 
 import { TestBed, async } from '@angular/core/testing';
+import { MockComponent } from './testing/mock.component';
 import { AppComponent } from './app.component';
+import { Http, Response } from '@angular/http';
+import { Router, ActivatedRoute } from '@angular/router';
+import { BaseDataLoaderService } from './services/jobs/base-data-loader.service';
+import { HttpResponseInterceptorService } from './services/http-response-interceptor.service';
+import { SessionContext } from './common/session-context';
+import { MessageService } from './services/message.service';
+import { ReminderCallerJobService } from './services/jobs/reminder-caller-job.service';
+import { ImportFileCallerService } from './services/jobs/import-file-caller.service';
+import { AbstractMockObservableService } from './common/abstract-mock-observable.service';
+
+class FakeRouter {
+  navigate(commands: any[]) {
+    return commands[0];
+  }
+}
+
+class MockHttp extends AbstractMockObservableService {
+  get() {
+    return this;
+  }
+}
+
+class MockHttpRes {
+  public content: any;
+  json() { return this.content; }
+}
 
 describe('AppComponent', () => {
+  let router: Router;
+  const mockService = new MockHttp();
+  let sessionContext: SessionContext;
+
   beforeEach(() => {
+    router = new FakeRouter() as any as Router;
+    sessionContext = new SessionContext();    
+
     TestBed.configureTestingModule({
       declarations: [
-        AppComponent
+        AppComponent,
+        MockComponent({selector: 'app-main-navigation'}),
+        MockComponent({selector: 'app-message-banner'}),
+        MockComponent({selector: 'router-outlet'})
       ],
+      providers: [
+        { provide: Http, useValue: mockService },
+        { provide: Router, useValue: router },
+        { provide: BaseDataLoaderService, useValue: {} },
+        { provide: ActivatedRoute },    
+        { provide: HttpResponseInterceptorService },    
+        { provide: SessionContext, useValue: sessionContext },
+        { provide: MessageService },
+        { provide: ReminderCallerJobService },
+        { provide: ImportFileCallerService }
+      ],      
     });
     TestBed.compileComponents();
+
+    const httpRes = new MockHttpRes();
+    httpRes.content = {};
+    mockService.content = httpRes;
+    
+
   });
-/*
+
+  
+
   it('should create the app', async(() => {
-    const fixture = TestBed.createComponent(AppComponent);
+    const fixture = TestBed.createComponent(AppComponent);    
     const app = fixture.debugElement.componentInstance;
     expect(app).toBeTruthy();
   }));
 
-  it(`should have as title 'app works!'`, async(() => {
-    const fixture = TestBed.createComponent(AppComponent);
+ 
+  it('should extract the user data from the JWT-AccessToken', async(() => {
+    const fixture = TestBed.createComponent(AppComponent);    
     const app = fixture.debugElement.componentInstance;
-    expect(app.title).toEqual('app works!');
+
+    const accessToken = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJodVl0e' +
+      'VByUEVLQ1phY3FfMW5sOGZscENETnFHdmZEZHctYUxGQXNoWHZVIn0.eyJqdGkiOiI4ZmY5NTlhZC' +
+      '02ODQ1LTRlOGEtYjRiYi02ODQ0YjAwMjU0ZjgiLCJleHAiOjE1MDY2MDA0NTAsIm5iZiI6MCwiaWF' +
+      '0IjoxNTA2NjAwMTUwLCJpc3MiOiJodHRwOi8vZW50amF2YTAwMjo4MDgwL2F1dGgvcmVhbG1zL2Vs' +
+      'b2dib29rIiwiYXVkIjoiZWxvZ2Jvb2stYmFja2VuZCIsInN1YiI6IjM1OWVmOWM5LTc3ZGYtNGEzZ' +
+      'C1hOWM5LWY5NmQ4MzdkMmQ1NyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImVsb2dib29rLWJhY2tlbm' +
+      'QiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI5NjVmNzM1MS0yZThiLTQ1MjgtOWYzZC1' +
+      'lZTYyODNhOTViMTYiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNj' +
+      'ZXNzIjp7InJvbGVzIjpbImVsb2dib29rLXN1cGVydXNlciIsImVsb2dib29rLW5vcm1hbHVzZXIiL' +
+      'CJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbn' +
+      'QiOnsicm9sZXMiOlsidmlldy11c2VycyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJ' +
+      'hY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3Mi' +
+      'LCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiQWRtaW5pc3RyYXRvciBBZG1pbmlzdHJhdG93aWNoI' +
+      'iwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJnaXZlbl9uYW1lIjoiQWRtaW5pc3RyYXRvci' +
+      'IsImZhbWlseV9uYW1lIjoiQWRtaW5pc3RyYXRvd2ljaCIsImVtYWlsIjoic2VyZ2VqLmtlcm5AcHRh' +
+      'LmRlIiwicm9sZXN0ZXN0IjoiW2Vsb2dib29rLXN1cGVydXNlciwgZWxvZ2Jvb2stbm9ybWFsdXNlc' +
+      'iwgdW1hX2F1dGhvcml6YXRpb24sIG9mZmxpbmVfYWNjZXNzLCB1bWFfYXV0aG9yaXphdGlvbiwgZW' +
+      'xvZ2Jvb2stbm9ybWFsdXNlcl0ifQ.o94Bl43oqyLNzZRABvIq9z-XI8JQjqj2FSDdUUEZGZPTN4uw' +
+      'D5fyi0sONbDxmTFvgWPh_8ZhX6tlDGiupVDBY4eRH43Eettm-t4CDauL7FzB3w3dDPFMB5DhP4rrp' +
+      'k_kATwnY2NKLRbequnh8Z6wLXjcmQNLgrgknXB_gogWAqH29dqKexwceMNIbq-kjaeLsmHSXM9TE9' +
+      'q7_Ln9el04OlkpOVspVguedfINcNFg0DmYLJWyD2ORkOHLmYigN6YnyB9P2NFOnKGlLuQ87GjosI0' +
+      '0zBniRGi3PhE9NGd51Qggdbcsm0aM8GiMaZ7SO5i8iQWL10TRFRFyTEfy6hSO8g';
+
+      const incognito: any = app;
+      incognito.processAccessToken( accessToken );
+
+      expect( sessionContext.getCurrUser().name).toBe('Administrator Administratowich');
+      expect( sessionContext.getAccessToken()).toBe( accessToken );
   }));
 
+  /*
   it('should render title in a h1 tag', async(() => {
     const fixture = TestBed.createComponent(AppComponent);
     fixture.detectChanges();
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 84d5334..3456c3c 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -48,6 +48,31 @@
     this.extractTokenFromParameters();
   }
 
+  private processAccessToken( accessToken: string ) {
+    const jwtHelper: JwtHelper = new JwtHelper();
+    const decoded: any = jwtHelper.decodeToken(accessToken);
+    const user: User = new User();      
+    user.id = decoded.sub;
+    user.username = decoded.preferred_username;
+    user.itemName = decoded.preferred_username;
+    let firstName = decoded.given_name;       
+    if (!firstName) {
+      firstName = '';        
+    }
+    let lastName = decoded.family_name;       
+    if (!lastName) {
+      lastName = '';        
+    }        
+
+    user.name = firstName + ' ' + lastName;
+
+    if (decoded.realm_access.roles.filter(s => s === Globals.OAUTH2CONF_SUPERUSER_ROLE).length >= 1) {
+      user.specialUser = true;
+    }
+
+    this.sessionContext.setCurrUser(user);
+    this.sessionContext.setAccessToken(accessToken);
+}
 
   /**
    * Extract the params (suscribe to router event) and store them in the sessionContext.
@@ -55,31 +80,9 @@
   private extractTokenFromParameters() {
     this.activatedRoute.params.subscribe((params: Params) => {
       const accessToken = this.getParametersFromUrl();
-      if (accessToken) {
-        const jwtHelper: JwtHelper = new JwtHelper();
-        const decoded: any = jwtHelper.decodeToken(accessToken);
-        const user: User = new User();      
-        user.id = decoded.sub;
-        user.username = decoded.preferred_username;
-        user.itemName = decoded.preferred_username;
-        let firstName = decoded.given_name;       
-        if (!firstName) {
-          firstName = '';        
-        }
-        let lastName = decoded.family_name;       
-        if (!lastName) {
-          lastName = '';        
-        }        
-    
-        user.name = firstName + ' ' + lastName;
-  
-        if (decoded.realm_access.roles.filter(s => s === Globals.OAUTH2CONF_SUPERUSER_ROLE).length >= 1) {
-          user.specialUser = true;
-        }
-  
-        this.sessionContext.setCurrUser(user);
-        this.sessionContext.setAccessToken(accessToken);
 
+      if (accessToken) {
+        this.processAccessToken( accessToken );        
       }  
       this.messageService.loginLogoff$.emit(MessageDefines.MSG_LOG_IN_SUCCEEDED);     
     });
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 16a2375..a96c64d 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -6,7 +6,6 @@
 import { Daterangepicker } from 'ng2-daterangepicker';
 import { HttpModule } from '@angular/http';
 import { NotificationService } from './services/notification.service';
-import { NotificationSearchSortService } from './services/notification-search-sort.service';
 import { AuthenticationService } from './services/authentication.service';
 import { BaseDataService } from './services/base-data.service';
 import { ResponsibilityService } from './services/responsibility.service';
@@ -118,7 +117,6 @@
   ],
   providers: [
     NotificationService,
-    NotificationSearchSortService,
     AuthenticationService,
     ResponsibilityService,
     ReminderService,
diff --git a/src/app/common-components/message-banner/message-banner.component.spec.ts b/src/app/common-components/message-banner/message-banner.component.spec.ts
index 4046152..d21109d 100644
--- a/src/app/common-components/message-banner/message-banner.component.spec.ts
+++ b/src/app/common-components/message-banner/message-banner.component.spec.ts
@@ -1,14 +1,24 @@
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
+import { SessionContext } from '../../common/session-context';
+import { By } from '@angular/platform-browser';
+import { DebugElement } from '@angular/core';
 import { MessageBannerComponent } from './message-banner.component';
+import { BannerMessage } from '../../common/banner-message';
+import { BannerMessageStatusEn } from '../../common/enums';
 
 describe('MessageBannerComponent', () => {
   let component: MessageBannerComponent;
   let fixture: ComponentFixture<MessageBannerComponent>;
+  let sessionContext: SessionContext;  
 
   beforeEach(async(() => {
+    sessionContext = new SessionContext();  
+
     TestBed.configureTestingModule({
-      declarations: [ MessageBannerComponent ]
+      declarations: [ MessageBannerComponent ],
+      providers: [
+        { provide: SessionContext, useValue: sessionContext },
+      ],  
     })
     .compileComponents();
   }));
@@ -19,7 +29,36 @@
     fixture.detectChanges();
   });
 
-  // it('should be created', () => {
-  //   expect(component).toBeTruthy();
-  // });
+  it('should be created', () => {
+     expect(component).toBeTruthy();
+   });
+
+  it('should count the zOrder correctly and toggle the visibility due to zOrder', () => {
+    const fixture2 = TestBed.createComponent(MessageBannerComponent);
+    const component2: any = fixture2.componentInstance;
+    const bannerMessage = new BannerMessage();
+
+    sessionContext.setBannerMessage(BannerMessageStatusEn.success, 'Testor', true);
+
+    const x1: any = component;
+    x1.ngOnInit();
+
+    expect(component.getMaxMessageBannerZOrder()).toBe(0);
+    fixture.detectChanges();
+
+    // Component 1 is the only one and has the topmost zOrder=>Visible
+    expect(fixture.debugElement.query( By.css('.close'))).not.toBeNull();
+    
+    component2.zOrder = 666;
+    component2.ngOnInit();
+
+    expect(component.getMaxMessageBannerZOrder()).toBe(666);
+    fixture.detectChanges();
+    fixture2.detectChanges();
+
+    // Component 2 has a bigger zOrder => Component1=invisible, Component2=visible
+    expect(fixture.debugElement.query( By.css('.close'))).toBeNull();
+    expect(fixture2.debugElement.query( By.css('.close'))).not.toBeNull();
+
+  });
 });
diff --git a/src/app/common/session-context.ts b/src/app/common/session-context.ts
index 658f4e5..d42e2ab 100644
--- a/src/app/common/session-context.ts
+++ b/src/app/common/session-context.ts
@@ -35,9 +35,10 @@
     getCurrSessionId(): string { return localStorage.getItem(Globals.LOCALSTORAGE_SESSION_ID); }
     setCurrSessionId(sid: string): void { localStorage.setItem(Globals.LOCALSTORAGE_SESSION_ID, sid); }
 
-    initBannerMessage(){
+    initBannerMessage() {
         this.bannerMessage = new BannerMessage();
     }
+    
     clearStorage() {
         this.initBannerMessage();
         localStorage.clear();
diff --git a/src/app/dialogs/shift-change/shift-change.component.ts b/src/app/dialogs/shift-change/shift-change.component.ts
index 136bef2..ca259e9 100644
--- a/src/app/dialogs/shift-change/shift-change.component.ts
+++ b/src/app/dialogs/shift-change/shift-change.component.ts
@@ -119,7 +119,7 @@
 
   shiftChange(filter: boolean): void {
     const self = this;
-    let filteredResponsibilityContainers = this.responsibilityContainers;
+    const filteredResponsibilityContainers = this.responsibilityContainers;
 
     this.responsibilityService.planResponsibilities(filteredResponsibilityContainers).subscribe(resps => setResp(resps),
       error => {
diff --git a/src/app/pages/search/search.component.spec.ts b/src/app/pages/search/search.component.spec.ts
index 0ddd519..67778b9 100644
--- a/src/app/pages/search/search.component.spec.ts
+++ b/src/app/pages/search/search.component.spec.ts
@@ -30,7 +30,6 @@
 import { Notification } from '../../model/notification';
 import { NotificationService } from '../../services/notification.service';
 import { SearchResultService } from '../../services/search-result.service';
-import { NotificationSearchSortService } from '../../services/notification-search-sort.service';
 import { SEARCH_RESULT_NOTIFICATIONS } from '../../test-data/search-result-notifications';
 import { FilterSelection } from '../../model/filter-selection';
 import { CurrentRemindersComponent } from '../../lists/current-reminders/current-reminders.component';
@@ -107,30 +106,11 @@
     itemAdded$ = new EventEmitter();
     loadCalled = false;
     searchResultNotifications = SEARCH_RESULT_NOTIFICATIONS;
-
-    public searchFirstNotifications(notifications: Notification[], searchInput: string, filterSelection: FilterSelection) {
-      this.loadCalled = true;
-      const notificationSearchSortService = new NotificationSearchSortService();
-      // TODO: redesign service
-      //notificationSearchSortService.content = this.searchResultNotifications;
-      return notificationSearchSortService;
-    }
-    public searchAllNotifications(notifications: Notification[], searchInput: string, filterSelection: FilterSelection) {
-      this.loadCalled = true;
-      const notificationSearchSortService = new NotificationSearchSortService();
-      // TODO: redesign service
-      //notificationSearchSortService.content = this.searchResultNotifications;
-      return notificationSearchSortService;
-    }
   }
 
   class MockSearchResultService extends AbstractMockObservableService {
-    //TODO
-
     public getSearchResults(searchResultFilter?: GlobalSearchFilter) {
 
-      //const searchResultService = new SearchResultService();
-
       const searchResultNotifications = SEARCH_RESULT_NOTIFICATIONS;
       this.content = searchResultNotifications;
       return this;
@@ -205,7 +185,6 @@
         { provide: OVERLAY_PROVIDERS, useClass: OVERLAY_PROVIDERS },
         { provide: DaterangepickerConfig, useClass: DaterangepickerConfig },
         { provide: NotificationService, useValue: mockNotificationService },
-        { provide: NotificationSearchSortService, useValue: mockNotificationSearchSortService },
         { provide: SearchResultService, useValue: mockSearchResultService },
         { provide: SessionContext, useClass: SessionContext },
         { provide: ReminderService, useClass: ReminderService },
diff --git a/src/app/services/base-data.service.spec.ts b/src/app/services/base-data.service.spec.ts
index 3e98bf9..d1399bf 100644
--- a/src/app/services/base-data.service.spec.ts
+++ b/src/app/services/base-data.service.spec.ts
@@ -22,7 +22,7 @@
 
 describe('Http-BaseDataService (mockBackend)', () => {
   let sessionContext: SessionContext;
-let messageService:MessageService;
+let messageService: MessageService;
   beforeEach( async(() => {
     TestBed.configureTestingModule({
       imports: [ HttpModule ],
@@ -35,7 +35,7 @@
     })
     .compileComponents();
     sessionContext = new SessionContext();
-    messageService= new MessageService();
+    messageService = new MessageService();
   }));
 
   it('can instantiate service when inject service',
diff --git a/src/app/services/base-http.service.spec.ts b/src/app/services/base-http.service.spec.ts
index ad832df..8ada80c 100644
--- a/src/app/services/base-http.service.spec.ts
+++ b/src/app/services/base-http.service.spec.ts
@@ -8,7 +8,7 @@
 describe('BaseHttpService', () => {
   const _sc: SessionContext = new SessionContext();
   class BaseHttpServiceMock extends BaseHttpService {
-    public constructor( public messageService:MessageService ) {
+    public constructor( public messageService: MessageService ) {
       super(messageService );
     }
     public getBaseUrl(): string {
diff --git a/src/app/services/import.service.spec.ts b/src/app/services/import.service.spec.ts
index 1ed0130..96b2a52 100644
--- a/src/app/services/import.service.spec.ts
+++ b/src/app/services/import.service.spec.ts
@@ -18,7 +18,7 @@
 describe('Http-ImportService (mockBackend)', () => {
 
   let sessionContext: SessionContext;
-  let messageService: MessageService;
+  const messageService: MessageService = new MessageService();
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
diff --git a/src/app/services/notification-search-sort.service.spec.ts b/src/app/services/notification-search-sort.service.spec.ts
deleted file mode 100644
index bec6955..0000000
--- a/src/app/services/notification-search-sort.service.spec.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/* tslint:disable:no-unused-variable */
-
-import { TestBed, async, inject } from '@angular/core/testing';
-import { NotificationSearchSortService } from './notification-search-sort.service';
-
-describe('NotificationSearchSortService', () => {
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      providers: [NotificationSearchSortService]
-    });
-  });
-
-  it('should ...', inject([NotificationSearchSortService], (service: NotificationSearchSortService) => {
-    expect(service).toBeTruthy();
-  }));
-});
diff --git a/src/app/services/notification-search-sort.service.ts b/src/app/services/notification-search-sort.service.ts
deleted file mode 100644
index aa2c0ff..0000000
--- a/src/app/services/notification-search-sort.service.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Injectable } from '@angular/core';
-
-import { Notification } from '../model/notification';
-import { FilterSelection } from '../model/filter-selection';
-
-@Injectable()
-export class NotificationSearchSortService {
-
-  constructor() { }
-
-  private getSortedNotifications(notifications: Notification[]): Notification[] {
-    return notifications.sort((a, b) => a.createDate > b.createDate ? 1 : -1);
-  }
-/*
-  private getAllSortedNotifications(): Observable<Notification[]> {
-    return this.getSortedNotifications(this.getAllNotifications());
-  }
-  */
-
-  private searchNotifications(searchInput: string, filterSelection: FilterSelection, notifications: Notification[]): Notification[] {
-    return notifications.filter(notification => {
-      if ((filterSelection.all || filterSelection.status) && notification.status.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.notificationText) && notification.notificationText.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.freeText) && notification.freeText.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.freeTextExtended) && notification.freeTextExtended.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.responsibilityForwarding) && 
-           notification.responsibilityForwarding.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.responsibilityControlPoint) && 
-           notification.responsibilityControlPoint.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.creator) && notification.createUser.includes(searchInput)) {
-        return true;
-      }
-      if ((filterSelection.all || filterSelection.clerk) && notification.clerk.includes(searchInput)) {
-        return true;
-      }
-    });
-  }
-
-  searchFirstNotifications(notifications: Notification[], searchInput: string, filterSelection: FilterSelection): Notification[] {
-    return this.searchNotifications(searchInput, filterSelection, notifications).splice(0, 5);
-  }
-
-  searchAllNotifications(notifications: Notification[], searchInput: string, filterSelection: FilterSelection): Notification[] {
-    return this.searchNotifications(searchInput, filterSelection, notifications);
-  }  
-
-}
diff --git a/src/app/services/user.service.spec.ts b/src/app/services/user.service.spec.ts
index fc6883d..c8fbe8c 100644
--- a/src/app/services/user.service.spec.ts
+++ b/src/app/services/user.service.spec.ts
@@ -18,7 +18,7 @@
 
 describe('Http-UserService (mockBackend)', () => {
   let sessionContext: SessionContext;
-let messageService:MessageService;
+  let messageService: MessageService;
   beforeEach( async(() => {
     TestBed.configureTestingModule({
       imports: [ HttpModule ],