ONOS-1724 - GUI -- svgUnit tests written. WIP topoToolbar unit tests written. Firing key presses programmatically investigated.

Change-Id: Ifff05859ebfebcee513d7fa8c42b52dc62f48f97
diff --git a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
index 53d957f..cb67ae8 100644
--- a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
+++ b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
@@ -53,6 +53,10 @@
                         ' is not a function';
                 }
 
+                if (!force) {
+                    bad.push('SvgUtilService: createDragBehavior(): ' +
+                    'Bad force reference');
+                }
                 if (!fSel) {
                     bad.push(naf('selectCb'));
                 }
@@ -71,7 +75,6 @@
                     return null;
                 }
 
-
                 function dragged(d) {
                     var threshold = draggedThreshold(force.alpha()),
                         dx = d.oldX - d.px,
diff --git a/web/gui/src/main/webapp/tests/app/fw/layer/quickhelp-spec.js b/web/gui/src/main/webapp/tests/app/fw/layer/quickhelp-spec.js
index acbc4a5..68ac923 100644
--- a/web/gui/src/main/webapp/tests/app/fw/layer/quickhelp-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/layer/quickhelp-spec.js
@@ -18,21 +18,20 @@
  ONOS GUI -- Layer -- Flash Service - Unit Tests
  */
 describe('factory: fw/layer/quickhelp.js', function () {
-    var $log, $timeout, fs, qhs, d3Elem;
+    var $log, fs, qhs, d3Elem;
 
     beforeEach(module('onosUtil', 'onosSvg', 'onosLayer'));
 
-    beforeEach(inject(function (_$log_, _$timeout_, FnService, QuickHelpService) {
+    beforeEach(inject(function (_$log_, FnService, QuickHelpService) {
         $log = _$log_;
-        //$timeout = _$timeout_;
         fs = FnService;
         qhs = QuickHelpService;
-        //jasmine.clock().install();
+        jasmine.clock().install();
         d3Elem = d3.select('body').append('div').attr('id', 'myqhdiv');
     }));
 
     afterEach(function () {
-        //jasmine.clock().uninstall();
+        jasmine.clock().uninstall();
         d3.select('#myqhdiv').remove();
     });
 
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
index 4164492..ab2bfa3 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
@@ -18,7 +18,9 @@
  ONOS GUI -- SVG -- SVG Util Service - Unit Tests
  */
 describe('factory: fw/svg/svgUtil.js', function() {
-    var $log, fs, sus, svg, d3Elem;
+    var $log, fs, sus, svg, defs, force;
+
+    var noop = function () {};
 
     beforeEach(module('onosUtil', 'onosSvg'));
 
@@ -27,7 +29,8 @@
         fs = FnService;
         sus = SvgUtilService;
         svg = d3.select('body').append('svg').attr('id', 'mySvg');
-        d3Elem = svg.append('defs');
+        defs = svg.append('defs');
+        force = d3.layout.force();
     }));
 
     afterEach(function () {
@@ -46,9 +49,100 @@
         ])).toBeTruthy();
     });
 
+    // === createDragBehavior
+    // TODO: break up drag into separate functions for testing
+    // d3 needs better testing support...
 
-    // TODO: add unit tests for drag behavior
-    // TODO: add unit tests for loadGlowDefs
+    // Note: just checking to see if error message was called
+    //       because jasmine spy isn't catching the right newline char
+    it('should complain if function given no parameters', function () {
+        spyOn($log, 'error');
+        expect(sus.createDragBehavior()).toBeNull();
+        expect($log.error).toHaveBeenCalled();
+    });
+
+    it('should complain if function is not given clickEnabled', function () {
+        spyOn($log, 'error');
+        expect(sus.createDragBehavior(force, noop, noop, noop)).toBeNull();
+        expect($log.error).toHaveBeenCalled();
+    });
+
+    it('should complain if function is not given dragEnabled', function () {
+        spyOn($log, 'error');
+        expect(sus.createDragBehavior(force, noop, noop)).toBeNull();
+        expect($log.error).toHaveBeenCalled();
+    });
+
+    it('should complain if function is not given atDragEnd', function () {
+        spyOn($log, 'error');
+        expect(sus.createDragBehavior(force, noop)).toBeNull();
+        expect($log.error).toHaveBeenCalled();
+    });
+
+    it('should complain if function is not given selectCb', function () {
+        spyOn($log, 'error');
+        expect(sus.createDragBehavior(force)).toBeNull();
+        expect($log.error).toHaveBeenCalled();
+    });
+
+    // === loadGlowDefs
+    function checkAttrs(glow, r, g, b) {
+        var filterEffects, feColor, feBlur, feMerge, feMergeNodes;
+
+        // filter attrs
+        expect(glow.attr('x')).toBe('-50%');
+        expect(glow.attr('y')).toBe('-50%');
+        expect(glow.attr('width')).toBe('200%');
+        expect(glow.attr('height')).toBe('200%');
+
+        filterEffects = d3.selectAll(glow.node().childNodes);
+        expect(filterEffects.size()).toBe(3);
+
+        // Note: d3 didn't recognize 'feColorMatrix' and others as valid selectors
+        //       this is a work around
+        feColor = d3.select(filterEffects[0].shift());
+        feBlur = d3.select(filterEffects[0].shift());
+        feMerge = d3.select(filterEffects[0].shift());
+
+        // feColorMatrix attrs
+        expect(feColor.empty()).toBe(false);
+        expect(feColor.attr('type')).toBe('matrix');
+        expect(feColor.attr('values')).toBe(
+            '0 0 0 0  ' + r + ' ' +
+            '0 0 0 0  ' + g + ' ' +
+            '0 0 0 0  ' + b + ' ' +
+            '0 0 0 1  0 '
+        );
+
+        // feGuassianBlur attrs
+        expect(feBlur.empty()).toBe(false);
+        expect(feBlur.attr('stdDeviation')).toBe('3');
+        expect(feBlur.attr('result')).toBe('coloredBlur');
+
+        // feMerge attrs
+        feMergeNodes = d3.selectAll(feMerge.node().childNodes);
+        expect(feMergeNodes.size()).toBe(2);
+        expect(d3.select(feMergeNodes[0][0]).attr('in')).toBe('coloredBlur');
+        expect(d3.select(feMergeNodes[0][1]).attr('in')).toBe('SourceGraphic');
+    }
+
+    it('should load glow definitions', function () {
+        var blue, yellow;
+        sus.loadGlowDefs(defs);
+
+        expect(defs.empty()).toBe(false);
+        expect((defs.selectAll('filter')).size()).toBe(2);
+
+        // blue-glow specific
+        blue = defs.select('#blue-glow');
+        expect(blue.empty()).toBe(false);
+        checkAttrs(blue, 0.0, 0.0, 0.7);
+
+        // yellow-glow specific
+        yellow = defs.select('#yellow-glow');
+        expect(yellow.empty()).toBe(false);
+        checkAttrs(yellow, 1.0, 1.0, 0.3);
+    });
 
     // === cat7
 
diff --git a/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js b/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
index 28cd4c2..227d790 100644
--- a/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
@@ -55,8 +55,16 @@
         ])).toBeTruthy();
     });
 
-    // Code to emulate key presses....
-    // NOTE: kinda messy, but it seems to get the job done.
+    // This no longer works because 'initKeyboardEvent' has been depreciated.
+    // Now there is a constructor for 'KeyboardEvent' where you can modify
+    //      the new event with a dictionary(?) 'KeyboardEventInit'.
+    // However, the below code has been so recently depreciated, there are no
+    //      examples online of how to use the new interface, and some browsers
+    //      don't support it still. These tests will have to be put off for a
+    //      while more. (Investigated 4/28/15)
+    // Also tried was Angular's triggerHandler() function, but it doesn't seem
+    //      that it can take arguments about the event.
+    // Using jQuery in tests might be a good idea, for triggering test events.
     function jsKeyDown(element, code) {
         var ev = document.createEvent('KeyboardEvent');
 
@@ -184,8 +192,9 @@
         expect(ks.keyBindings().viewFunction).toBeFalsy();
     }
 
-    // FIXME: jsKeyDown(...) no longer emulates key presses ?! :(
+    // TODO: jsKeyDown(...) no longer emulates key presses ?! :(
     // The following four unit tests ignored until we can figure this out.
+    // INVESTIGATED: see jsKeyDown for details...
 
     xit('should allow specific key bindings', function () {
         bindTestKeys();
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoToolbar-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoToolbar-spec.js
new file mode 100644
index 0000000..63d2f23
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoToolbar-spec.js
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Topo View -- Topo Toolbar Service - Unit Tests
+ */
+describe('factory: view/topo/topoToolbar.js', function() {
+    var $log, fs, tts, prefs, ps,
+        d3Elem;
+
+    beforeEach(module('ovTopo', 'onosUtil', 'onosLayer', 'ngRoute', 'onosNav',
+        'onosWidget'));
+
+    beforeEach(inject(function (_$log_, FnService,
+                                TopoToolbarService, PanelService, PrefsService) {
+        $log = _$log_;
+        fs = FnService;
+        tts = TopoToolbarService;
+        prefs = PrefsService;
+        ps = PanelService;
+        d3Elem = d3.select('body').append('div').attr('id', 'floatpanels');
+        ps.init();
+    }));
+
+    it('should define TopoToolbarService', function () {
+        expect(tts).toBeDefined();
+    });
+
+    it('should define api functions', function () {
+        expect(fs.areFunctions(tts, [
+            'init', 'createToolbar', 'destroyToolbar',
+            'keyListener', 'toggleToolbar'
+        ])).toBeTruthy();
+    });
+
+    function verifyFirstRow() {
+
+    }
+
+    function verifySecondRow() {
+
+    }
+
+    function verifyThirdRow() {
+
+    }
+
+    it('should create a toolbar', function () {
+        //var toolbar = tts.createToolbar('foo');
+        //expect(toolbar).toBeTruthy();
+        //expect(d3.select('#toolbar-foo').empty()).toBe(false);
+        //verifyFirstRow();
+        //verifySecondRow();
+        //verifyThirdRow();
+    });
+
+});
\ No newline at end of file