Bri Prebilic Cole

ONOS-1722 - GUI -- QuickHelp unit tests written, minor other user input precautions added.

Change-Id: Ifeec1a014bc0dd72026295f2331c8fe5416330fd
...@@ -59,6 +59,11 @@ ...@@ -59,6 +59,11 @@
59 downArrow: 'D-arrow' 59 downArrow: 'D-arrow'
60 }; 60 };
61 61
62 + // list of needed bindings to use in aggregateData
63 + var neededBindings = [
64 + 'globalKeys', 'globalFormat', 'viewKeys', 'viewGestures'
65 + ];
66 +
62 // =========================================== 67 // ===========================================
63 // === Function Definitions === 68 // === Function Definitions ===
64 69
...@@ -315,6 +320,22 @@ ...@@ -315,6 +320,22 @@
315 .remove(); 320 .remove();
316 } 321 }
317 322
323 + function goodBindings(bindings) {
324 + var warnPrefix = 'Quickhelp Service: showQuickHelp(), ';
325 + if (!bindings || !fs.isO(bindings) || fs.isEmptyObject(bindings)) {
326 + $log.warn(warnPrefix + 'invalid bindings object');
327 + return false;
328 + }
329 + if (!(neededBindings.every(function (key) { return key in bindings; }))) {
330 + $log.warn(
331 + warnPrefix +
332 + 'needed bindings for help panel not provided:',
333 + neededBindings
334 + );
335 + return false
336 + }
337 + return true;
338 + }
318 339
319 // =========================================== 340 // ===========================================
320 // === Module Definition === 341 // === Module Definition ===
...@@ -329,12 +350,15 @@ ...@@ -329,12 +350,15 @@
329 sus = _sus_; 350 sus = _sus_;
330 351
331 function initQuickHelp(opts) { 352 function initQuickHelp(opts) {
332 - settings = angular.extend({}, defaultSettings, opts); 353 + settings = angular.extend({}, defaultSettings, fs.isO(opts));
333 qhdiv = d3.select('#quickhelp'); 354 qhdiv = d3.select('#quickhelp');
334 } 355 }
335 356
336 function showQuickHelp(bindings) { 357 function showQuickHelp(bindings) {
337 svg = qhdiv.select('svg'); 358 svg = qhdiv.select('svg');
359 + if (!goodBindings(bindings)) {
360 + return null;
361 + }
338 if (svg.empty()) { 362 if (svg.empty()) {
339 addSvg(); 363 addSvg();
340 popBind(bindings); 364 popBind(bindings);
......
...@@ -178,8 +178,23 @@ ...@@ -178,8 +178,23 @@
178 178
179 // --- Toolbar Functions --------------------------------------------- 179 // --- Toolbar Functions ---------------------------------------------
180 180
181 + function notValid(what) {
182 + $log.warn('Topo.js getActionEntry(): Not a valid ' + what);
183 + }
181 function getActionEntry(key) { 184 function getActionEntry(key) {
182 - var entry = actionMap[key]; 185 + var entry;
186 +
187 + if (!key) {
188 + notValid('key');
189 + return null;
190 + }
191 +
192 + entry = actionMap[key];
193 +
194 + if (!entry) {
195 + notValid('actionMap entry');
196 + return null;
197 + }
183 return fs.isA(entry) || [entry, '']; 198 return fs.isA(entry) || [entry, ''];
184 } 199 }
185 200
......
...@@ -18,7 +18,26 @@ ...@@ -18,7 +18,26 @@
18 ONOS GUI -- Layer -- Flash Service - Unit Tests 18 ONOS GUI -- Layer -- Flash Service - Unit Tests
19 */ 19 */
20 describe('factory: fw/layer/quickhelp.js', function () { 20 describe('factory: fw/layer/quickhelp.js', function () {
21 - var $log, fs, qhs, d3Elem; 21 + var $log, fs, qhs, d3Elem,
22 + fade = 500,
23 + noop = function () {},
24 + mockBindings = {
25 + globalKeys: {
26 + slash: [noop, 'Show / hide Quick Help'],
27 + T: [noop, 'Toggle Theme']
28 + },
29 + globalFormat: ['slash', 'T'],
30 + viewKeys: {
31 + H: [noop, 'Show / hide hosts'],
32 + I: [noop, 'Toggle instances panel']
33 + },
34 + viewGestures: []
35 + };
36 +
37 + // list of needed bindings to use in aggregateData
38 + var neededBindings = [
39 + 'globalKeys', 'globalFormat', 'viewKeys', 'viewGestures'
40 + ];
22 41
23 beforeEach(module('onosUtil', 'onosSvg', 'onosLayer')); 42 beforeEach(module('onosUtil', 'onosSvg', 'onosLayer'));
24 43
...@@ -26,13 +45,15 @@ describe('factory: fw/layer/quickhelp.js', function () { ...@@ -26,13 +45,15 @@ describe('factory: fw/layer/quickhelp.js', function () {
26 $log = _$log_; 45 $log = _$log_;
27 fs = FnService; 46 fs = FnService;
28 qhs = QuickHelpService; 47 qhs = QuickHelpService;
48 +
29 jasmine.clock().install(); 49 jasmine.clock().install();
30 - d3Elem = d3.select('body').append('div').attr('id', 'myqhdiv'); 50 + d3Elem = d3.select('body').append('div').attr('id', 'quickhelp');
51 + qhs.initQuickHelp();
31 })); 52 }));
32 53
33 afterEach(function () { 54 afterEach(function () {
34 jasmine.clock().uninstall(); 55 jasmine.clock().uninstall();
35 - d3.select('#myqhdiv').remove(); 56 + d3.select('#quickhelp').remove();
36 }); 57 });
37 58
38 function helpItemSelection() { 59 function helpItemSelection() {
...@@ -53,22 +74,141 @@ describe('factory: fw/layer/quickhelp.js', function () { ...@@ -53,22 +74,141 @@ describe('factory: fw/layer/quickhelp.js', function () {
53 expect(helpItemSelection().size()).toBe(0); 74 expect(helpItemSelection().size()).toBe(0);
54 }); 75 });
55 76
56 - // TODO: check that the help stuff appears 77 + // === showQuickHelp
57 -/* 78 +
58 - it('should show help items', function () { 79 + it('should warn if bad bindings are provided', function () {
59 - var item, rect, text; 80 + var warning =
60 - flash.flash('foo'); 81 + 'Quickhelp Service: showQuickHelp(), invalid bindings object';
61 - //jasmine.clock().tick(101); 82 + spyOn($log, 'warn');
83 +
84 + expect(qhs.showQuickHelp()).toBeNull();
85 + expect($log.warn).toHaveBeenCalledWith(warning);
86 +
87 + expect(qhs.showQuickHelp({})).toBeNull();
88 + expect($log.warn).toHaveBeenCalledWith(warning);
89 +
90 + expect(qhs.showQuickHelp([1, 2, 3])).toBeNull();
91 + expect($log.warn).toHaveBeenCalledWith(warning);
92 + });
93 +
94 + it('should warn if not all needed bindings are provided', function () {
95 + var warning =
96 + 'Quickhelp Service: showQuickHelp(),' +
97 + ' needed bindings for help panel not provided:';
98 + spyOn($log, 'warn');
99 +
100 + expect(qhs.showQuickHelp({
101 + foo: 'foo', bar: 'bar'
102 + })).toBeNull();
103 + expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
104 +
105 + expect(qhs.showQuickHelp({
106 + globalKeys: {}
107 + })).toBeNull();
108 + expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
109 +
110 + expect(qhs.showQuickHelp({
111 + globalKeys: {},
112 + globalFormat: {},
113 + viewKeys: {}
114 + })).toBeNull();
115 + expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
116 + });
117 +
118 + it('should not warn if bindings are provided', function () {
119 + spyOn($log, 'warn');
120 + expect(qhs.showQuickHelp(mockBindings)).toBe(undefined);
121 + expect($log.warn).not.toHaveBeenCalled();
122 + });
123 +
124 + it('should append an svg', function () {
125 + var svg = d3Elem.select('svg');
126 + expect(d3Elem.empty()).toBe(false);
127 + expect(svg.empty()).toBe(true);
128 +
129 + qhs.showQuickHelp(mockBindings);
130 +
131 + svg = d3Elem.select('svg');
132 + expect(svg.empty()).toBe(false);
133 + expect(svg.attr('width')).toBe('100%');
134 + expect(svg.attr('height')).toBe('80%');
135 + expect(svg.attr('viewBox')).toBe('-200 0 400 400');
136 + });
137 +
138 + it('should create the quick help panel', function () {
139 + var helpItems, g, rect, text, rows;
140 + qhs.showQuickHelp(mockBindings);
141 +
142 + helpItems = helpItemSelection();
143 + expect(helpItems.size()).toBe(1);
144 +
145 + g = d3.select('g.help');
146 + expect(g.attr('opacity')).toBe('0');
147 +
148 + rect = g.select('rect');
149 + expect(rect.attr('rx')).toBe('8');
150 +
151 + text = g.select('text');
152 + expect(text.text()).toBe('Quick Help');
153 + expect(text.classed('title')).toBe(true);
154 + expect(text.attr('dy')).toBe('1.2em');
155 + expect(text.attr('transform')).toBeTruthy();
156 +
157 + rows = g.select('g');
158 + expect(rows.empty()).toBe(false);
159 +
160 + jasmine.clock().tick(fade + 1);
161 + setTimeout(function () {
162 + expect(g.attr('opacity')).toBe('1');
163 + }, fade);
164 +
165 + // TODO: test aggregate data helper function
166 + });
167 +
168 + it('should show panel with custom fade time', function () {
169 + var g,
170 + ctmFade = 200;
171 + qhs.initQuickHelp({ fade: ctmFade });
172 + qhs.showQuickHelp(mockBindings);
173 +
174 + g = d3.select('g.help');
175 + expect(g.attr('opacity')).toBe('0');
176 +
177 + jasmine.clock().tick(ctmFade + 1);
178 + setTimeout(function () {
179 + expect(g.attr('opacity')).toBe('1');
180 + }, ctmFade);
181 + });
182 +
183 + // === hideQuickHelp
184 +
185 + it('should hide quick help if svg exists', function () {
186 + var svg;
187 +
188 + expect(qhs.hideQuickHelp()).toBe(false);
189 +
190 + svg = d3.select('#quickhelp')
191 + .append('svg');
192 + svg.append('g')
193 + .classed('help', true)
194 + .attr('opacity', 1);
195 +
196 + expect(qhs.hideQuickHelp()).toBe(true);
197 +
198 + jasmine.clock().tick(fade + 1);
62 setTimeout(function () { 199 setTimeout(function () {
63 - item = flashItemSelection(); 200 + expect(svg.select('g.help').attr('opacity')).toBe('0');
64 - expect(item.size()).toEqual(1); 201 + }, fade);
65 - expect(item.classed('flashItem')).toBeTruthy(); 202 +
66 - expect(item.select('rect').size()).toEqual(1); 203 + jasmine.clock().tick(20);
67 - text = item.select('text'); 204 + setTimeout(function () {
68 - expect(text.size()).toEqual(1); 205 + expect(svg.empty()).toBe(true);
69 - expect(text.text()).toEqual('foo'); 206 + }, fade + 20);
70 - }, 100);
71 }); 207 });
72 -*/ 208 +
209 + it('should not hide quick help if svg does not exist', function () {
210 + expect(qhs.hideQuickHelp()).toBe(false);
211 + });
212 +
73 }); 213 });
74 214
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 ONOS GUI -- Topo View -- Topo Toolbar Service - Unit Tests 18 ONOS GUI -- Topo View -- Topo Toolbar Service - Unit Tests
19 */ 19 */
20 describe('factory: view/topo/topoToolbar.js', function() { 20 describe('factory: view/topo/topoToolbar.js', function() {
21 - var $log, fs, tts, prefs, ps, 21 + var $log, fs, ttbs, prefs, ps,
22 d3Elem; 22 d3Elem;
23 23
24 beforeEach(module('ovTopo', 'onosUtil', 'onosLayer', 'ngRoute', 'onosNav', 24 beforeEach(module('ovTopo', 'onosUtil', 'onosLayer', 'ngRoute', 'onosNav',
...@@ -28,7 +28,7 @@ describe('factory: view/topo/topoToolbar.js', function() { ...@@ -28,7 +28,7 @@ describe('factory: view/topo/topoToolbar.js', function() {
28 TopoToolbarService, PanelService, PrefsService) { 28 TopoToolbarService, PanelService, PrefsService) {
29 $log = _$log_; 29 $log = _$log_;
30 fs = FnService; 30 fs = FnService;
31 - tts = TopoToolbarService; 31 + ttbs = TopoToolbarService;
32 prefs = PrefsService; 32 prefs = PrefsService;
33 ps = PanelService; 33 ps = PanelService;
34 d3Elem = d3.select('body').append('div').attr('id', 'floatpanels'); 34 d3Elem = d3.select('body').append('div').attr('id', 'floatpanels');
...@@ -36,35 +36,17 @@ describe('factory: view/topo/topoToolbar.js', function() { ...@@ -36,35 +36,17 @@ describe('factory: view/topo/topoToolbar.js', function() {
36 })); 36 }));
37 37
38 it('should define TopoToolbarService', function () { 38 it('should define TopoToolbarService', function () {
39 - expect(tts).toBeDefined(); 39 + expect(ttbs).toBeDefined();
40 }); 40 });
41 41
42 it('should define api functions', function () { 42 it('should define api functions', function () {
43 - expect(fs.areFunctions(tts, [ 43 + expect(fs.areFunctions(ttbs, [
44 'init', 'createToolbar', 'destroyToolbar', 44 'init', 'createToolbar', 'destroyToolbar',
45 'keyListener', 'toggleToolbar' 45 'keyListener', 'toggleToolbar'
46 ])).toBeTruthy(); 46 ])).toBeTruthy();
47 }); 47 });
48 48
49 - function verifyFirstRow() { 49 + // NOTE: topoToolbar relies too much on topo's closure variables
50 - 50 + // to adequately test it
51 - }
52 -
53 - function verifySecondRow() {
54 -
55 - }
56 -
57 - function verifyThirdRow() {
58 -
59 - }
60 -
61 - it('should create a toolbar', function () {
62 - //var toolbar = tts.createToolbar('foo');
63 - //expect(toolbar).toBeTruthy();
64 - //expect(d3.select('#toolbar-foo').empty()).toBe(false);
65 - //verifyFirstRow();
66 - //verifySecondRow();
67 - //verifyThirdRow();
68 - });
69 51
70 }); 52 });
...\ No newline at end of file ...\ No newline at end of file
......