@@ -12,6 +12,7 @@ import AbstractMicroservice from '@services/abstract-microservice';
1212import Microservice from '@services/microservice' ;
1313
1414const notSupposedMessage = 'was not supposed to succeed' ;
15+ const stopMsMessage = 'socket hang up' ;
1516
1617describe ( 'services/abstract-microservice' , ( ) => {
1718 const options = {
@@ -52,7 +53,7 @@ describe('services/abstract-microservice', () => {
5253 . resolves ( { data : task , method : 'POST' } )
5354 // Throw error for exit from infinite loop (stop worker)
5455 . onCall ( 1 )
55- . rejects ( { message : 'socket hang up' } ) ;
56+ . rejects ( { message : stopMsMessage } ) ;
5657
5758 await ms . start ( ) ;
5859 stubbed . restore ( ) ;
@@ -63,6 +64,14 @@ describe('services/abstract-microservice', () => {
6364 const testEndpoint = 'endpoint' ;
6465 const endpointHandler = ( ) => ( { hello : 'world' } ) ;
6566
67+ const rpcChannels = {
68+ $info : { } ,
69+ 'ms/demo' : { worker_ids : [ ] } ,
70+ 'ms/example' : { worker_ids : [ 'worker-id' ] } ,
71+ 'events/demo' : { worker_ids : [ ] } ,
72+ 'events/example' : { worker_ids : [ 'worker-id' ] } ,
73+ } ;
74+
6675 beforeEach ( ( ) => {
6776 sinon . stub ( process , 'exit' ) ;
6877 sinon . stub ( console , 'info' ) ;
@@ -436,16 +445,111 @@ describe('services/abstract-microservice', () => {
436445 } ) ;
437446
438447 it ( 'should correctly return list of registered microservices' , async ( ) => {
439- const channels = {
440- $info : { } ,
441- 'ms/demo' : { worker_ids : [ ] } ,
442- 'ms/example' : { worker_ids : [ 'worker-id' ] } ,
443- } ;
444- const stubbed = sinon . stub ( axios , 'request' ) . resolves ( { data : channels } ) ;
448+ const stubbed = sinon . stub ( axios , 'request' ) . resolves ( { data : rpcChannels } ) ;
445449
446450 expect ( await ms . lookup ( ) ) . to . deep . equal ( [ 'demo' , 'example' ] ) ;
447451 expect ( await ms . lookup ( true ) ) . to . deep . equal ( [ 'example' ] ) ;
448452
449453 stubbed . restore ( ) ;
450454 } ) ;
455+
456+ it ( 'should correctly return event channel prefix' , ( ) => {
457+ expect ( ms ) . to . have . property ( 'eventChannelPrefix' ) . to . equal ( ms . getEventChannelPrefix ( ) ) ;
458+ } ) ;
459+
460+ it ( 'should correctly add/get/remove event handler' , ( ) => {
461+ const handler = ( ) => true ;
462+ const channel = 'test.operations.channel' ;
463+
464+ ms . addEventHandler ( channel , handler ) ;
465+
466+ const isAdded = ms . getEventHandlers ( ) [ channel ] . indexOf ( handler ) !== - 1 ;
467+
468+ ms . removeEventHandler ( channel , handler ) ;
469+
470+ const isRemoved = ms . getEventHandlers ( ) [ channel ] . indexOf ( handler ) === - 1 ;
471+
472+ expect ( isAdded ) . to . ok ;
473+ expect ( isRemoved ) . to . ok ;
474+ } ) ;
475+
476+ it ( 'should correctly publish event' , async ( ) => {
477+ const stubbed = sinon
478+ . stub ( axios , 'request' )
479+ // return rpc channels
480+ . onCall ( 0 )
481+ . resolves ( { data : rpcChannels } )
482+ // send event on first channel successful
483+ . onCall ( 1 )
484+ . resolves ( { status : 200 } )
485+ // send event on second channel failed
486+ . onCall ( 2 )
487+ . rejects ( ) ;
488+ const testData = { test : 1 } ;
489+ const eventName = 'test.event' ;
490+
491+ const result = await Microservice . eventPublish ( eventName , testData ) ;
492+ const { url, data, headers } = stubbed . secondCall . firstArg ;
493+
494+ stubbed . restore ( ) ;
495+
496+ expect ( result ) . to . equal ( 1 ) ;
497+ expect ( url ) . to . equal ( `/${ ms . getEventChannelPrefix ( ) } /demo` ) ;
498+ expect ( headers ) . to . deep . equal ( { type : 'async' } ) ;
499+ expect ( data ) . to . deep . equal ( { ...testData , payload : { eventName, sender : options . name } } ) ;
500+ } ) ;
501+
502+ it ( 'should throw error when publish event' , async ( ) => {
503+ const message = 'publish event error' ;
504+ const stubbed = sinon . stub ( axios , 'request' ) . rejects ( new Error ( message ) ) ;
505+ const channel = 'test.error' ;
506+
507+ const result = await Microservice . eventPublish ( channel ) ;
508+
509+ stubbed . restore ( ) ;
510+
511+ expect ( result ) . to . equal ( message ) ;
512+ } ) ;
513+
514+ it ( 'should successful handle event' , async ( ) => {
515+ const eventName = 'sample.event' ;
516+ const eventParams = { sample : 'param' , payload : { sender : 'demo' , eventName } } ;
517+ const handler = sinon . stub ( ) ;
518+ const stubbedAxios = sinon
519+ . stub ( axios , 'request' )
520+ // unknown event, just skip
521+ . onCall ( 0 )
522+ . resolves ( { data : { } } )
523+ // unknown event worker error
524+ . onCall ( 1 )
525+ . rejects ( { message : 'unknown error' } )
526+ // successful event
527+ . onCall ( 2 )
528+ . resolves ( { data : eventParams } )
529+ // end
530+ . onCall ( 3 )
531+ . rejects ( { message : stopMsMessage } ) ;
532+ const clock = sinon . useFakeTimers ( ) ;
533+
534+ ms . addEventHandler ( eventName , handler ) ; // full match
535+ ms . addEventHandler ( 'sample.*' , handler ) ; // partial match
536+ ms . addEventHandler ( '*' , handler ) ; // listen all events
537+ ms . addEventHandler ( 'another.event.channel' , handler ) ;
538+
539+ ms [ 'options' ] [ 'workers' ] = 0 ; // temporary disable standard workers
540+
541+ const start = ms . start ( ) ;
542+
543+ await clock . tickAsync ( 5000 ) ;
544+ await start ;
545+
546+ clock . restore ( ) ;
547+ stubbedAxios . restore ( ) ;
548+ ms [ 'options' ] [ 'workers' ] = 1 ;
549+
550+ const receivedParams = handler . firstCall . firstArg ;
551+
552+ expect ( handler . getCalls ( ) . length ) . to . equal ( 3 ) ;
553+ expect ( receivedParams ) . to . deep . equal ( eventParams ) ;
554+ } ) ;
451555} ) ;
0 commit comments