ONOS-1722 - GUI -- QuickHelp unit tests written, minor other user input precautions added.
Change-Id: Ifeec1a014bc0dd72026295f2331c8fe5416330fd
diff --git a/web/gui/src/main/webapp/app/fw/layer/quickhelp.js b/web/gui/src/main/webapp/app/fw/layer/quickhelp.js
index d5e8c0d..a25cf68 100644
--- a/web/gui/src/main/webapp/app/fw/layer/quickhelp.js
+++ b/web/gui/src/main/webapp/app/fw/layer/quickhelp.js
@@ -59,6 +59,11 @@
downArrow: 'D-arrow'
};
+ // list of needed bindings to use in aggregateData
+ var neededBindings = [
+ 'globalKeys', 'globalFormat', 'viewKeys', 'viewGestures'
+ ];
+
// ===========================================
// === Function Definitions ===
@@ -315,6 +320,22 @@
.remove();
}
+ function goodBindings(bindings) {
+ var warnPrefix = 'Quickhelp Service: showQuickHelp(), ';
+ if (!bindings || !fs.isO(bindings) || fs.isEmptyObject(bindings)) {
+ $log.warn(warnPrefix + 'invalid bindings object');
+ return false;
+ }
+ if (!(neededBindings.every(function (key) { return key in bindings; }))) {
+ $log.warn(
+ warnPrefix +
+ 'needed bindings for help panel not provided:',
+ neededBindings
+ );
+ return false
+ }
+ return true;
+ }
// ===========================================
// === Module Definition ===
@@ -329,12 +350,15 @@
sus = _sus_;
function initQuickHelp(opts) {
- settings = angular.extend({}, defaultSettings, opts);
+ settings = angular.extend({}, defaultSettings, fs.isO(opts));
qhdiv = d3.select('#quickhelp');
}
function showQuickHelp(bindings) {
svg = qhdiv.select('svg');
+ if (!goodBindings(bindings)) {
+ return null;
+ }
if (svg.empty()) {
addSvg();
popBind(bindings);
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 2415282..ed1dbc6 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -178,8 +178,23 @@
// --- Toolbar Functions ---------------------------------------------
+ function notValid(what) {
+ $log.warn('Topo.js getActionEntry(): Not a valid ' + what);
+ }
function getActionEntry(key) {
- var entry = actionMap[key];
+ var entry;
+
+ if (!key) {
+ notValid('key');
+ return null;
+ }
+
+ entry = actionMap[key];
+
+ if (!entry) {
+ notValid('actionMap entry');
+ return null;
+ }
return fs.isA(entry) || [entry, ''];
}
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 68ac923..0f473b4 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,7 +18,26 @@
ONOS GUI -- Layer -- Flash Service - Unit Tests
*/
describe('factory: fw/layer/quickhelp.js', function () {
- var $log, fs, qhs, d3Elem;
+ var $log, fs, qhs, d3Elem,
+ fade = 500,
+ noop = function () {},
+ mockBindings = {
+ globalKeys: {
+ slash: [noop, 'Show / hide Quick Help'],
+ T: [noop, 'Toggle Theme']
+ },
+ globalFormat: ['slash', 'T'],
+ viewKeys: {
+ H: [noop, 'Show / hide hosts'],
+ I: [noop, 'Toggle instances panel']
+ },
+ viewGestures: []
+ };
+
+ // list of needed bindings to use in aggregateData
+ var neededBindings = [
+ 'globalKeys', 'globalFormat', 'viewKeys', 'viewGestures'
+ ];
beforeEach(module('onosUtil', 'onosSvg', 'onosLayer'));
@@ -26,13 +45,15 @@
$log = _$log_;
fs = FnService;
qhs = QuickHelpService;
+
jasmine.clock().install();
- d3Elem = d3.select('body').append('div').attr('id', 'myqhdiv');
+ d3Elem = d3.select('body').append('div').attr('id', 'quickhelp');
+ qhs.initQuickHelp();
}));
afterEach(function () {
jasmine.clock().uninstall();
- d3.select('#myqhdiv').remove();
+ d3.select('#quickhelp').remove();
});
function helpItemSelection() {
@@ -53,22 +74,141 @@
expect(helpItemSelection().size()).toBe(0);
});
- // TODO: check that the help stuff appears
-/*
- it('should show help items', function () {
- var item, rect, text;
- flash.flash('foo');
- //jasmine.clock().tick(101);
- setTimeout(function () {
- item = flashItemSelection();
- expect(item.size()).toEqual(1);
- expect(item.classed('flashItem')).toBeTruthy();
- expect(item.select('rect').size()).toEqual(1);
- text = item.select('text');
- expect(text.size()).toEqual(1);
- expect(text.text()).toEqual('foo');
- }, 100);
+ // === showQuickHelp
+
+ it('should warn if bad bindings are provided', function () {
+ var warning =
+ 'Quickhelp Service: showQuickHelp(), invalid bindings object';
+ spyOn($log, 'warn');
+
+ expect(qhs.showQuickHelp()).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning);
+
+ expect(qhs.showQuickHelp({})).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning);
+
+ expect(qhs.showQuickHelp([1, 2, 3])).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning);
});
-*/
+
+ it('should warn if not all needed bindings are provided', function () {
+ var warning =
+ 'Quickhelp Service: showQuickHelp(),' +
+ ' needed bindings for help panel not provided:';
+ spyOn($log, 'warn');
+
+ expect(qhs.showQuickHelp({
+ foo: 'foo', bar: 'bar'
+ })).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
+
+ expect(qhs.showQuickHelp({
+ globalKeys: {}
+ })).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
+
+ expect(qhs.showQuickHelp({
+ globalKeys: {},
+ globalFormat: {},
+ viewKeys: {}
+ })).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(warning, neededBindings);
+ });
+
+ it('should not warn if bindings are provided', function () {
+ spyOn($log, 'warn');
+ expect(qhs.showQuickHelp(mockBindings)).toBe(undefined);
+ expect($log.warn).not.toHaveBeenCalled();
+ });
+
+ it('should append an svg', function () {
+ var svg = d3Elem.select('svg');
+ expect(d3Elem.empty()).toBe(false);
+ expect(svg.empty()).toBe(true);
+
+ qhs.showQuickHelp(mockBindings);
+
+ svg = d3Elem.select('svg');
+ expect(svg.empty()).toBe(false);
+ expect(svg.attr('width')).toBe('100%');
+ expect(svg.attr('height')).toBe('80%');
+ expect(svg.attr('viewBox')).toBe('-200 0 400 400');
+ });
+
+ it('should create the quick help panel', function () {
+ var helpItems, g, rect, text, rows;
+ qhs.showQuickHelp(mockBindings);
+
+ helpItems = helpItemSelection();
+ expect(helpItems.size()).toBe(1);
+
+ g = d3.select('g.help');
+ expect(g.attr('opacity')).toBe('0');
+
+ rect = g.select('rect');
+ expect(rect.attr('rx')).toBe('8');
+
+ text = g.select('text');
+ expect(text.text()).toBe('Quick Help');
+ expect(text.classed('title')).toBe(true);
+ expect(text.attr('dy')).toBe('1.2em');
+ expect(text.attr('transform')).toBeTruthy();
+
+ rows = g.select('g');
+ expect(rows.empty()).toBe(false);
+
+ jasmine.clock().tick(fade + 1);
+ setTimeout(function () {
+ expect(g.attr('opacity')).toBe('1');
+ }, fade);
+
+ // TODO: test aggregate data helper function
+ });
+
+ it('should show panel with custom fade time', function () {
+ var g,
+ ctmFade = 200;
+ qhs.initQuickHelp({ fade: ctmFade });
+ qhs.showQuickHelp(mockBindings);
+
+ g = d3.select('g.help');
+ expect(g.attr('opacity')).toBe('0');
+
+ jasmine.clock().tick(ctmFade + 1);
+ setTimeout(function () {
+ expect(g.attr('opacity')).toBe('1');
+ }, ctmFade);
+ });
+
+ // === hideQuickHelp
+
+ it('should hide quick help if svg exists', function () {
+ var svg;
+
+ expect(qhs.hideQuickHelp()).toBe(false);
+
+ svg = d3.select('#quickhelp')
+ .append('svg');
+ svg.append('g')
+ .classed('help', true)
+ .attr('opacity', 1);
+
+ expect(qhs.hideQuickHelp()).toBe(true);
+
+ jasmine.clock().tick(fade + 1);
+ setTimeout(function () {
+ expect(svg.select('g.help').attr('opacity')).toBe('0');
+ }, fade);
+
+ jasmine.clock().tick(20);
+ setTimeout(function () {
+ expect(svg.empty()).toBe(true);
+ }, fade + 20);
+ });
+
+ it('should not hide quick help if svg does not exist', function () {
+ expect(qhs.hideQuickHelp()).toBe(false);
+ });
+
});
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
index 63d2f23..eedc476 100644
--- 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
@@ -18,7 +18,7 @@
ONOS GUI -- Topo View -- Topo Toolbar Service - Unit Tests
*/
describe('factory: view/topo/topoToolbar.js', function() {
- var $log, fs, tts, prefs, ps,
+ var $log, fs, ttbs, prefs, ps,
d3Elem;
beforeEach(module('ovTopo', 'onosUtil', 'onosLayer', 'ngRoute', 'onosNav',
@@ -28,7 +28,7 @@
TopoToolbarService, PanelService, PrefsService) {
$log = _$log_;
fs = FnService;
- tts = TopoToolbarService;
+ ttbs = TopoToolbarService;
prefs = PrefsService;
ps = PanelService;
d3Elem = d3.select('body').append('div').attr('id', 'floatpanels');
@@ -36,35 +36,17 @@
}));
it('should define TopoToolbarService', function () {
- expect(tts).toBeDefined();
+ expect(ttbs).toBeDefined();
});
it('should define api functions', function () {
- expect(fs.areFunctions(tts, [
+ expect(fs.areFunctions(ttbs, [
'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();
- });
+ // NOTE: topoToolbar relies too much on topo's closure variables
+ // to adequately test it
});
\ No newline at end of file