import * as Promise from 'bluebird' ; import { IAddress , IMessage , Message , Session , UniversalBot } from 'botbuilder' ; import { setTimeout } from 'timers' ; import { IConfig , MessageFilter , NO_TIMEOUT } from './config' ; import { ExpectedMessage } from './ExpectedMessage' ; import { OutgoingMessageComparator } from './OutgoingMessageComparator' ; export type botToUserMessageCheckerFunction = ( msg : IMessage | IMessage [ ] ) => void ; function expectedResponsesAreEmpty ( expectedResponses ) { return ! expectedResponses || ! expectedResponses . length || ! expectedResponses [ 0 ] . length ; } /**
 * Handles sending messages to bot, intercepts the responses, and compares the response to the expected responses for the particular test
 * step
 */ export class MessageService { private bot : UniversalBot ; private botToUserMessageChecker : botToUserMessageCheckerFunction ; private config : IConfig ; constructor ( bot , config ) { this . bot = bot ; this . applyOutgoingMessageListener ( ) ; this . botToUserMessageChecker = ( msg ) => { } ; this . config = config ; } param message param expectedResponses public sendMessageToBot ( message , expectedResponses , ignoreOrder = false ) { const outgoingMessageComparator = new OutgoingMessageComparator ( expectedResponses , ignoreOrder ) ; const responsesFullyProcessedPromise = this . setBotToUserMessageChecker ( expectedResponses , outgoingMessageComparator ) ; const receiveMessagePromise = new Promise < void > ( ( res , rej ) => { this . bot . receive ( message , ( e ) => e ? rej ( e ) : res ( ) ) ; } ) ; let promiseToReturn = expectedResponses && expectedResponses . length ? responsesFullyProcessedPromise : receiveMessagePromise ; if ( this . config . timeout !== NO_TIMEOUT ) { promiseToReturn = promiseToReturn . timeout ( this . config . timeout ) ; } return promiseToReturn . catch ( Promise . TimeoutError , ( e ) => { return Promise . reject ( outgoingMessageComparator . getTimeoutErrorMessage ( ) ) ; } ) ; } param expectedResponses private setBotToUserMessageChecker ( expectedResponses , outgoingMessageComparator ) { return new Promise < void > ( ( res , rej ) => { if ( ! outgoingMessageComparator . expectsAdditionalMessages ( ) ) { return res ( ) ; } this . botToUserMessageChecker = ( messages ) => { if ( ! ( messages instanceof Array ) ) { messages = [ messages ] ; } messages . forEach ( ( msg ) => { try { outgoingMessageComparator . compareOutgoingMessageToExpectedResponses ( msg ) ; } catch ( e ) { return rej ( e ) ; } } ) ; if ( ! outgoingMessageComparator . expectsAdditionalMessages ( ) ) { return res ( ) ; } } ; } ) ; } /**
     * Inject middleware to intercept outgoing messages to check their content
     */ private applyOutgoingMessageListener ( ) { this . bot . on ( 'outgoing' , ( outgoingMessages ) => { if ( ! ( outgoingMessages instanceof Array ) ) { outgoingMessages = [ outgoingMessages ] ; } this . config . messageFilters . forEach ( ( messageFilter ) => outgoingMessages = ( outgoingMessages as IMessage [ ] ) . filter ( messageFilter ) ) ; this . botToUserMessageChecker ( outgoingMessages ) ; } ) ; } }