UNPKG

@babblevoice/projectrtp

Version:
412 lines (344 loc) 13 kB
/* TODO More of our interface requires testing. Enough to ensure all data is passed over our proxy correctly. The correctness of a channel is tested in channel tests. */ const expect = require( "chai" ).expect const mockserver = require( "../mock/mockproxyserver" ) const prtp = require( "../../index" ).projectrtp const message = require( "../../lib/message" ) const node = require( "../../lib/node" ).interface describe( "rtpproxy node", function() { it( "connect to server", async function() { const ourstate = message.newstate() let completed const done = new Promise( ( r ) => completed = r ) const mock = new mockserver() await mock.listen() mock.onnewconnection( ( sock ) => { sock.on( "data", async ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { expect( msg ).to.have.property( "status" ).that.is.a( "object" ) expect( msg.status ).to.have.property( "workercount" ).that.is.a( "number" ) expect( msg.status ).to.have.property( "instance" ).that.is.a( "string" ) expect( msg.status ).to.have.property( "channel" ).that.is.a( "object" ) expect( msg.status.channel ).to.have.property( "available" ).that.is.a( "number" ) expect( msg.status.channel ).to.have.property( "current" ).that.is.a( "number" ) ournode.destroy() await mock.close() completed() } ) } ) } ) const ournode = await prtp.node.connect( mock.port, "127.0.0.1" ) await done } ) it( "connect to server then drop the re-go", async function() { this.timeout( 2000 ) this.slow( 1500 ) let completed const done = new Promise( ( r ) => completed = r ) const ourstate = message.newstate() const mock = new mockserver() await mock.listen() mock.onnewconnection( ( sock ) => { sock.on( "data", ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { expect( msg ).to.have.property( "status" ).that.is.a( "object" ) expect( msg.status ).to.have.property( "workercount" ).that.is.a( "number" ) expect( msg.status ).to.have.property( "instance" ).that.is.a( "string" ) expect( msg.status ).to.have.property( "channel" ).that.is.a( "object" ) expect( msg.status.channel ).to.have.property( "available" ).that.is.a( "number" ) expect( msg.status.channel ).to.have.property( "current" ).that.is.a( "number" ) /* drop the connection */ for( const sock in mock.socks ) { try{ mock.socks[ sock ].destroy() } catch( e ) { console.error( e ) } } if( 1 === connectcount ) completed() connectcount++ } ) } ) } ) let connectcount = 0 const ournode = await prtp.proxy.connect( mock.port ) await done ournode.destroy() await mock.close() } ) it( "connect and open channel", async function() { let completed const done = new Promise( ( r ) => completed = r ) const ourstate = message.newstate() const mock = new mockserver() await mock.listen() let state = "begin" mock.onnewconnection( ( sock ) => { sock.on( "data", async ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { switch( state ) { case "begin": { /* We should receive our status after connecting */ expect( msg ).to.have.property( "status" ).that.is.a( "object" ) expect( msg.status ).to.have.property( "workercount" ).that.is.a( "number" ) expect( msg.status ).to.have.property( "instance" ).that.is.a( "string" ) expect( msg.status ).to.have.property( "channel" ).that.is.a( "object" ) expect( msg.status.channel ).to.have.property( "available" ).that.is.a( "number" ) expect( msg.status.channel ).to.have.property( "current" ).that.is.a( "number" ) state = "open" sock.write( message.createmessage( { "id": "54", "channel": "open" } ) ) return } case "open": { /* a confirmed open message */ expect( msg ).to.have.property( "id" ).that.is.a( "string" ) expect( msg ).to.have.property( "uuid" ).that.is.a( "string" ) expect( msg ).to.have.property( "local" ).that.is.a( "object" ) expect( msg.local ).to.have.property( "port" ).that.is.a( "number" ) expect( msg.local ).to.have.property( "address" ).that.is.a( "string" ) expect( msg.local ).to.have.property( "dtls" ).that.is.a( "object" ) expect( msg.local.dtls ).to.have.property( "fingerprint" ).that.is.a( "string" ) expect( msg.local.dtls ).to.have.property( "enabled" ).that.is.a( "boolean" ) state = "close" sock.write( message.createmessage( { "id": msg.id, "channel": "close", "uuid": msg.uuid } ) ) return } case "close": { /* The fullness of this object is tested elsewhere - but confirm it is a close object we receive */ expect( msg ).to.have.property( "action" ).that.is.a( "string" ).to.be.equal( "close" ) expect( msg ).to.have.property( "id" ).that.is.a( "string" ) expect( msg ).to.have.property( "uuid" ).that.is.a( "string" ) expect( msg ).to.have.property( "stats" ).that.is.a( "object" ) expect( msg.stats ).to.have.property( "in" ).that.is.a( "object" ) expect( msg.stats ).to.have.property( "out" ).that.is.a( "object" ) expect( msg.stats ).to.have.property( "tick" ).that.is.a( "object" ) ournode.destroy() await mock.close() completed() } } } ) } ) } ) const ournode = await prtp.proxy.connect( mock.port ) await done } ) it( "connect and open channel and look for middle messages", async function() { const ourport = 45332 const ourserver = await prtp.server.listen( ourport, "127.0.0.1" ) const ournode = node.create( prtp ) const n = await ournode.connect( ourport, "127.0.0.1" ) const recvedmsgs = [] const chnl = await prtp.openchannel( ( e ) => { recvedmsgs.push( e ) } ) chnl.play( { "interupt":true, "files": [ { "wav": "test/interface/pcaps/180fa1ac-08e5-11ed-bd4d-02dba5b5aad6.wav" } ] } ) await new Promise( ( resolve ) => { setTimeout( () => resolve(), 100 ) } ) await chnl.close() await new Promise( ( resolve ) => { setTimeout( () => resolve(), 100 ) } ) n.destroy() await ourserver.destroy() expect( recvedmsgs[ 0 ].action ).to.equal( "play" ) expect( recvedmsgs[ 0 ].event ).to.equal( "start" ) expect( recvedmsgs[ 1 ].action ).to.equal( "play" ) expect( recvedmsgs[ 1 ].event ).to.equal( "end" ) expect( recvedmsgs[ 2 ].action ).to.equal( "close" ) } ) it( "bad method on node", async function() { let completed const done = new Promise( ( r ) => completed = r ) const ourstate = message.newstate() const mock = new mockserver() await mock.listen() let state = "begin" mock.onnewconnection( ( sock ) => { sock.on( "data", async ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { switch( state ) { case "begin": { state = "open" sock.write( message.createmessage( { "id": "54", "channel": "open" } ) ) return } case "open": { state = "close" sock.write( message.createmessage( { "id": msg.id, "channel": "blah", "uuid": msg.uuid } ) ) return } case "close": { expect( msg ).to.have.property( "id" ).that.is.a( "string" ) expect( msg ).to.have.property( "uuid" ).that.is.a( "string" ) expect( msg ).to.have.property( "error" ).that.is.a( "string" ) state = "closed" sock.write( message.createmessage( { "id": msg.id, "channel": "close", "uuid": msg.uuid } ) ) return } case "closed": { /* The fullness of this object is tested elsewhere - but confirm it is a close object we receive */ expect( msg ).to.have.property( "action" ).that.is.a( "string" ).to.be.equal( "close" ) ournode.destroy() await mock.close() completed() } } } ) } ) } ) const ournode = await prtp.proxy.connect( mock.port ) await done } ) it( "echo channel", async function() { let completed const done = new Promise( ( r ) => completed = r ) const ourstate = message.newstate() const mock = new mockserver() await mock.listen() let state = "begin" mock.onnewconnection( ( sock ) => { sock.on( "data", async ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { switch( state ) { case "begin": { state = "open" sock.write( message.createmessage( { "id": "54", "channel": "open" } ) ) return } case "open": { state = "close" sock.write( message.createmessage( { "id": msg.id, "channel": "echo", "uuid": msg.uuid } ) ) sock.write( message.createmessage( { "id": msg.id, "channel": "close", "uuid": msg.uuid } ) ) return } case "close": { /* The fullness of this object is tested elsewhere - but confirm it is a close object we receive */ expect( msg ).to.have.property( "action" ).that.is.a( "string" ).to.be.equal( "close" ) completed() } } } ) } ) } ) const ournode = await prtp.proxy.connect( mock.port ) await done ournode.destroy() await mock.close() } ) it( "echo with onpre and onpost", async function() { let completed const done = new Promise( ( r ) => completed = r ) const ourstate = message.newstate() const mock = new mockserver() await mock.listen() let state = "begin" mock.onnewconnection( ( sock ) => { sock.on( "data", async ( data ) => { message.parsemessage( ourstate, data, async ( msg ) => { switch( state ) { case "begin": { state = "open" sock.write( message.createmessage( { "id": "54", "channel": "open" } ) ) return } case "open": { state = "close" sock.write( message.createmessage( { "id": msg.id, "channel": "echo", "uuid": msg.uuid } ) ) sock.write( message.createmessage( { "id": msg.id, "channel": "close", "uuid": msg.uuid } ) ) return } case "close": { /* The fullness of this object is tested elsewhere - but confirm it is a close object we receive */ expect( msg ).to.have.property( "action" ).that.is.a( "string" ).to.be.equal( "close" ) ournode.destroy() await mock.close() expect( onprecount ).to.equal( 3 ) expect( onpostcount ).to.equal( 2 ) completed() } } } ) } ) } ) const ournode = await prtp.proxy.connect( mock.port ) let onprecount = 0 const expectedpremessages = [ { "channel": "open" }, { "channel": "echo" }, { "channel": "close" } ] /* The onpre and onpost methods registers callbacks which can be used by external framework before we action a command or sendback a responce. */ ournode.onpre( ( msg, cb ) => { expect( msg ).to.deep.include( expectedpremessages[ onprecount ] ) onprecount++ cb( msg ) } ) let onpostcount = 0 const expectedpostmessages = [ { "action": "open" }, { "action": "close" } ] ournode.onpost( ( msg, cb ) => { expect( msg ).to.deep.include( expectedpostmessages[ onpostcount ] ) onpostcount++ cb( msg ) } ) await done } ) } )