GUI -- Cleaned up websocket callback wrapping and beefed up unit tests.
Change-Id: I3457e7d8009d0c7ebb900d06ae01c59cf7370cba
Showing
3 changed files
with
104 additions
and
28 deletions
... | @@ -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 | } | ... | ... |
... | @@ -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 | }); | ... | ... |
-
Please register or login to post a comment