import test from 'ava' ; import { connect , ErrorCode , NatsConnectionOptions , Payload } from '../src/nats' ; import { Lock } from './helpers/latch' ; import { SC , startServer , stopServer } from './helpers/nats_server_control' ; import { next } from 'nuid' ; import { createInbox } from "../src/util" ; test . before ( async ( t ) => { let server = await startServer ( ) ; t . context = { server : server } ; } ) ; test . after . always ( ( t ) => { stopServer ( t . context . server ) ; } ) ; test ( 'connect no json propagates options' , async ( t ) => { t . plan ( 1 ) ; let sc = t . context as SC ; let nc = await connect ( { url : sc . server . nats } ) ; t . is ( nc . protocolHandler . payload , Payload . STRING , 'default payload' ) ; nc . close ( ) ; } ) ; test ( 'connect json propagates options' , async ( t ) => { t . plan ( 1 ) ; let sc = t . context as SC ; let nc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; t . is ( nc . protocolHandler . payload , Payload . JSON ) ; nc . close ( ) ; } ) ; test ( 'pubsub should fail circular json' , async ( t ) => { t . plan ( 1 ) ; let sc = t . context as SC ; let o = { } ; o . a = o ; let nc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; t . throws ( ( ) => { nc . publish ( next ( ) , o ) ; } , { code : ErrorCode . BAD_JSON } ) ; nc . close ( ) ; } ) ; test ( 'bad json error in callback' , async ( t ) => { t . plan ( 1 ) ; let sc = t . context as SC ; let o = { } ; o . a = o ; let jc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; jc . subscribe ( "bad_json" , ( err ) => { t . is ( err ?. code , ErrorCode . BAD_JSON ) ; } ) ; await jc . flush ( ) ; let nc = await connect ( { url : sc . server . nats } ) ; nc . publish ( "bad_json" , "" ) ; await nc . flush ( ) ; await jc . flush ( ) ; jc . close ( ) ; nc . close ( ) ; } ) ; test ( 'reqrep should fail circular json' , async ( t ) => { t . plan ( 1 ) ; let sc = t . context as SC ; let o = { } ; o . a = o ; let nc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; await t . throwsAsync ( nc . request ( next ( ) , 1000 , o ) , { code : ErrorCode . BAD_JSON } ) ; nc . close ( ) ; } ) ; async function pubsub ( t , input ) { t . plan ( 1 ) ; let lock = new Lock ( ) ; try { let sc = t . context as SC ; let nc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; let subj = next ( ) ; nc . subscribe ( subj , ( err , msg ) => { if ( err ) { t . fail ( err ) ; } if ( input === undefined ) { input = null ; } t . deepEqual ( msg . data , input ) ; lock . unlock ( ) ; } ) ; nc . publish ( subj , input ) ; } catch ( err ) { t . fail ( err ) ; lock . unlock ( ) ; } return lock . latch ; } async function reqrep ( t , input ) { t . plan ( 1 ) ; let lock = new Lock ( ) ; try { let sc = t . context as SC ; let nc = await connect ( { url : sc . server . nats , payload : Payload . JSON } ) ; let subj = next ( ) ; nc . subscribe ( subj , ( err , msg ) => { if ( msg . reply ) { nc . publish ( msg . reply , msg . data ) ; } } ) ; let msg = await nc . request ( subj , 500 , input ) ; if ( input === undefined ) { input = null ; } t . deepEqual ( msg . data , input ) ; lock . unlock ( ) ; } catch ( err ) { t . fail ( err ) ; lock . unlock ( ) ; } return lock . latch ; } const complex = { json : { field : 'hello' , body : 'world' } , empty_array : [ ] , array : [ 1 , - 2.3 , 'foo' , false ] , true : true , false : false , null : null , number : - 123.45 , empty_string : '' , string : 'abc' } ; test ( 'subscribe subject should be in subject ' , async ( t ) => { t . plan ( 2 ) ; let sc = t . context as SC ; let nc = await connect ( { url : sc . server . nats , payload : Payload . STRING } as NatsConnectionOptions ) ; let jnc = await connect ( { url : sc . server . nats , payload : Payload . JSON } as NatsConnectionOptions ) ; let prefix = createInbox ( ) ; let subj = `${ prefix }.*` ; await jnc . subscribe ( subj , ( err , msg ) => { t . truthy ( err ) ; t . is ( msg . subject , `${ prefix }.foo` ) ; } ) ; await jnc . flush ( ) ; nc . publish ( `${ prefix }.foo` ) ; await nc . flush ( ) ; await jnc . flush ( ) ; jnc . close ( ) ; nc . close ( ) ; } ) ; test ( 'string' , pubsub , 'helloworld' ) ; test ( 'empty' , pubsub , '' ) ; test ( 'null' , pubsub , null ) ; test ( 'undefined' , pubsub , undefined ) ; test ( 'number' , pubsub , 10 ) ; test ( 'false' , pubsub , false ) ; test ( 'true' , pubsub , true ) ; test ( 'empty array' , pubsub , [ ] ) ; test ( 'any array' , pubsub , [ 1 , 'a' , false , 3.1416 ] ) ; test ( 'empty object' , pubsub , { } ) ; test ( 'object' , pubsub , { a : 1 , b : false , c : 'name' , d : 3.1416 } ) ; test ( 'complex' , pubsub , complex ) ; test ( 'rr string' , reqrep , 'helloworld' ) ; test ( 'rr empty' , reqrep , '' ) ; test ( 'rr null' , reqrep , null ) ; test ( 'rr undefined' , reqrep , undefined ) ; test ( 'rr number' , reqrep , 10 ) ; test ( 'rr false' , reqrep , false ) ; test ( 'rr true' , reqrep , true ) ; test ( 'rr empty array' , reqrep , [ ] ) ; test ( 'rr any array' , reqrep , [ 1 , 'a' , false , 3.1416 ] ) ; test ( 'rr empty object' , reqrep , { } ) ; test ( 'rr object' , reqrep , { a : 1 , b : false , c : 'name' , d : 3.1416 } ) ; test ( 'rr complex' , reqrep , complex ) ;