diff --git a/libraries/botbuilder-testing/src/dialogTestClient.ts b/libraries/botbuilder-testing/src/dialogTestClient.ts index 460e9fe6bf..4aa9da4a7e 100644 --- a/libraries/botbuilder-testing/src/dialogTestClient.ts +++ b/libraries/botbuilder-testing/src/dialogTestClient.ts @@ -6,9 +6,8 @@ * Licensed under the MIT License. */ - import { Activity, TestAdapter, Middleware, ConversationState, MemoryStorage, AutoSaveStateMiddleware, TurnContext } from 'botbuilder-core'; -import { Dialog, DialogSet, DialogTurnStatus, DialogTurnResult } from 'botbuilder-dialogs'; +import { Dialog, DialogContext, DialogSet, DialogTurnStatus, DialogTurnResult } from 'botbuilder-dialogs'; /** * A client for testing dialogs in isolation. @@ -16,8 +15,17 @@ import { Dialog, DialogSet, DialogTurnStatus, DialogTurnResult } from 'botbuild export class DialogTestClient { private readonly _callback: (turnContext: TurnContext) => Promise; + private _dialogContext: DialogContext = null; private readonly _testAdapter: TestAdapter; + + /** + * A DialogTurnResult instance with the result of the last turn. + */ public dialogTurnResult: DialogTurnResult; + + /** + * A ConversationState instance for the current test client. + */ public conversationState: ConversationState; /** @@ -40,7 +48,7 @@ export class DialogTestClient { */ public constructor(channelId: string, targetDialog: Dialog, initialDialogOptions?: any, middlewares?: Middleware[], conversationState?: ConversationState); public constructor(testAdapter: TestAdapter, targetDialog: Dialog, initialDialogOptions?: any, middlewares?: Middleware[], conversationState?: ConversationState) - constructor(channelOrAdapter: string|TestAdapter, targetDialog: Dialog, initialDialogOptions?: any, middlewares?: Middleware[], conversationState?: ConversationState) { + public constructor(channelOrAdapter: string|TestAdapter, targetDialog: Dialog, initialDialogOptions?: any, middlewares?: Middleware[], conversationState?: ConversationState) { this.conversationState = conversationState || new ConversationState(new MemoryStorage()); let dialogState = this.conversationState.createProperty('DialogState'); @@ -58,6 +66,15 @@ export class DialogTestClient { this.addUserMiddlewares(middlewares); } + /** + * Gets a reference for the DialogContext. + * @remarks + * This property will be null until at least one activity is sent to DialogTestClient. + */ + public get dialogContext(): DialogContext { + return this._dialogContext; + } + /** * Send an activity into the dialog. * @returns a TestFlow that can be used to assert replies etc @@ -75,31 +92,30 @@ export class DialogTestClient { /** * Get the next reply waiting to be delivered (if one exists) */ - public getNextReply() { + public getNextReply(): Partial { return this._testAdapter.activityBuffer.shift(); } private getDefaultCallback(targetDialog: Dialog, initialDialogOptions: any, dialogState: any): (turnContext: TurnContext) => Promise { - return async (turnContext: TurnContext) => { + return async (turnContext: TurnContext): Promise => { const dialogSet = new DialogSet(dialogState); dialogSet.add(targetDialog); - const dialogContext = await dialogSet.createContext(turnContext); - this.dialogTurnResult = await dialogContext.continueDialog(); + this._dialogContext = await dialogSet.createContext(turnContext); + this.dialogTurnResult = await this._dialogContext.continueDialog(); if (this.dialogTurnResult.status === DialogTurnStatus.empty) { - this.dialogTurnResult = await dialogContext.beginDialog(targetDialog.id, initialDialogOptions); + this.dialogTurnResult = await this._dialogContext.beginDialog(targetDialog.id, initialDialogOptions); } }; } private addUserMiddlewares(middlewares: Middleware[]): void { if (middlewares != null) { - middlewares.forEach((middleware) => { + middlewares.forEach((middleware): void => { this._testAdapter.use(middleware); }); } } - -} \ No newline at end of file +} diff --git a/libraries/botbuilder-testing/tests/dialogTestClient.test.js b/libraries/botbuilder-testing/tests/dialogTestClient.test.js index 8ab7c5b95a..240a9db486 100644 --- a/libraries/botbuilder-testing/tests/dialogTestClient.test.js +++ b/libraries/botbuilder-testing/tests/dialogTestClient.test.js @@ -5,7 +5,7 @@ const { DialogTestClient, DialogTestLogger } = require('../'); const { ComponentDialog, TextPrompt, WaterfallDialog, DialogTurnStatus, DialogSet } = require('botbuilder-dialogs'); -const assert = require('assert'); +const { ok: assert, strictEqual } = require('assert'); describe('DialogTestClient', function() { @@ -20,6 +20,23 @@ describe('DialogTestClient', function() { assert(client._testAdapter.template.channelId == 'custom', 'Created with wrong channel id'); }); + it('should set a dialogContext after an activity is received', async function() { + let dialog = new WaterfallDialog('waterfall', [ + async step => { + await step.context.sendActivity('hello'); + return step.endDialog(); + } + ]); + + let client = new DialogTestClient('test', dialog); + strictEqual(client.dialogContext, null); + let reply = await client.sendActivity('hello'); + assert(client.dialogContext, 'client.dialogContext not found'); + assert(reply.text == 'hello', 'dialog responded with incorrect message'); + assert(reply.channelId == 'test', 'test channel id didnt get set'); + assert(client.dialogTurnResult.status == DialogTurnStatus.complete, 'dialog did not end properly'); + }); + it('should process a single turn waterfall dialog', async function() { let dialog = new WaterfallDialog('waterfall', [