import createServer from '../websocket' ; import workers from './worker' ; import BlockchainLink from '../../src' ; const getMethod = ( instanceName ) => { let method ; switch ( instanceName ) { case 'blockfrost' : method = 'GET_BLOCK' ; break ; case 'ripple' : method = 'server_info' ; break ; default : method = 'getBlockHash' ; break ; } return method ; } ; workers . forEach ( instance => { describe ( `Connection ${ instance . name }` , ( ) => { let server ; let blockchain ; beforeEach ( async ( ) => { jest . setTimeout ( 20000 ) ; server = await createServer ( instance . name ) ; blockchain = new BlockchainLink ( { ... instance , server : [ `ws://localhost:${ server . options . port }` ] , debug : false , } ) ; } ) ; afterEach ( async ( ) => { await blockchain . disconnect ( ) ; blockchain . dispose ( ) ; await server . close ( ) ; } ) ; it ( 'Handle connection timeout' , async ( ) => { try { blockchain . settings . server = [ 'wss://google.com:11111' , 'wss://google.com:22222' ] ; blockchain . settings . timeout = 4000 ; await blockchain . connect ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/connect' ) ; expect ( error . message ) . toEqual ( 'All backends are down' ) ; } } ) ; it ( 'Handle message timeout' , async ( ) => { server . setFixtures ( [ { method : instance . name === 'ripple' ? 'server_info' : 'getInfo' , response : undefined , delay : 8000 , } , ] ) ; try { blockchain . settings . timeout = 4000 ; await blockchain . getInfo ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/websocket_timeout' ) ; } } ) ; it ( 'Handle ping (subscription)' , async ( ) => { const method = getMethod ( instance . name ) ; server . setFixtures ( [ { method , response : undefined } , { method , response : undefined } , ] ) ; blockchain . settings . pingTimeout = 2500 ; await blockchain . subscribe ( { type : 'block' } ) ; await new Promise ( resolve => setTimeout ( resolve , 6000 ) ) ; expect ( server . fixtures ) . toEqual ( [ ] ) ; } ) ; it ( 'Handle ping (keepAlive)' , async ( ) => { const method = getMethod ( instance . name ) ; server . setFixtures ( [ { method , response : undefined } , { method , response : undefined } , ] ) ; blockchain . settings . pingTimeout = 2500 ; blockchain . settings . keepAlive = true ; await blockchain . subscribe ( { type : 'block' } ) ; await blockchain . unsubscribe ( { type : 'block' } ) ; await new Promise ( resolve => setTimeout ( resolve , 6000 ) ) ; expect ( server . fixtures ) . toEqual ( [ ] ) ; } ) ; it ( 'Ping should not be called and websocket should be disconnected' , async ( ) => { const method = getMethod ( instance . name ) ; server . setFixtures ( [ { method , response : undefined } , { method , response : undefined } , ] ) ; const callback = jest . fn ( ) ; blockchain . on ( 'disconnected' , callback ) ; blockchain . settings . pingTimeout = 2500 ; await blockchain . subscribe ( { type : 'block' } ) ; await blockchain . unsubscribe ( { type : 'block' } ) ; await new Promise ( resolve => setTimeout ( resolve , 4000 ) ) ; expect ( callback ) . toHaveBeenCalled ( ) ; expect ( server . fixtures . length ) . toEqual ( 2 ) ; } ) ; it ( 'Handle connect event' , async ( done ) => { blockchain . on ( 'connected' , done ) ; const result = await blockchain . connect ( ) ; expect ( result ) . toEqual ( true ) ; } ) ; it ( 'Handle disconnect event' , async ( done ) => { blockchain . on ( 'disconnected' , done ) ; await blockchain . connect ( ) ; if ( instance . name === 'ripple' ) { setTimeout ( ( ) => blockchain . disconnect ( ) , 1000 ) ; } else { blockchain . disconnect ( ) ; } } ) ; it ( 'Connect (only one endpoint is valid)' , async ( ) => { if ( instance . name === 'blockfrost' ) return ; blockchain . settings . server = [ 'gibberish1' , 'gibberish2' , 'gibberish3' , 'gibberish4' , ] . concat ( blockchain . settings . server ) ; const result = await blockchain . connect ( ) ; expect ( result ) . toEqual ( true ) ; } ) ; it ( 'Connect error (no server field)' , async ( ) => { blockchain . settings . server = null ; try { await blockchain . connect ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/connect' ) ; } } ) ; it ( 'Connect error (server field empty array)' , async ( ) => { blockchain . settings . server = [ ] ; try { await blockchain . connect ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/connect' ) ; } } ) ; it ( 'Connect error (server field invalid type)' , async ( ) => { blockchain . settings . server = 1 ; try { await blockchain . connect ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/connect' ) ; } } ) ; it ( 'Disconnect without connection' , async ( ) => { const r = await blockchain . disconnect ( ) ; expect ( r ) . toEqual ( true ) ; } ) ; it ( 'Websocket connection closed without error before connection.open event' , async ( ) => { server . removeAllListeners ( 'connection' ) ; server . on ( 'connection' , ( ws ) => ws . close ( ) ) ; try { await blockchain . connect ( ) ; } catch ( error ) { expect ( error . code ) . toEqual ( 'blockchain_link/connect' ) ; } } ) ; it ( 'Connect error (server field with invalid values)' , async ( ) => { blockchain . settings . timeout = 4000 ; blockchain . settings . server = [ 'gibberish' , 'ws://gibberish' , 'http://gibberish' , 'https://gibberish/' , 1 , false , { foo : 'bar' } , ] ; try { await blockchain . connect ( ) ; } catch ( error ) { expect ( error . message ) . toEqual ( 'All backends are down' ) ; } } ) ; } ) ; } ) ;