import { TestScheduler } from 'rxjs/testing' ; import { of , throwError } from 'rxjs' ; import { delay , catchError , switchMap } from 'rxjs/operators' ; import connect , { normalClosureMessage , WebSocketLike } from '.' ; describe ( 'rxjs-websockets' , ( ) => { let scheduler ; let expect$ ; let flush ; let cold ; let hot ; beforeEach ( ( ) => { scheduler = new TestScheduler ( ( x , y ) => { expect ( x ) . toEqual ( y ) ; } ) ; expect$ = scheduler . expectObservable . bind ( scheduler ) ; flush = scheduler . flush . bind ( scheduler ) ; cold = scheduler . createColdObservable . bind ( scheduler ) ; hot = scheduler . createHotObservable . bind ( scheduler ) ; } ) ; class MockSocket { onmessage = ( event ) => { } ; onopen = ( event ) => { } ; onclose = ( event ) => { } ; onerror = ( event ) => { } ; close = jest . fn ( ) ; send ( data ) { this . onmessage ( { data } ) ; } } const connectHelper = ( mockSocket , protocols = [ ] ) => connect ( 'url' , { protocols , makeWebSocket : ( ) => mockSocket } ) ; it ( 'connects to websocket lazily and retrieves data' , ( ) => { const mockSocket = new MockSocket ( ) ; const socket = connectHelper ( mockSocket ) ; const input = hot ( 'abcde|' ) ; expect$ ( of ( null ) . pipe ( delay ( 10 , scheduler ) , switchMap ( ( ) => { return socket . pipe ( switchMap ( ( factory ) => { expect ( scheduler . now ( ) ) . toEqual ( 20 ) ; return factory ( input ) ; } ) ) ; } ) ) ) . toBe ( '--cde' ) ; scheduler . schedule ( ( ) => { if ( mockSocket . onopen ) mockSocket . onopen ( { } ) ; } , 20 ) ; flush ( ) ; } ) ; it ( 'closes websocket on unsubscribe' , ( ) => { const mockSocket = new MockSocket ( ) ; const socket = connectHelper ( mockSocket ) ; scheduler . schedule ( ( ) => mockSocket . onopen ( { } ) , 10 ) ; expect$ ( socket . pipe ( switchMap ( ( factory ) => factory ( cold ( 'a|' ) ) ) ) , '--!' ) . toBe ( '-a' ) ; flush ( ) ; expect ( mockSocket . close ) . toHaveBeenCalledTimes ( 1 ) ; } ) ; describe ( 'raises Error' , ( ) => { const runTest = ( reason , code , expectedReason ) => { const mockSocket = new MockSocket ( ) ; const socket = connectHelper ( mockSocket ) ; scheduler . schedule ( ( ) => mockSocket . onopen ( { } ) , 10 ) ; scheduler . schedule ( ( ) => mockSocket . onclose ( { reason , code } ) , 30 ) ; expect$ ( socket . pipe ( switchMap ( ( factory ) => factory ( cold ( 'a' ) ) ) , catchError ( ( error ) => throwError ( error . message ) ) ) ) . toBe ( '-a-#' , undefined , expectedReason ) ; flush ( ) ; } ; it ( 'with message equal to reason on unclean websocket close' , ( ) => { const reason = 'Freakish closure' ; runTest ( reason , 9000 , reason ) ; } ) ; it ( 'with normalClosureMessage when socket was closed normally' , ( ) => { runTest ( 'whatever' , 1000 , normalClosureMessage ) ; } ) ; } ) ; } ) ;