@@ -39,6 +39,10 @@ describe('Client', () => {
39
39
} ) ;
40
40
} ) ;
41
41
42
+ mockAws . close . mockImplementation ( async ( ) => {
43
+
44
+ } ) ;
45
+
42
46
mockAws . mockBusy = ( ) => {
43
47
const deferred = new Deferred ( ) ;
44
48
mockAws . send . mockImplementationOnce ( ( ) => deferred . promise ) ;
@@ -130,7 +134,7 @@ describe('Client', () => {
130
134
mockAws . mockResponse ( 'loginSuccess' , { } ) ;
131
135
expect ( mockAws . send ) . not . toHaveBeenCalled ( ) ;
132
136
await client . connect ( ) ;
133
- expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Login ( validSession . sessionId ) ) ;
137
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Login ( validSession . sessionId ) , SEND_OPTIONS . TIMED ) ;
134
138
} ) ;
135
139
136
140
it ( 'should not consider itself connected to the app if "loginSuccess" params.appConnected = false' , async ( ) => {
@@ -160,14 +164,14 @@ describe('Client', () => {
160
164
161
165
it ( 'should schedule "currentStatus" query when it takes too long' , async ( ) => {
162
166
const { action } = await simulateInFlightAction ( ) ;
163
- expect ( mockAws . send ) . toHaveBeenCalledWith ( action ) ;
167
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( action , SEND_OPTIONS . DEFAULT ) ;
164
168
expect ( mockAws . send ) . toHaveBeenCalledTimes ( 2 ) ; // action + login
165
169
166
170
mockAws . mockBusy ( ) ; // for the current status query
167
171
jest . advanceTimersByTime ( validSession . debugSynchronization ) ;
168
172
await fastForwardAllPromises ( ) ;
169
173
170
- expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . CurrentStatus ( ) ) ;
174
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . CurrentStatus ( ) , SEND_OPTIONS . TIMED ) ;
171
175
expect ( jest . getTimerCount ( ) ) . toBe ( 0 ) ; // should not spam with "currentStatus" queries
172
176
} ) ;
173
177
@@ -258,7 +262,7 @@ describe('Client', () => {
258
262
mockAws . mockResponse ( 'whateverDone' ) ;
259
263
const action = anAction ( ) ;
260
264
await client . sendAction ( action ) ;
261
- expect ( mockAws . send ) . toHaveBeenCalledWith ( action ) ;
265
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( action , SEND_OPTIONS . DEFAULT ) ;
262
266
} ) ;
263
267
264
268
it ( 'should pass the parsed response to action.handle()' , async ( ) => {
@@ -297,7 +301,6 @@ describe('Client', () => {
297
301
[ 'waitForActive' , 'waitForActiveDone' , actions . WaitForActive ] ,
298
302
[ 'waitUntilReady' , 'ready' , actions . Ready ] ,
299
303
[ 'currentStatus' , 'currentStatusResult' , actions . CurrentStatus , { } , { status : 'App is idle' } ] ,
300
- [ 'cleanup' , 'cleanupDone' , actions . Cleanup , true ] ,
301
304
] ) ( '.%s' , ( methodName , expectedResponseType , Action , params , expectedResponseParams ) => {
302
305
beforeEach ( async ( ) => {
303
306
await client . connect ( ) ;
@@ -308,7 +311,7 @@ describe('Client', () => {
308
311
await client [ methodName ] ( params ) ;
309
312
310
313
const action = new Action ( params ) ;
311
- expect ( mockAws . send ) . toHaveBeenCalledWith ( action ) ;
314
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( action , { timeout : expect . any ( Number ) } ) ;
312
315
} ) ;
313
316
314
317
it ( `should throw on a wrong response from device` , async ( ) => {
@@ -362,7 +365,7 @@ describe('Client', () => {
362
365
await client . connect ( ) ;
363
366
mockAws . mockResponse ( 'cleanupDone' ) ;
364
367
await client . cleanup ( ) ;
365
- expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Cleanup ( true ) ) ;
368
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Cleanup ( true ) , SEND_OPTIONS . TIMED ) ;
366
369
} ) ;
367
370
368
371
it ( 'should send cleanup action (stopRunner=false) to the app if there were failed invocations' , async ( ) => {
@@ -371,7 +374,7 @@ describe('Client', () => {
371
374
await expect ( client . execute ( anInvocation ) ) . rejects . toThrowError ( / T e s t F a i l e d .* S o m e D e t a i l s / ) ;
372
375
mockAws . mockResponse ( 'cleanupDone' ) ;
373
376
await client . cleanup ( ) ;
374
- expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Cleanup ( false ) ) ;
377
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Cleanup ( false ) , SEND_OPTIONS . TIMED ) ;
375
378
} ) ;
376
379
377
380
it ( 'should close the websocket upon "cleanupDone" from the app' , async ( ) => {
@@ -381,11 +384,32 @@ describe('Client', () => {
381
384
expect ( mockAws . close ) . toHaveBeenCalled ( ) ;
382
385
} ) ;
383
386
384
- it ( 'should close the websocket even on error' , async ( ) => {
387
+ it ( 'should close the websocket even if getting "cleanupDone" fails' , async ( ) => {
388
+ await client . connect ( ) ;
389
+ mockAws . mockResponse ( 'serverError' ) ;
390
+ await client . cleanup ( ) ;
391
+ expect ( mockAws . close ) . toHaveBeenCalled ( ) ;
392
+ } ) ;
393
+
394
+ it ( 'should close the websocket even on an inner error' , async ( ) => {
395
+ await client . connect ( ) ;
396
+ mockAws . mockSyncError ( 'MyError' ) ;
397
+ await client . cleanup ( ) ;
398
+ expect ( mockAws . close ) . toHaveBeenCalled ( ) ;
399
+ expect ( log . error ) . toHaveBeenCalledWith ( { event : 'ERROR' } , expect . stringContaining ( 'MyError' ) ) ;
400
+ } ) ;
401
+
402
+ it ( 'should not bail even if the world is crashing, instead it should log errors and exit calmly' , async ( ) => {
385
403
await client . connect ( ) ;
386
- mockAws . mockSyncError ( 'UnexpectedError' ) ;
387
- await expect ( client . cleanup ( ) ) . rejects . toThrowError ( 'UnexpectedError' ) ;
404
+
405
+ mockAws . send . mockRejectedValue ( 'MyError1' ) ;
406
+ mockAws . close . mockRejectedValue ( 'MyError2' ) ;
407
+
408
+ await client . cleanup ( ) ;
409
+
388
410
expect ( mockAws . close ) . toHaveBeenCalled ( ) ;
411
+ expect ( log . error ) . toHaveBeenCalledWith ( { event : 'ERROR' } , expect . stringContaining ( 'MyError1' ) ) ;
412
+ expect ( log . error ) . toHaveBeenCalledWith ( { event : 'ERROR' } , expect . stringContaining ( 'MyError2' ) ) ;
389
413
} ) ;
390
414
391
415
it ( 'should delete the injected .terminateApp method' , async ( ) => {
@@ -543,7 +567,7 @@ describe('Client', () => {
543
567
mockAws . mockEventCallback ( 'appConnected' ) ;
544
568
mockAws . mockResponse ( 'ready' ) ;
545
569
await fastForwardAllPromises ( ) ;
546
- expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Ready ( ) ) ;
570
+ expect ( mockAws . send ) . toHaveBeenCalledWith ( new actions . Ready ( ) , SEND_OPTIONS . DEFAULT ) ;
547
571
expect ( isReady ) . toBe ( true ) ;
548
572
} ) ;
549
573
@@ -558,7 +582,7 @@ describe('Client', () => {
558
582
await client . connect ( ) ;
559
583
await fastForwardAllPromises ( ) ;
560
584
expect ( isReady ) . toBe ( true ) ;
561
- expect ( mockAws . send ) . not . toHaveBeenCalledWith ( new actions . Ready ( ) ) ;
585
+ expect ( mockAws . send ) . not . toHaveBeenCalledWith ( new actions . Ready ( ) , expect . anything ( ) ) ;
562
586
} ) ;
563
587
} )
564
588
@@ -692,4 +716,9 @@ describe('Client', () => {
692
716
await Promise . resolve ( ) ;
693
717
}
694
718
}
719
+
720
+ const SEND_OPTIONS = {
721
+ DEFAULT : { timeout : 0 } ,
722
+ TIMED : { timeout : 5000 } ,
723
+ } ;
695
724
} ) ;
0 commit comments