Simon Hunt

GUI -- Cleaned up websocket callback wrapping and beefed up unit tests.

Change-Id: I3457e7d8009d0c7ebb900d06ae01c59cf7370cba
...@@ -23,14 +23,21 @@ ...@@ -23,14 +23,21 @@
23 var fs; 23 var fs;
24 24
25 function fnOpen(f) { 25 function fnOpen(f) {
26 - return fs.isF(f); 26 + // wrap the onOpen function; we will handle any housekeeping here...
27 + if (!fs.isF(f)) {
28 + return null;
29 + }
30 +
31 + return function (openEvent) {
32 + // NOTE: nothing worth passing to the caller?
33 + f();
34 + };
27 } 35 }
28 36
29 function fnMessage(f) { 37 function fnMessage(f) {
30 // wrap the onMessage function; we will attempt to decode the 38 // wrap the onMessage function; we will attempt to decode the
31 // message event payload as JSON and pass that in... 39 // message event payload as JSON and pass that in...
32 - var fn = fs.isF(f); 40 + if (!fs.isF(f)) {
33 - if (!fn) {
34 return null; 41 return null;
35 } 42 }
36 43
...@@ -44,12 +51,21 @@ ...@@ -44,12 +51,21 @@
44 e: e 51 e: e
45 }; 52 };
46 } 53 }
47 - fn(ev); 54 + f(ev);
48 - } 55 + };
49 } 56 }
50 57
51 function fnClose(f) { 58 function fnClose(f) {
52 - return fs.isF(f); 59 + // wrap the onClose function; we will handle any parameters to the
60 + // close event here...
61 + if (!fs.isF(f)) {
62 + return null;
63 + }
64 +
65 + return function (closeEvent) {
66 + // NOTE: only seen {reason == ""} so far, nevertheless...
67 + f(closeEvent.reason);
68 + };
53 } 69 }
54 70
55 angular.module('onosRemote') 71 angular.module('onosRemote')
...@@ -60,7 +76,7 @@ ...@@ -60,7 +76,7 @@
60 fs = _fs_; 76 fs = _fs_;
61 77
62 // creates a web socket for the given path, returning a "handle". 78 // creates a web socket for the given path, returning a "handle".
63 - // opts contains the event handler callbacks. 79 + // opts contains the event handler callbacks, etc.
64 function createWebSocket(path, opts) { 80 function createWebSocket(path, opts) {
65 var o = opts || {}, 81 var o = opts || {},
66 wsport = opts && opts.wsport, 82 wsport = opts && opts.wsport,
...@@ -86,13 +102,14 @@ ...@@ -86,13 +102,14 @@
86 ws.onclose = fnClose(o.onClose); 102 ws.onclose = fnClose(o.onClose);
87 } 103 }
88 104
89 - function send(msg) { 105 + // messages are expected to be event objects..
90 - if (msg) { 106 + function send(ev) {
107 + if (ev) {
91 if (ws) { 108 if (ws) {
92 - ws.send(msg); 109 + ws.send(JSON.stringify(ev));
93 } else { 110 } else {
94 $log.warn('ws.send() no web socket open!', 111 $log.warn('ws.send() no web socket open!',
95 - fullUrl, msg); 112 + fullUrl, ev);
96 } 113 }
97 } 114 }
98 } 115 }
......
...@@ -141,8 +141,8 @@ ...@@ -141,8 +141,8 @@
141 141
142 } 142 }
143 143
144 - function onWsClose(closeEvent) { 144 + function onWsClose(reason) {
145 - $log.log('web socket closed...', closeEvent); 145 + $log.log('web socket closed; reason=', reason);
146 146
147 } 147 }
148 148
......
...@@ -50,15 +50,58 @@ describe('factory: fw/remote/websocket.js', function () { ...@@ -50,15 +50,58 @@ describe('factory: fw/remote/websocket.js', function () {
50 }); 50 });
51 51
52 it('should use the appropriate URL', function () { 52 it('should use the appropriate URL', function () {
53 - debugger;
54 var ws = wss.createWebSocket('foo/path'); 53 var ws = wss.createWebSocket('foo/path');
55 expect(ws.meta.path).toEqual('ws://foo:80/onos/ui/ws/foo/path'); 54 expect(ws.meta.path).toEqual('ws://foo:80/onos/ui/ws/foo/path');
56 }); 55 });
57 56
57 + it('should use the appropriate URL with modified port', function () {
58 + var ws = wss.createWebSocket('foo/path', { wsport: 1243 });
59 + expect(ws.meta.path).toEqual('ws://foo:1243/onos/ui/ws/foo/path');
60 + });
61 +
62 + var oCalled, mCalled, cCalled, json, reason;
63 +
64 + function oo() {
65 + oCalled++;
66 + }
67 + function om(j) {
68 + mCalled++;
69 + json = j;
70 + }
71 + function oc(r) {
72 + cCalled++;
73 + reason = r;
74 + }
75 +
76 + function resetCounters() {
77 + oCalled = mCalled = cCalled = 0;
78 + json = reason = null;
79 + }
80 +
81 + function validateCallbacks(ws, op, msg, cl) {
82 + // we have to cheat a little, by digging into the websocket structure
83 + var onO = fs.isF(ws.meta.ws.onopen),
84 + onM = fs.isF(ws.meta.ws.onmessage),
85 + onC = fs.isF(ws.meta.ws.onclose);
86 +
87 + expect(!!onO).toEqual(op);
88 + expect(!!onM).toEqual(msg);
89 + expect(!!onC).toEqual(cl);
90 +
91 + onO && onO({});
92 + onM && onM({ data: '{ "item": "ivalue" }'});
93 + onC && onC({ reason: 'rvalue' });
94 +
95 + expect(oCalled).toEqual(op ? 1 : 0);
96 + expect(mCalled).toEqual(msg ? 1 : 0);
97 + expect(cCalled).toEqual(cl ? 1 : 0);
98 +
99 + expect(json).toEqual(msg ? { item: 'ivalue' } : null);
100 + expect(reason).toEqual(cl ? 'rvalue' : null);
101 + }
102 +
58 it('should install the appropriate callbacks', function () { 103 it('should install the appropriate callbacks', function () {
59 - function oo() {} 104 + resetCounters();
60 - function om() {}
61 - function oc() {}
62 105
63 var ws = wss.createWebSocket('foo', { 106 var ws = wss.createWebSocket('foo', {
64 onOpen: oo, 107 onOpen: oo,
...@@ -66,27 +109,43 @@ describe('factory: fw/remote/websocket.js', function () { ...@@ -66,27 +109,43 @@ describe('factory: fw/remote/websocket.js', function () {
66 onClose: oc 109 onClose: oc
67 }); 110 });
68 111
69 - expect(ws.meta.ws.onopen).toBe(oo); 112 + validateCallbacks(ws, true, true, true);
70 - // TODO: om is wrapped - we can't test by reference
71 - //expect(ws.meta.ws.onmessage).toBe(om);
72 - expect(ws.meta.ws.onclose).toBe(oc);
73 }); 113 });
74 114
75 it('should install partial callbacks', function () { 115 it('should install partial callbacks', function () {
76 - function oo() {} 116 + resetCounters();
77 - function om() {}
78 117
79 var ws = wss.createWebSocket('foo', { 118 var ws = wss.createWebSocket('foo', {
80 onOpen: oo, 119 onOpen: oo,
81 onMessage: om 120 onMessage: om
82 }); 121 });
83 122
84 - expect(ws.meta.ws.onopen).toBe(oo); 123 + validateCallbacks(ws, true, true, false);
85 - // TODO: om is wrapped - we can't test by reference 124 + });
86 - //expect(ws.meta.ws.onmessage).toBe(om); 125 +
87 - expect(ws.meta.ws.onclose).toBeNull(); 126 + it('should install no callbacks', function () {
127 + resetCounters();
128 +
129 + var ws = wss.createWebSocket('foo');
130 +
131 + validateCallbacks(ws, false, false, false);
132 + });
133 +
134 + // can't really test send without faking out the WebSocket.
135 +/*
136 + it('should stringify objects for sending', function () {
137 + var ws = wss.createWebSocket('foo');
138 + ws.send({ item: 'itemVal' });
139 +
140 + // what to assert?
88 }); 141 });
142 +*/
89 143
90 - // TODO: more testing to be done. 144 + it('should remove websocket reference on close', function () {
145 + var ws = wss.createWebSocket('foo');
146 + expect(ws.meta.ws instanceof WebSocket).toBeTruthy();
91 147
148 + ws.close();
149 + expect(ws.meta.ws).toBeNull();
150 + });
92 }); 151 });
......