diff --git a/README.md b/README.md index e1de07d..0dd3e7b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@ Passing in the config overrides any default values or values set by bot-tester.j defaultAddress: botbuilder.IAddress, timeout: number // in milliseconds // each filter returns false for messages that the BotTester should ignore - messageFilters: ((message:IMessage) => boolean)[] + messageFilters: ((message:IMessage) => boolean)[], + ignoreTypingEvent: boolean, + ignoreEndOfConversationEvent: boolean } ``` if timeout is defined, then a particular ```runTest()``` call will fail if it does not receive each expected message within the timeout period of time set in the options. @@ -411,5 +413,18 @@ describe('BotTester', () => { .runTest() ).to.be.rejected.notify(done); }); + + it('can ignore typing events', () => { + bot.dialog('/', (session) => { + session.send('hello'); + session.sendTyping(); + session.send('goodbye'); + }); + + return new BotTester(bot) + .ignoreTypingEvent() + .sendMessageToBot('hey', 'hello', 'goodbye') + .runTest(); + }); }); ``` diff --git a/src/BotTester.ts b/src/BotTester.ts index 7521d61..c4207ba 100644 --- a/src/BotTester.ts +++ b/src/BotTester.ts @@ -1,5 +1,6 @@ import * as Promise from 'bluebird'; import { IAddress, IMessage, Message, Session, UniversalBot } from 'botbuilder'; +import { ignoreEndOfConversationEventFilter, ignoreTypingEventFilter } from './builtInMessageFilters'; import { config, IConfig, MessageFilter } from './config'; import { ExpectedMessage, PossibleExpectedMessageCollections, PossibleExpectedMessageType } from './ExpectedMessage'; import { botToUserMessageCheckerFunction, MessageService } from './MessageService'; @@ -24,6 +25,16 @@ export interface IOptionsModifier { * sets the timeout time that the BotTester will wait for any particular message before failing */ setTimeout(milliseconds: number): BotTester; + + /** + * adds prebuilt filter to ignore typing event + */ + ignoreTypingEvent(): BotTester; + + /** + * adds prebuilt filter to ignore endOfConversationEvent + */ + ignoreEndOfConversationEvent(): BotTester; } /** @@ -119,10 +130,30 @@ export class BotTester implements IBotTester, IOptionsModifier { return this; } + public ignoreEndOfConversationEvent(): BotTester { + this.config.ignoreEndOfConversationEvent = true; + + return this; + } + + public ignoreTypingEvent(): BotTester { + this.config.ignoreTypingEvent = true; + + return this; + } + /** * Initializes the MessegeService here to allow config changes to accumulate */ public runTest(): Promise<{}> { + if (this.config.ignoreTypingEvent) { + this.config.messageFilters.push(ignoreTypingEventFilter); + } + + if (this.config.ignoreEndOfConversationEvent) { + this.config.messageFilters.push(ignoreEndOfConversationEventFilter); + } + this.messageService = new MessageService(this.bot, this.config); return Promise.mapSeries(this.testSteps, (fn: TestStep) => fn()); diff --git a/src/ExpectedMessage.ts b/src/ExpectedMessage.ts index ed839e2..294ca54 100644 --- a/src/ExpectedMessage.ts +++ b/src/ExpectedMessage.ts @@ -1,4 +1,4 @@ -import { IMessage } from 'botbuilder'; +import { IMessage, IEvent } from 'botbuilder'; import { expect } from './assertionLibraries/IExpectation'; export enum ExpectedMessageType { @@ -10,7 +10,7 @@ export enum ExpectedMessageType { /** * Types accepted for responses checkers */ -export type PossibleExpectedMessageType = string | IMessage | RegExp; +export type PossibleExpectedMessageType = string | IMessage | RegExp | IEvent; /** * Response expectations area always collections. The collection is the set of possible responses, chosen at random. If the collection size diff --git a/src/MessageService.ts b/src/MessageService.ts index 7b10aa8..da4e8c3 100644 --- a/src/MessageService.ts +++ b/src/MessageService.ts @@ -87,7 +87,6 @@ export class MessageService { } catch (e) { return rej(e); } - }); if (!outgoingMessageComparator.expectsAdditionalMessages()) { diff --git a/src/builtInMessageFilters.ts b/src/builtInMessageFilters.ts new file mode 100644 index 0000000..b8129dd --- /dev/null +++ b/src/builtInMessageFilters.ts @@ -0,0 +1,13 @@ +import { IMessage } from 'botbuilder'; + +export function ignoreInternalSaveMessageFilter(message: IMessage): boolean { + return message.type !== '__save__'; +} + +export function ignoreEndOfConversationEventFilter(message: IMessage): boolean { + return message.type !== 'endOfConversation'; +} + +export function ignoreTypingEventFilter(message: IMessage): boolean { + return message.type !== 'typing'; +} diff --git a/src/config.ts b/src/config.ts index d911314..744f1fd 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,6 +16,16 @@ export interface IConfig { */ defaultAddress?: IAddress; + /** + * ignores typing event messages + */ + ignoreTypingEvent?: boolean; + + /** + * ignores end of conversation event messages + */ + ignoreEndOfConversationEvent?: boolean; + /** * filters for messages that the BotTester framework should use */ diff --git a/test/BotTester.spec.ts b/test/BotTester.spec.ts index d600457..ef9cb55 100644 --- a/test/BotTester.spec.ts +++ b/test/BotTester.spec.ts @@ -388,6 +388,19 @@ describe('BotTester', () => { .runTest() ).to.be.rejected.notify(done); }); + + it('can ignore typing events', () => { + bot.dialog('/', (session) => { + session.send('hello'); + session.sendTyping(); + session.send('goodbye'); + }); + + return new BotTester(bot) + .ignoreTypingEvent() + .sendMessageToBot('hey', 'hello', 'goodbye') + .runTest(); + }); }); //``` diff --git a/test/BotTesterFailure.spec.ts b/test/BotTesterFailure.spec.ts index 66ec045..37dcbd4 100644 --- a/test/BotTesterFailure.spec.ts +++ b/test/BotTesterFailure.spec.ts @@ -218,4 +218,39 @@ describe('BotTester', () => { .sendMessageToBot('intro', 'hello', 'how', 'are', 'you?') .runTest()).to.be.rejected.notify(done); }); + + it('will fail if a endOfConversationEvent is seen with an ingoreEndOfConversationEventFilter', (done: Function) => { + bot.dialog('/', (session: Session) => { + session.send('hello'); + session.endConversation(); + }); + + expect(new BotTester(bot) + // need to timeout before the tests do to catch the error + .setTimeout(500) + .ignoreEndOfConversationEvent() + //tslint:disable + .sendMessageToBot('hey', 'hello', {type: 'endOfConversation'} as any) + //tslint:enable + .runTest()) + .to.be.rejected.notify(done); + }); + + it('will fail if a typing event is seen with an ignoreTypingEventFilter', (done: Function) => { + bot.dialog('/', (session: Session) => { + session.send('hello'); + session.sendTyping(); + session.send('hey'); + }); + + expect(new BotTester(bot) + // need to timeout before the tests do to catch the error + .setTimeout(500) + .ignoreTypingEvent() + //tslint:disable + .sendMessageToBot('hey', 'hello', {type: 'typing'} as any, 'hey') + //tslint:enable + .runTest()) + .to.be.rejected.notify(done); + }); });