CORD-833 Prevent duplication of navigation routes

Change-Id: Idbd797976080a3d7b29912950c687f1b0fcb67e1
diff --git a/src/app/core/services/navigation.spec.ts b/src/app/core/services/navigation.spec.ts
index 62e8d3c..fbfb91c 100644
--- a/src/app/core/services/navigation.spec.ts
+++ b/src/app/core/services/navigation.spec.ts
@@ -4,7 +4,7 @@
 import {xosCore} from '../index';
 import {IXosNavigationService, IXosNavigationRoute} from './navigation';
 
-let service: IXosNavigationService;
+let service: IXosNavigationService, $log: ng.ILogService;
 
 let defaultRoutes: IXosNavigationRoute[];
 
@@ -36,8 +36,11 @@
 
   beforeEach(angular.mock.inject((
     NavigationService: IXosNavigationService,
+    _$log_: ng.ILogService
   ) => {
     service = NavigationService;
+    $log = _$log_;
+    spyOn($log, 'warn');
     defaultRoutes = [
       {
         label: 'Home',
@@ -61,6 +64,7 @@
     ];
     service.add(testRoutes[0]);
     service.add(testRoutes[1]);
+    expect($log.warn).not.toHaveBeenCalled();
     const serviceRoutes = service.query();
     expect(serviceRoutes).toEqual(defaultRoutes.concat(testRoutes));
   });
@@ -84,4 +88,13 @@
     }
     expect(wrapper).toThrowError('[XosNavigation] You can\'t provide both state and url');
   });
+
+  it('should not add route that already exist', () => {
+    const testRoute: IXosNavigationRoute = {label: 'TestState', state: 'xos.test'};
+    service.add(testRoute);
+    service.add(testRoute);
+    expect($log.warn).toHaveBeenCalled();
+    expect($log.warn).toHaveBeenCalledWith(`[XosNavigation] Route with label: ${testRoute.label}, state: ${testRoute.state} and parent: ${testRoute.parent} already exist`);
+    expect(service.query()).toEqual(defaultRoutes.concat([testRoute]));
+  });
 });
diff --git a/src/app/core/services/navigation.ts b/src/app/core/services/navigation.ts
index 31f2b4e..e35c9f8 100644
--- a/src/app/core/services/navigation.ts
+++ b/src/app/core/services/navigation.ts
@@ -18,10 +18,11 @@
 }
 
 export class NavigationService {
-  static $inject = ['StyleConfig'];
+  static $inject = ['$log', 'StyleConfig'];
   private routes: IXosNavigationRoute[];
 
   constructor(
+    private $log: ng.ILogService,
     private StyleConfig: IXosStyleConfig
   ) {
     const defaultRoutes = [
@@ -51,6 +52,18 @@
       throw new Error('[XosNavigation] You can\'t provide both state and url');
     }
 
+    const routeExist = _.findIndex(this.routes, (r: IXosNavigationRoute) => {
+      if (r.label === route.label && r.state === route.state && r.parent === route.parent) {
+        return true;
+      }
+      return false;
+    }) > -1;
+
+    if (routeExist) {
+      this.$log.warn(`[XosNavigation] Route with label: ${route.label}, state: ${route.state} and parent: ${route.parent} already exist`);
+      return;
+    }
+
 
     if (angular.isDefined(route.parent)) {
       // route parent should be a state for now