ONOS-1721 - GUI -- Websocket Service unit tests written, topo nav glyph added, other minor improvements.
Change-Id: I8199024e884d8538cd7c7d891d4fb4c81541150d
diff --git a/web/gui/src/main/webapp/tests/app/fw/remote/websocket-spec.js b/web/gui/src/main/webapp/tests/app/fw/remote/websocket-spec.js
index fc1e18d..9673f16 100644
--- a/web/gui/src/main/webapp/tests/app/fw/remote/websocket-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/remote/websocket-spec.js
@@ -20,8 +20,34 @@
describe('factory: fw/remote/websocket.js', function () {
var $log, fs, wss;
+ var noop = function () {},
+ send = jasmine.createSpy('send').and.callFake(function (ev) {
+ return ev;
+ }),
+ mockWebSocket = {
+ send: send
+ };
+
beforeEach(module('onosRemote', 'onosLayer', 'ngRoute', 'onosNav', 'onosSvg'));
+ beforeEach(function () {
+ mockWebSocket = {
+ send: send
+ };
+ });
+
+ beforeEach(function () {
+ module(function ($provide) {
+ $provide.factory('WSock', function () {
+ return {
+ newWebSocket: function () {
+ return mockWebSocket;
+ }
+ };
+ });
+ });
+ });
+
beforeEach(module(function($provide) {
$provide.factory('$location', function () {
return {
@@ -36,6 +62,7 @@
$log = _$log_;
fs = FnService;
wss = WebSocketService;
+ wss.resetState();
}));
@@ -45,21 +72,197 @@
it('should define api functions', function () {
expect(fs.areFunctions(wss, [
- 'resetSid', 'createWebSocket', 'bindHandlers', 'unbindHandlers',
+ 'resetSid', 'resetState',
+ 'createWebSocket', 'bindHandlers', 'unbindHandlers',
'addOpenListener', 'removeOpenListener', 'sendEvent'
])).toBeTruthy();
});
- it('should use the appropriate URL', function () {
+ it('should use the appropriate URL, createWebsocket', function () {
var url = wss.createWebSocket();
expect(url).toEqual('ws://foo:80/onos/ui/websock/core');
});
- it('should use the appropriate URL with modified port', function () {
- var url = wss.createWebSocket({ wsport: 1243 });
- expect(url).toEqual('ws://foo:1243/onos/ui/websock/core');
+ it('should use the appropriate URL with modified port, createWebsocket',
+ function () {
+ var url = wss.createWebSocket({ wsport: 1243 });
+ expect(url).toEqual('ws://foo:1243/onos/ui/websock/core');
});
- // TODO: inject mock WSock service and write more tests ...
+ it('should verify websocket event handlers, createWebsocket', function () {
+ wss.createWebSocket({ wsport: 1234 });
+ expect(fs.isF(mockWebSocket.onopen)).toBeTruthy();
+ expect(fs.isF(mockWebSocket.onmessage)).toBeTruthy();
+ expect(fs.isF(mockWebSocket.onclose)).toBeTruthy();
+ });
+
+ it('should invoke listener callbacks when websocket is up, handleOpen',
+ function () {
+ var num = 0;
+ function incrementNum() { num++; }
+ wss.addOpenListener(incrementNum);
+ wss.createWebSocket({ wsport: 1234 });
+ mockWebSocket.onopen();
+ expect(num).toBe(1);
+ });
+
+ it('should send pending events, handleOpen', function () {
+ var fakeEvent = {
+ event: 'mockEv',
+ sid: 1,
+ payload: { mock: 'thing' }
+ };
+ wss.sendEvent(fakeEvent.event, fakeEvent.payload);
+ expect(mockWebSocket.send).not.toHaveBeenCalled();
+ wss.createWebSocket({ wsport: 1234 });
+ mockWebSocket.onopen();
+ expect(mockWebSocket.send).toHaveBeenCalledWith(JSON.stringify(fakeEvent));
+ });
+
+ it('should handle an incoming bad JSON message, handleMessage', function () {
+ spyOn($log, 'error');
+ var badMsg = {
+ data: 'bad message'
+ };
+ wss.createWebSocket({ wsport: 1234 });
+ expect(mockWebSocket.onmessage(badMsg)).toBeNull();
+ expect($log.error).toHaveBeenCalled();
+ });
+
+ it('should verify message was handled, handleMessage', function () {
+ var num = 0,
+ fakeHandler = {
+ mockEvResp: function () { num++; }
+ },
+ data = JSON.stringify({
+ event: 'mockEvResp',
+ payload: {}
+ }),
+ event = {
+ data: data
+ };
+ wss.createWebSocket({ wsport: 1234 });
+ wss.bindHandlers(fakeHandler);
+ expect(mockWebSocket.onmessage(event)).toBe(undefined);
+ expect(num).toBe(1);
+ });
+
+ it('should warn if there is an unhandled event, handleMessage', function () {
+ spyOn($log, 'warn');
+ var data = { foo: 'bar', bar: 'baz'},
+ dataString = JSON.stringify(data),
+ badEv = {
+ data: dataString
+ };
+ wss.createWebSocket({ wsport: 1234 });
+ mockWebSocket.onmessage(badEv);
+ expect($log.warn).toHaveBeenCalledWith('Unhandled event:', data);
+ });
+
+ it('should not warn if valid input, bindHandlers', function () {
+ spyOn($log, 'warn');
+ expect(wss.bindHandlers({
+ foo: noop,
+ bar: noop
+ })).toBe(undefined);
+ expect($log.warn).not.toHaveBeenCalled();
+ });
+
+ it('should warn if no arguments, bindHandlers', function () {
+ spyOn($log, 'warn');
+ expect(wss.bindHandlers()).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.bindHandlers(): no event handlers'
+ );
+ expect(wss.bindHandlers({})).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.bindHandlers(): no event handlers'
+ );
+ });
+
+ it('should warn if handler is not a function, bindHandlers', function () {
+ spyOn($log, 'warn');
+ expect(wss.bindHandlers({
+ foo: 'handler1',
+ bar: 3,
+ baz: noop
+ })).toBe(undefined);
+ expect($log.warn).toHaveBeenCalledWith('foo handler not a function');
+ expect($log.warn).toHaveBeenCalledWith('bar handler not a function');
+ });
+
+ it('should warn if duplicate handlers were given, bindHandlers',
+ function () {
+ spyOn($log, 'warn');
+ wss.bindHandlers({
+ foo: noop
+ });
+ expect(wss.bindHandlers({
+ foo: noop
+ })).toBe(undefined);
+ expect($log.warn).toHaveBeenCalledWith('duplicate bindings ignored:',
+ ['foo']);
+ });
+
+ it('should warn if no arguments, unbindHandlers', function () {
+ spyOn($log, 'warn');
+ expect(wss.unbindHandlers()).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.unbindHandlers(): no event handlers'
+ );
+ expect(wss.unbindHandlers({})).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.unbindHandlers(): no event handlers'
+ );
+ });
+ // Note: cannot test unbindHandlers' forEach due to it using closure variable
+
+ it('should not warn if valid argument, addOpenListener', function () {
+ spyOn($log, 'warn');
+ var o = wss.addOpenListener(noop);
+ expect(o.id === 1);
+ expect(o.cb === noop);
+ expect($log.warn).not.toHaveBeenCalled();
+ o = wss.addOpenListener(noop);
+ expect(o.id === 2);
+ expect(o.cb === noop);
+ expect($log.warn).not.toHaveBeenCalled();
+ });
+
+ it('should log error if callback not a function, addOpenListener',
+ function () {
+ spyOn($log, 'error');
+ var o = wss.addOpenListener('foo');
+ expect(o.id === 1);
+ expect(o.cb === 'foo');
+ expect(o.error === 'No callback defined');
+ expect($log.error).toHaveBeenCalledWith(
+ 'WSS.addOpenListener(): callback not a function'
+ );
+ });
+
+ it('should not warn if valid listener object, removeOpenListener', function () {
+ spyOn($log, 'warn');
+ expect(wss.removeOpenListener({
+ id: 1,
+ cb: noop
+ })).toBe(undefined);
+ expect($log.warn).not.toHaveBeenCalled();
+ });
+
+ it('should warn if listener is invalid, removeOpenListener', function () {
+ spyOn($log, 'warn');
+ expect(wss.removeOpenListener({})).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.removeOpenListener(): invalid listener', {}
+ );
+ expect(wss.removeOpenListener('listener')).toBeNull();
+ expect($log.warn).toHaveBeenCalledWith(
+ 'WSS.removeOpenListener(): invalid listener', 'listener'
+ );
+ });
+
+ // Note: handleClose is not currently tested due to all work it does relies
+ // on closure variables that cannot be mocked
});
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
index 2f168ae..354967e 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
@@ -20,7 +20,7 @@
describe('factory: fw/svg/glyph.js', function() {
var $log, fs, gs, d3Elem, svg;
- var numBaseGlyphs = 36,
+ var numBaseGlyphs = 38,
vbBird = '352 224 113 112',
vbGlyph = '0 0 110 110',
vbBadge = '0 0 10 10',
@@ -38,6 +38,10 @@
chain: 'M60.4,77.6c-',
crown: 'M99.5,21.6c0,',
lock: 'M79.4,48.6h',
+ topo: 'M97.2,76.3H86.6',
+
+ // navigation specific glyphs
+ flowTable: 'M15.9,19.1h-8v-13h',
// toolbar specific glyphs
summary: longPrefix + 'M16.7',
@@ -75,7 +79,7 @@
},
glyphIds = [
'unknown', 'node', 'switch', 'roadm', 'endstation', 'router',
- 'bgpSpeaker', 'chain', 'crown', 'lock',
+ 'bgpSpeaker', 'chain', 'crown', 'lock', 'topo', 'flowTable',
'summary', 'details', 'ports', 'map', 'cycleLabels', 'oblique',
'filters', 'resetZoom', 'relatedIntents', 'nextIntent',
'prevIntent', 'intentTraffic', 'allTraffic', 'flows', 'eqMaster'
diff --git a/web/gui/src/main/webapp/tests/app/fw/widget/tableBuilder-spec.js b/web/gui/src/main/webapp/tests/app/fw/widget/tableBuilder-spec.js
index 27f9b40..f631617 100644
--- a/web/gui/src/main/webapp/tests/app/fw/widget/tableBuilder-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/widget/tableBuilder-spec.js
@@ -30,7 +30,6 @@
beforeEach(module('onosWidget', 'onosUtil', 'onosRemote'));
- // TODO: actual websocket calls should be tested in the websocket service
beforeEach(function () {
module(function ($provide) {
$provide.value('WebSocketService', mockWss);
@@ -93,8 +92,4 @@
expect(mockWss.unbindHandlers).toHaveBeenCalled();
});
- // TODO: figure out how to test respCb.
- // should it just be verified by the fact that the callback function
- // is called by the wss?
-
});