[CORD-965] Fixed Safari bug on Keyboard Shortcut and added tests

Change-Id: Ibaf99ea4eccda47105f6dba149950b55ad7f383c
diff --git a/src/app/core/services/keyboard-shortcut.spec.ts b/src/app/core/services/keyboard-shortcut.spec.ts
new file mode 100644
index 0000000..b573656
--- /dev/null
+++ b/src/app/core/services/keyboard-shortcut.spec.ts
@@ -0,0 +1,179 @@
+import * as angular from 'angular';
+import 'angular-mocks';
+import {IXosKeyboardShortcutService, XosKeyboardShortcut, IXosKeyboardShortcutBinding} from './keyboard-shortcut';
+import {IXosSidePanelService} from '../side-panel/side-panel.service';
+
+let service: IXosKeyboardShortcutService;
+let $log: ng.ILogService;
+let $transitions: any;
+let XosSidePanel: IXosSidePanelService;
+
+const baseGlobalModifiers: IXosKeyboardShortcutBinding[] = [
+  {
+    key: 'a',
+    cb: 'cb'
+  },
+  {
+    key: 'a',
+    cb: 'modified',
+    modifiers: ['alt']
+  },
+  {
+    key: 'a',
+    cb: 'modified',
+    modifiers: ['meta']
+  }
+];
+
+const baseLocalModifiers: IXosKeyboardShortcutBinding[] = [
+  {
+    key: 'b',
+    cb: 'cb'
+  },
+  {
+    key: 'b',
+    cb: 'modified',
+    modifiers: ['meta', 'alt']
+  }
+];
+
+describe('The XosKeyboardShortcut service', () => {
+
+  beforeEach(() => {
+    angular.module('leyBinding', ['ui.router'])
+      .service('XosKeyboardShortcut', XosKeyboardShortcut)
+      .value('XosSidePanel', {
+
+      });
+    angular.mock.module('leyBinding');
+
+    angular.mock.inject((
+      _$log_: ng.ILogService,
+      _$transitions_: any,
+      _XosSidePanel_: IXosSidePanelService
+    ) => {
+      $log = _$log_;
+      $transitions = _$transitions_;
+      XosSidePanel = _XosSidePanel_;
+    });
+
+    service = new XosKeyboardShortcut($log, $transitions, XosSidePanel);
+  });
+
+  it('should have a setup method', () => {
+    expect(service.setup).toBeDefined();
+  });
+
+  describe('the addActiveModifierKey method', () => {
+    beforeEach(() => {
+      service['activeModifiers'] = [];
+    });
+    it('should add an active modifier', () => {
+      service['addActiveModifierKey']('shift');
+      expect(service['activeModifiers']).toEqual(['shift']);
+    });
+
+    it('should not add a modifier twice', () => {
+      service['addActiveModifierKey']('shift');
+      service['addActiveModifierKey']('shift');
+      expect(service['activeModifiers']).toEqual(['shift']);
+    });
+  });
+
+  describe('the removeActiveModifierKey method', () => {
+    beforeEach(() => {
+      service['activeModifiers'] = ['shift', 'meta'];
+    });
+    it('should remove an active modifier', () => {
+      service['removeActiveModifierKey']('shift');
+      expect(service['activeModifiers']).toEqual(['meta']);
+    });
+  });
+
+  describe('the findBindedShortcut method', () => {
+    beforeEach(() => {
+      service['activeModifiers'] = [];
+      service['keyMapping']['global'] = baseGlobalModifiers;
+      service['keyMapping']['view'] = baseLocalModifiers;
+    });
+
+    it('should find a global keybinding', () => {
+      const binding = service['findBindedShortcut']('a');
+      expect(binding).toEqual({key: 'a', cb: 'cb'});
+    });
+
+    it('should find a global keybinding with modifiers', () => {
+      service['activeModifiers'] = ['meta'];
+      const binding = service['findBindedShortcut']('a');
+      expect(binding).toEqual({key: 'a', cb: 'modified', modifiers: ['meta']});
+    });
+
+    it('should find a view keybinding', () => {
+      const binding = service['findBindedShortcut']('b');
+      expect(binding).toEqual({key: 'b', cb: 'cb'});
+    });
+
+    it('should find a view keybinding with modifiers', () => {
+      service['activeModifiers'] = ['meta', 'alt'];
+      const binding = service['findBindedShortcut']('b');
+      expect(binding).toEqual({key: 'b', cb: 'modified', modifiers: ['meta', 'alt']});
+    });
+
+    it('should not care about binding key case', () => {
+      const binding = service['findBindedShortcut']('A');
+      expect(binding).toEqual({key: 'a', cb: 'cb'});
+    });
+  });
+
+  describe('the registerKeyBinding method', () => {
+
+    const binding = {
+      key: 'B',
+      cb: 'callback'
+    };
+
+    beforeEach(() => {
+      service['keyMapping'] = {
+        global: [
+          {
+            key: 'a',
+            cb: 'cb'
+          }
+        ],
+        view: []
+      };
+    });
+
+    it('should add a new global keybinding', () => {
+      service['registerKeyBinding'](binding, 'global');
+      expect(service['keyMapping']['global'].length).toBe(2);
+      expect(service['keyMapping']['global'][1].key).toBe('b');
+    });
+
+    it('should add a new view keybinding', () => {
+      service['registerKeyBinding'](binding);
+      expect(service['keyMapping']['view'].length).toBe(1);
+      expect(service['keyMapping']['view'][0].key).toBe('b');
+    });
+
+    it('should not add binding that is not registered as "global" or "view"', () => {
+      function errorFunctionWrapper() {
+        service['registerKeyBinding']({
+          key: 'z',
+          cb: 'cb'
+        }, 'something');
+      }
+      expect(errorFunctionWrapper).toThrow(new Error('[XosKeyboardShortcut] A shortcut can be registered with scope "global" or "view" only'));
+    });
+
+    it('should not add binding that has an already registered key', () => {
+      function errorFunctionWrapper() {
+        service['registerKeyBinding']({
+          key: 'A',
+          cb: 'cb'
+        }, 'global');
+      }
+      expect(errorFunctionWrapper).toThrow(new Error('[XosKeyboardShortcut] A shortcut for key "a" has already been registered'));
+    });
+  });
+});