]>
git.proxmox.com Git - mirror_novnc.git/blob - tests/test.websock.js
1 const expect
= chai
. expect
;
3 import Websock
from '../core/websock.js' ;
4 import FakeWebSocket
from './fake.websocket.js' ;
6 describe ( 'Websock' , function () {
9 describe ( 'Queue methods' , function () {
11 const RQ_TEMPLATE
= new Uint8Array ([ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]);
13 beforeEach ( function () {
16 sock
. _allocateBuffers ();
17 sock
. _rQ
. set ( RQ_TEMPLATE
);
18 sock
. _rQlen
= RQ_TEMPLATE
. length
;
20 describe ( 'rQlen' , function () {
21 it ( 'should return the length of the receive queue' , function () {
24 expect ( sock
. rQlen
). to
. equal ( RQ_TEMPLATE
. length
);
27 it ( "should return the proper length if we read some from the receive queue" , function () {
30 expect ( sock
. rQlen
). to
. equal ( RQ_TEMPLATE
. length
- 1 );
34 describe ( 'rQpeek8' , function () {
35 it ( 'should peek at the next byte without poping it off the queue' , function () {
36 const befLen
= sock
. rQlen
;
37 const peek
= sock
. rQpeek8 ();
38 expect ( sock
. rQpeek8 ()). to
. equal ( peek
);
39 expect ( sock
. rQlen
). to
. equal ( befLen
);
43 describe ( 'rQshift8()' , function () {
44 it ( 'should pop a single byte from the receive queue' , function () {
45 const peek
= sock
. rQpeek8 ();
46 const befLen
= sock
. rQlen
;
47 expect ( sock
. rQshift8 ()). to
. equal ( peek
);
48 expect ( sock
. rQlen
). to
. equal ( befLen
- 1 );
52 describe ( 'rQshift16()' , function () {
53 it ( 'should pop two bytes from the receive queue and return a single number' , function () {
54 const befLen
= sock
. rQlen
;
55 const expected
= ( RQ_TEMPLATE
[ 0 ] << 8 ) + RQ_TEMPLATE
[ 1 ];
56 expect ( sock
. rQshift16 ()). to
. equal ( expected
);
57 expect ( sock
. rQlen
). to
. equal ( befLen
- 2 );
61 describe ( 'rQshift32()' , function () {
62 it ( 'should pop four bytes from the receive queue and return a single number' , function () {
63 const befLen
= sock
. rQlen
;
64 const expected
= ( RQ_TEMPLATE
[ 0 ] << 24 ) +
65 ( RQ_TEMPLATE
[ 1 ] << 16 ) +
66 ( RQ_TEMPLATE
[ 2 ] << 8 ) +
68 expect ( sock
. rQshift32 ()). to
. equal ( expected
);
69 expect ( sock
. rQlen
). to
. equal ( befLen
- 4 );
73 describe ( 'rQshiftStr' , function () {
74 it ( 'should shift the given number of bytes off of the receive queue and return a string' , function () {
75 const befLen
= sock
. rQlen
;
76 const befRQi
= sock
. rQi
;
77 const shifted
= sock
. rQshiftStr ( 3 );
78 expect ( shifted
). to
. be
. a ( 'string' );
79 expect ( shifted
). to
. equal ( String
. fromCharCode
. apply ( null , Array
. prototype . slice
. call ( new Uint8Array ( RQ_TEMPLATE
. buffer
, befRQi
, 3 ))));
80 expect ( sock
. rQlen
). to
. equal ( befLen
- 3 );
83 it ( 'should shift the entire rest of the queue off if no length is given' , function () {
85 expect ( sock
. rQlen
). to
. equal ( 0 );
88 it ( 'should be able to handle very large strings' , function () {
89 const BIG_LEN
= 500000 ;
90 const RQ_BIG
= new Uint8Array ( BIG_LEN
);
92 let letterCode
= 'a' . charCodeAt ( 0 );
93 for ( let i
= 0 ; i
< BIG_LEN
; i
++) {
94 RQ_BIG
[ i
] = letterCode
;
95 expected
+= String
. fromCharCode ( letterCode
);
97 if ( letterCode
< 'z' . charCodeAt ( 0 )) {
100 letterCode
= 'a' . charCodeAt ( 0 );
103 sock
. _rQ
. set ( RQ_BIG
);
104 sock
. _rQlen
= RQ_BIG
. length
;
106 const shifted
= sock
. rQshiftStr ();
108 expect ( shifted
). to
. be
. equal ( expected
);
109 expect ( sock
. rQlen
). to
. equal ( 0 );
113 describe ( 'rQshiftBytes' , function () {
114 it ( 'should shift the given number of bytes of the receive queue and return an array' , function () {
115 const befLen
= sock
. rQlen
;
116 const befRQi
= sock
. rQi
;
117 const shifted
= sock
. rQshiftBytes ( 3 );
118 expect ( shifted
). to
. be
. an
. instanceof ( Uint8Array
);
119 expect ( shifted
). to
. array
. equal ( new Uint8Array ( RQ_TEMPLATE
. buffer
, befRQi
, 3 ));
120 expect ( sock
. rQlen
). to
. equal ( befLen
- 3 );
123 it ( 'should shift the entire rest of the queue off if no length is given' , function () {
125 expect ( sock
. rQlen
). to
. equal ( 0 );
129 describe ( 'rQslice' , function () {
130 beforeEach ( function () {
134 it ( 'should not modify the receive queue' , function () {
135 const befLen
= sock
. rQlen
;
137 expect ( sock
. rQlen
). to
. equal ( befLen
);
140 it ( 'should return an array containing the given slice of the receive queue' , function () {
141 const sl
= sock
. rQslice ( 0 , 2 );
142 expect ( sl
). to
. be
. an
. instanceof ( Uint8Array
);
143 expect ( sl
). to
. array
. equal ( new Uint8Array ( RQ_TEMPLATE
. buffer
, 0 , 2 ));
146 it ( 'should use the rest of the receive queue if no end is given' , function () {
147 const sl
= sock
. rQslice ( 1 );
148 expect ( sl
). to
. have
. length ( RQ_TEMPLATE
. length
- 1 );
149 expect ( sl
). to
. array
. equal ( new Uint8Array ( RQ_TEMPLATE
. buffer
, 1 ));
152 it ( 'should take the current rQi in to account' , function () {
154 expect ( sock
. rQslice ( 0 , 2 )). to
. array
. equal ( new Uint8Array ( RQ_TEMPLATE
. buffer
, 1 , 2 ));
158 describe ( 'rQwait' , function () {
159 beforeEach ( function () {
163 it ( 'should return true if there are not enough bytes in the receive queue' , function () {
164 expect ( sock
. rQwait ( 'hi' , RQ_TEMPLATE
. length
+ 1 )). to
. be
. true ;
167 it ( 'should return false if there are enough bytes in the receive queue' , function () {
168 expect ( sock
. rQwait ( 'hi' , RQ_TEMPLATE
. length
)). to
. be
. false ;
171 it ( 'should return true and reduce rQi by "goback" if there are not enough bytes' , function () {
173 expect ( sock
. rQwait ( 'hi' , RQ_TEMPLATE
. length
, 4 )). to
. be
. true ;
174 expect ( sock
. rQi
). to
. equal ( 1 );
177 it ( 'should raise an error if we try to go back more than possible' , function () {
179 expect (() => sock
. rQwait ( 'hi' , RQ_TEMPLATE
. length
, 6 )). to
. throw ( Error
);
182 it ( 'should not reduce rQi if there are enough bytes' , function () {
184 sock
. rQwait ( 'hi' , 1 , 6 );
185 expect ( sock
. rQi
). to
. equal ( 5 );
189 describe ( 'flush' , function () {
190 beforeEach ( function () {
196 it ( 'should actually send on the websocket' , function () {
197 sock
. _websocket
. bufferedAmount
= 8 ;
198 sock
. _websocket
. readyState
= WebSocket
. OPEN
;
199 sock
. _sQ
= new Uint8Array ([ 1 , 2 , 3 ]);
201 const encoded
= sock
. _encodeMessage ();
204 expect ( sock
. _websocket
. send
). to
. have
. been
. calledOnce
;
205 expect ( sock
. _websocket
. send
). to
. have
. been
. calledWith ( encoded
);
208 it ( 'should not call send if we do not have anything queued up' , function () {
210 sock
. _websocket
. bufferedAmount
= 8 ;
214 expect ( sock
. _websocket
. send
). not
. to
. have
. been
. called
;
218 describe ( 'send' , function () {
219 beforeEach ( function () {
220 sock
. flush
= sinon
. spy ();
223 it ( 'should add to the send queue' , function () {
224 sock
. send ([ 1 , 2 , 3 ]);
226 expect ( new Uint8Array ( sq
. buffer
, sock
. _sQlen
- 3 , 3 )). to
. array
. equal ( new Uint8Array ([ 1 , 2 , 3 ]));
229 it ( 'should call flush' , function () {
230 sock
. send ([ 1 , 2 , 3 ]);
231 expect ( sock
. flush
). to
. have
. been
. calledOnce
;
235 describe ( 'sendString' , function () {
236 beforeEach ( function () {
237 sock
. send
= sinon
. spy ();
240 it ( 'should call send after converting the string to an array' , function () {
241 sock
. sendString ( " \x01\x02\x03 " );
242 expect ( sock
. send
). to
. have
. been
. calledWith ([ 1 , 2 , 3 ]);
247 describe ( 'lifecycle methods' , function () {
254 beforeEach ( function () {
255 sock
= new Websock ();
256 // eslint-disable-next-line no-global-assign
257 WebSocket
= sinon
. spy ();
258 WebSocket
. OPEN
= oldWS
. OPEN
;
259 WebSocket
. CONNECTING
= oldWS
. CONNECTING
;
260 WebSocket
. CLOSING
= oldWS
. CLOSING
;
261 WebSocket
. CLOSED
= oldWS
. CLOSED
;
263 WebSocket
. prototype . binaryType
= 'arraybuffer' ;
266 describe ( 'opening' , function () {
267 it ( 'should pick the correct protocols if none are given' , function () {
271 it ( 'should open the actual websocket' , function () {
272 sock
. open ( 'ws://localhost:8675' , 'binary' );
273 expect ( WebSocket
). to
. have
. been
. calledWith ( 'ws://localhost:8675' , 'binary' );
276 // it('should initialize the event handlers')?
279 describe ( 'closing' , function () {
280 beforeEach ( function () {
282 sock
. _websocket
. close
= sinon
. spy ();
285 it ( 'should close the actual websocket if it is open' , function () {
286 sock
. _websocket
. readyState
= WebSocket
. OPEN
;
288 expect ( sock
. _websocket
. close
). to
. have
. been
. calledOnce
;
291 it ( 'should close the actual websocket if it is connecting' , function () {
292 sock
. _websocket
. readyState
= WebSocket
. CONNECTING
;
294 expect ( sock
. _websocket
. close
). to
. have
. been
. calledOnce
;
297 it ( 'should not try to close the actual websocket if closing' , function () {
298 sock
. _websocket
. readyState
= WebSocket
. CLOSING
;
300 expect ( sock
. _websocket
. close
). not
. to
. have
. been
. called
;
303 it ( 'should not try to close the actual websocket if closed' , function () {
304 sock
. _websocket
. readyState
= WebSocket
. CLOSED
;
306 expect ( sock
. _websocket
. close
). not
. to
. have
. been
. called
;
309 it ( 'should reset onmessage to not call _recvMessage' , function () {
310 sinon
. spy ( sock
, '_recvMessage' );
312 sock
. _websocket
. onmessage ( null );
314 expect ( sock
. _recvMessage
). not
. to
. have
. been
. called
;
316 sock
. _recvMessage
. restore ();
321 describe ( 'event handlers' , function () {
322 beforeEach ( function () {
323 sock
. _recvMessage
= sinon
. spy ();
324 sock
. on ( 'open' , sinon
. spy ());
325 sock
. on ( 'close' , sinon
. spy ());
326 sock
. on ( 'error' , sinon
. spy ());
330 it ( 'should call _recvMessage on a message' , function () {
331 sock
. _websocket
. onmessage ( null );
332 expect ( sock
. _recvMessage
). to
. have
. been
. calledOnce
;
335 it ( 'should call the open event handler on opening' , function () {
336 sock
. _websocket
. onopen ();
337 expect ( sock
. _eventHandlers
. open
). to
. have
. been
. calledOnce
;
340 it ( 'should call the close event handler on closing' , function () {
341 sock
. _websocket
. onclose ();
342 expect ( sock
. _eventHandlers
. close
). to
. have
. been
. calledOnce
;
345 it ( 'should call the error event handler on error' , function () {
346 sock
. _websocket
. onerror ();
347 expect ( sock
. _eventHandlers
. error
). to
. have
. been
. calledOnce
;
352 // eslint-disable-next-line no-global-assign
357 describe ( 'WebSocket Receiving' , function () {
359 beforeEach ( function () {
360 sock
= new Websock ();
361 sock
. _allocateBuffers ();
364 it ( 'should support adding binary Uint8Array data to the receive queue' , function () {
365 const msg
= { data
: new Uint8Array ([ 1 , 2 , 3 ]) };
366 sock
. _mode
= 'binary' ;
367 sock
. _recvMessage ( msg
);
368 expect ( sock
. rQshiftStr ( 3 )). to
. equal ( ' \x01\x02\x03 ' );
371 it ( 'should call the message event handler if present' , function () {
372 sock
. _eventHandlers
. message
= sinon
. spy ();
373 const msg
= { data
: new Uint8Array ([ 1 , 2 , 3 ]). buffer
};
374 sock
. _mode
= 'binary' ;
375 sock
. _recvMessage ( msg
);
376 expect ( sock
. _eventHandlers
. message
). to
. have
. been
. calledOnce
;
379 it ( 'should not call the message event handler if there is nothing in the receive queue' , function () {
380 sock
. _eventHandlers
. message
= sinon
. spy ();
381 const msg
= { data
: new Uint8Array ([]). buffer
};
382 sock
. _mode
= 'binary' ;
383 sock
. _recvMessage ( msg
);
384 expect ( sock
. _eventHandlers
. message
). not
. to
. have
. been
. called
;
387 it ( 'should compact the receive queue when a message handler empties it' , function () {
388 sock
. _eventHandlers
. message
= () => { sock
. rQi
= sock
. _rQlen
; };
389 sock
. _rQ
= new Uint8Array ([ 0 , 1 , 2 , 3 , 4 , 5 , 0 , 0 , 0 , 0 ]);
392 const msg
= { data
: new Uint8Array ([ 1 , 2 , 3 ]). buffer
};
393 sock
. _mode
= 'binary' ;
394 sock
. _recvMessage ( msg
);
395 expect ( sock
. _rQlen
). to
. equal ( 0 );
396 expect ( sock
. rQi
). to
. equal ( 0 );
399 it ( 'should compact the receive queue when we reach the end of the buffer' , function () {
400 sock
. _rQ
= new Uint8Array ( 20 );
401 sock
. _rQbufferSize
= 20 ;
404 const msg
= { data
: new Uint8Array ([ 1 , 2 ]). buffer
};
405 sock
. _mode
= 'binary' ;
406 sock
. _recvMessage ( msg
);
407 expect ( sock
. _rQlen
). to
. equal ( 12 );
408 expect ( sock
. rQi
). to
. equal ( 0 );
411 it ( 'should automatically resize the receive queue if the incoming message is larger than the buffer' , function () {
412 sock
. _rQ
= new Uint8Array ( 20 );
415 sock
. _rQbufferSize
= 20 ;
416 const msg
= { data
: new Uint8Array ( 30 ). buffer
};
417 sock
. _mode
= 'binary' ;
418 sock
. _recvMessage ( msg
);
419 expect ( sock
. _rQlen
). to
. equal ( 30 );
420 expect ( sock
. rQi
). to
. equal ( 0 );
421 expect ( sock
. _rQ
. length
). to
. equal ( 240 ); // keep the invariant that rQbufferSize / 8 >= rQlen
424 it ( 'should automatically resize the receive queue if the incoming message is larger than 1/8th of the buffer and we reach the end of the buffer' , function () {
425 sock
. _rQ
= new Uint8Array ( 20 );
428 sock
. _rQbufferSize
= 20 ;
429 const msg
= { data
: new Uint8Array ( 6 ). buffer
};
430 sock
. _mode
= 'binary' ;
431 sock
. _recvMessage ( msg
);
432 expect ( sock
. _rQlen
). to
. equal ( 6 );
433 expect ( sock
. rQi
). to
. equal ( 0 );
434 expect ( sock
. _rQ
. length
). to
. equal ( 48 );
438 describe ( 'Data encoding' , function () {
439 before ( function () { FakeWebSocket
. replace (); });
440 after ( function () { FakeWebSocket
. restore (); });
442 describe ( 'as binary data' , function () {
444 beforeEach ( function () {
445 sock
= new Websock ();
446 sock
. open ( 'ws://' , 'binary' );
447 sock
. _websocket
. _open ();
450 it ( 'should only send the send queue up to the send queue length' , function () {
451 sock
. _sQ
= new Uint8Array ([ 1 , 2 , 3 , 4 , 5 ]);
453 const res
= sock
. _encodeMessage ();
454 expect ( res
). to
. array
. equal ( new Uint8Array ([ 1 , 2 , 3 ]));
457 it ( 'should properly pass the encoded data off to the actual WebSocket' , function () {
458 sock
. send ([ 1 , 2 , 3 ]);
459 expect ( sock
. _websocket
. _getSentData ()). to
. array
. equal ( new Uint8Array ([ 1 , 2 , 3 ]));