* Fix eslint issues in botbuilder-dialogs (2/2) * Update botbuilder-dialogs.api doc
This commit is contained in:
Родитель
68f49bac42
Коммит
134d3673ab
|
@ -397,7 +397,7 @@ export enum DialogReason {
|
|||
replaceCalled = "replaceCalled"
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class DialogsBotComponent extends BotComponent {
|
||||
// (undocumented)
|
||||
configureServices(services: ServiceCollection, configuration: Configuration): void;
|
||||
|
|
|
@ -89,6 +89,7 @@ export class ChoiceFactory {
|
|||
* @param text (Optional) text of the message.
|
||||
* @param speak (Optional) SSML to speak for the message.
|
||||
* @param options (Optional) formatting options to use when rendering as a list.
|
||||
* @returns The created message activity.
|
||||
*/
|
||||
static forChannel(
|
||||
channelOrContext: string | TurnContext,
|
||||
|
@ -134,7 +135,6 @@ export class ChoiceFactory {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a message [Activity](xref:botframework-schema.Activity) that includes a [Choice](xref:botbuilder-dialogs.Choice) list that have been added as `HeroCard`'s.
|
||||
*
|
||||
|
@ -172,6 +172,7 @@ export class ChoiceFactory {
|
|||
* @param text (Optional) text of the message.
|
||||
* @param speak (Optional) SSML to speak for the message.
|
||||
* @param options (Optional) formatting options to tweak rendering of list.
|
||||
* @returns The created message activity.
|
||||
*/
|
||||
static inline(
|
||||
choices: (string | Choice)[],
|
||||
|
@ -222,6 +223,7 @@ export class ChoiceFactory {
|
|||
* @param text (Optional) text of the message.
|
||||
* @param speak (Optional) SSML to speak for the message.
|
||||
* @param options (Optional) formatting options to tweak rendering of list.
|
||||
* @returns The created message activity.
|
||||
*/
|
||||
static list(
|
||||
choices: (string | Choice)[],
|
||||
|
@ -263,6 +265,7 @@ export class ChoiceFactory {
|
|||
* @param choices List of choices to add.
|
||||
* @param text (Optional) text of the message.
|
||||
* @param speak (Optional) SSML to speak for the message.
|
||||
* @returns An activity with choices as suggested actions.
|
||||
*/
|
||||
static suggestedAction(choices: (string | Choice)[], text?: string, speak?: string): Partial<Activity> {
|
||||
// Map choices to actions
|
||||
|
@ -291,6 +294,7 @@ export class ChoiceFactory {
|
|||
* const choices = ChoiceFactory.toChoices(['red', 'green', 'blue']);
|
||||
* ```
|
||||
* @param choices List of choices to add.
|
||||
* @returns A list of choices.
|
||||
*/
|
||||
static toChoices(choices: (string | Choice)[] | undefined): Choice[] {
|
||||
return (choices || [])
|
||||
|
|
|
@ -130,6 +130,7 @@ export interface FoundChoice {
|
|||
* @param utterance The text or user utterance to search over. For an incoming 'message' activity you can simply use `context.activity.text`.
|
||||
* @param choices List of choices to search over.
|
||||
* @param options (Optional) options used to tweak the search that's performed.
|
||||
* @returns A list of found choices, sorted by most relevant first.
|
||||
*/
|
||||
export function findChoices(
|
||||
utterance: string,
|
||||
|
|
|
@ -78,9 +78,11 @@ export interface SortedValue {
|
|||
* functions like `findChoices()` and `recognizeChoices()` are layered above this function. In most
|
||||
* cases its easier to just call one of the higher level functions instead but this function contains
|
||||
* the fuzzy search algorithm that drives choice recognition.
|
||||
*
|
||||
* @param utterance The text or user utterance to search over.
|
||||
* @param values List of values to search over.
|
||||
* @param options (Optional) options used to tweak the search that's performed.
|
||||
* @returns A list of found values.
|
||||
*/
|
||||
// tslint:disable-next-line:max-func-body-length
|
||||
export function findValues(
|
||||
|
@ -233,7 +235,7 @@ export function findValues(
|
|||
const usedTokens: { [index: number]: boolean } = {};
|
||||
matches.forEach((match: ModelResult<FoundValue>) => {
|
||||
// Apply filters
|
||||
let add = !foundIndexes.hasOwnProperty(match.resolution.index);
|
||||
let add = !Object.prototype.hasOwnProperty.call(foundIndexes, match.resolution.index);
|
||||
for (let i: number = match.start; i <= match.end; i++) {
|
||||
if (usedTokens[i]) {
|
||||
add = false;
|
||||
|
|
|
@ -40,6 +40,7 @@ import { ModelResult } from './modelResult';
|
|||
* @param utterance The text or user utterance to search over. For an incoming 'message' activity you can simply use `context.activity.text`.
|
||||
* @param choices List of choices to search over.
|
||||
* @param options (Optional) options used to tweak the search that's performed.
|
||||
* @returns A list of found choices, sorted by most relevant first.
|
||||
*/
|
||||
export function recognizeChoices(
|
||||
utterance: string,
|
||||
|
@ -63,7 +64,7 @@ export function recognizeChoices(
|
|||
},
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// noop
|
||||
// TODO: Should this log an error or do something?
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import { Converter, ConverterFactory } from './converter';
|
|||
export abstract class Configurable {
|
||||
/**
|
||||
* Fluent method for configuring the object.
|
||||
*
|
||||
* @param config Configuration settings to apply.
|
||||
* @returns The [Configurable](xref:botbuilder-dialogs.Configurable) after the operation is complete.
|
||||
*/
|
||||
configure(config: Record<string, unknown>): this {
|
||||
for (const key in config) {
|
||||
|
@ -46,6 +48,10 @@ export abstract class Configurable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _property The key of the conditional selector configuration.
|
||||
* @returns The converter for the selector configuration.
|
||||
*/
|
||||
getConverter(_property: string): Converter | ConverterFactory {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Creates an inner dialog context for the containers active child.
|
||||
*
|
||||
* @param dc Parents dialog context.
|
||||
* @returns A new dialog context for the active child or `undefined` if there is no active child.
|
||||
*/
|
||||
|
@ -29,7 +30,9 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Finds a child dialog that was previously added to the container.
|
||||
*
|
||||
* @param dialogId ID of the dialog to lookup.
|
||||
* @returns The Dialog if found; otherwise null.
|
||||
*/
|
||||
findDialog(dialogId: string): Dialog | undefined {
|
||||
return this.dialogs.find(dialogId);
|
||||
|
@ -41,6 +44,7 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
|
|||
*
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
* @param e The event being raised.
|
||||
* @returns True if the event is handled by the current dialog and bubbling should stop.
|
||||
*/
|
||||
async onDialogEvent(dc: DialogContext, e: DialogEvent): Promise<boolean> {
|
||||
const handled = await super.onDialogEvent(dc, e);
|
||||
|
@ -104,6 +108,8 @@ export abstract class DialogContainer<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Get the current telemetry client.
|
||||
*
|
||||
* @returns The [BotTelemetryClient](xref:botbuilder.BotTelemetryClient) to use for logging.
|
||||
*/
|
||||
get telemetryClient(): BotTelemetryClient {
|
||||
return this._telemetryClient;
|
||||
|
|
|
@ -55,7 +55,8 @@ export async function runDialog(
|
|||
}
|
||||
|
||||
const dialogSet = new DialogSet(accessor);
|
||||
dialogSet.telemetryClient = context.turnState.get<BotTelemetryClient>(BotTelemetryClientKey) ?? dialog.telemetryClient;
|
||||
dialogSet.telemetryClient =
|
||||
context.turnState.get<BotTelemetryClient>(BotTelemetryClientKey) ?? dialog.telemetryClient;
|
||||
|
||||
dialogSet.add(dialog);
|
||||
|
||||
|
@ -64,6 +65,13 @@ export async function runDialog(
|
|||
await internalRun(context, dialog.id, dialogContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn.
|
||||
* @param dialogId The dialog ID.
|
||||
* @param dialogContext The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
|
||||
* @param dialogStateManagerConfiguration Configuration for the dialog state manager.
|
||||
* @returns {Promise<DialogTurnResult>} a promise resolving to the dialog turn result.
|
||||
*/
|
||||
export async function internalRun(
|
||||
context: TurnContext,
|
||||
dialogId: string,
|
||||
|
@ -174,8 +182,9 @@ async function innerRun(
|
|||
/**
|
||||
* Helper to determine if we should send an EoC to the parent or not.
|
||||
*
|
||||
* @param context
|
||||
* @param turnResult
|
||||
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for the turn.
|
||||
* @param turnResult The dialog turn result.
|
||||
* @returns True if should send EoC, otherwise false.
|
||||
*/
|
||||
export function shouldSendEndOfConversationToParent(context: TurnContext, turnResult: DialogTurnResult): boolean {
|
||||
if (!(turnResult.status == DialogTurnStatus.complete || turnResult.status == DialogTurnStatus.cancelled)) {
|
||||
|
@ -241,7 +250,8 @@ export function isFromParentToSkill(context: TurnContext): boolean {
|
|||
const sendStateSnapshotTrace = async (dialogContext: DialogContext): Promise<void> => {
|
||||
const adapter = dialogContext.context.adapter;
|
||||
const claimIdentity = dialogContext.context.turnState.get<ClaimsIdentity>(adapter.BotIdentityKey);
|
||||
const traceLabel = claimIdentity && SkillValidation.isSkillClaim(claimIdentity.claims) ? 'Skill State' : 'Bot State';
|
||||
const traceLabel =
|
||||
claimIdentity && SkillValidation.isSkillClaim(claimIdentity.claims) ? 'Skill State' : 'Bot State';
|
||||
|
||||
// Send trace of memory
|
||||
const snapshot = getActiveDialogContext(dialogContext).state.getMemorySnapshot();
|
||||
|
|
|
@ -95,6 +95,7 @@ export class DialogSet {
|
|||
/**
|
||||
* Returns a 32-bit hash of the all the `Dialog.version` values in the set.
|
||||
*
|
||||
* @returns A version that will change when any of the child dialogs version changes.
|
||||
* @remarks
|
||||
* This hash is persisted to state storage and used to detect changes to a dialog set.
|
||||
*/
|
||||
|
@ -123,17 +124,18 @@ export class DialogSet {
|
|||
* of "duplicate2".
|
||||
* @param dialog The dialog or prompt to add.
|
||||
* If a telemetryClient is present on the dialog set, it will be added to each dialog.
|
||||
* @returns The dialog set after the operation is complete.
|
||||
*/
|
||||
add<T extends Dialog>(dialog: T): this {
|
||||
if (!(dialog instanceof Dialog)) {
|
||||
throw new Error(`DialogSet.add(): Invalid dialog being added.`);
|
||||
throw new Error('DialogSet.add(): Invalid dialog being added.');
|
||||
}
|
||||
|
||||
// Ensure new version hash is computed
|
||||
this._version = undefined;
|
||||
|
||||
// Ensure dialogs ID is unique.
|
||||
if (this.dialogs.hasOwnProperty(dialog.id)) {
|
||||
if (Object.prototype.hasOwnProperty.call(this.dialogs, dialog.id)) {
|
||||
// If we are trying to add the same exact instance, it's not a name collision.
|
||||
// No operation required since the instance is already in the dialog set.
|
||||
if (this.dialogs[dialog.id] === dialog) {
|
||||
|
@ -143,9 +145,10 @@ export class DialogSet {
|
|||
// If we are adding a new dialog with a conflicting name, add a suffix to avoid
|
||||
// dialog name collisions.
|
||||
let nextSuffix = 2;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const suffixId = dialog.id + nextSuffix.toString();
|
||||
if (!this.dialogs.hasOwnProperty(suffixId)) {
|
||||
if (!Object.prototype.hasOwnProperty.call(this.dialogs, suffixId)) {
|
||||
dialog.id = suffixId;
|
||||
break;
|
||||
} else {
|
||||
|
@ -174,12 +177,14 @@ export class DialogSet {
|
|||
|
||||
/**
|
||||
* Creates a dialog context which can be used to work with the dialogs in the set.
|
||||
*
|
||||
* @param context Context for the current turn of conversation with the user.
|
||||
* @returns A promise representing the asynchronous operation.
|
||||
*/
|
||||
async createContext(context: TurnContext): Promise<DialogContext> {
|
||||
if (!this.dialogState) {
|
||||
throw new Error(
|
||||
`DialogSet.createContext(): the dialog set was not bound to a stateProperty when constructed.`
|
||||
'DialogSet.createContext(): the dialog set was not bound to a stateProperty when constructed.'
|
||||
);
|
||||
}
|
||||
const state: DialogState = await this.dialogState.get(context, { dialogStack: [] } as DialogState);
|
||||
|
@ -197,13 +202,16 @@ export class DialogSet {
|
|||
* const dialog = dialogs.find('greeting');
|
||||
* ```
|
||||
* @param dialogId ID of the dialog or prompt to lookup.
|
||||
* @returns The dialog if found; otherwise undefined.
|
||||
*/
|
||||
find(dialogId: string): Dialog | undefined {
|
||||
return this.dialogs.hasOwnProperty(dialogId) ? this.dialogs[dialogId] : undefined;
|
||||
return Object.prototype.hasOwnProperty.call(this.dialogs, dialogId) ? this.dialogs[dialogId] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the telemetry client for this dialog set and apply it to all current dialogs.
|
||||
*
|
||||
* @returns The [BotTelemetryClient](xref:botbuilder.BotTelemetryClient) to use for logging.
|
||||
*/
|
||||
get telemetryClient(): BotTelemetryClient {
|
||||
return this._telemetryClient;
|
||||
|
|
|
@ -28,7 +28,14 @@ import {
|
|||
|
||||
const InitialSettings = z.record(z.unknown());
|
||||
|
||||
/**
|
||||
* Bot component for bot Dialogs.
|
||||
*/
|
||||
export class DialogsBotComponent extends BotComponent {
|
||||
/**
|
||||
* @param services Services Collection to register.
|
||||
* @param configuration Configuration for the bot component.
|
||||
*/
|
||||
configureServices(services: ServiceCollection, configuration: Configuration): void {
|
||||
services.composeFactory<MemoryScope[]>('memoryScopes', (memoryScopes) => {
|
||||
const rootConfiguration = configuration.get();
|
||||
|
|
|
@ -22,6 +22,9 @@ export class DialogsComponentRegistration
|
|||
pathResolvers: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates an instance of the [DialogsComponentRegistration](xref:botbuilder-dialogs.DialogsComponentRegistration) class.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import { DialogContext } from './dialogContext';
|
|||
export interface TemplateInterface<T, D = Record<string, unknown>> {
|
||||
/**
|
||||
* Given the turn context bind to the data to create the object
|
||||
*
|
||||
* @param dialogContext DialogContext.
|
||||
* @param data Data to bind to.
|
||||
* @returns Instance of T.
|
||||
|
|
|
@ -19,6 +19,7 @@ import { WaterfallStepContext } from './waterfallStepContext';
|
|||
* ```TypeScript
|
||||
* type WaterfallStep<O extends object = {}> = (step: WaterfallStepContext<O>) => Promise<DialogTurnResult>;
|
||||
* ```
|
||||
*
|
||||
* @param O (Optional) type of dialog options passed into the step.
|
||||
* @param WaterfallStep.step Contextual information for the current step being executed.
|
||||
*/
|
||||
|
@ -91,12 +92,13 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Gets the dialog version, composed of the ID and number of steps.
|
||||
*
|
||||
* @returns Dialog version, composed of the ID and number of steps.
|
||||
*/
|
||||
getVersion(): string {
|
||||
// Simply return the id + number of steps to help detect when new steps have
|
||||
// been added to a given waterfall.
|
||||
return `${ this.id }:${ this.steps.length }`;
|
||||
return `${this.id}:${this.steps.length}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,6 +138,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
* helloDialog.addStep(this.helloWorldStep.bind(this));
|
||||
* ```
|
||||
* @param step Asynchronous step function to call.
|
||||
* @returns Waterfall dialog for fluent calls to `addStep()`.
|
||||
*/
|
||||
addStep(step: WaterfallStep<O>): this {
|
||||
this.steps.push(step);
|
||||
|
@ -145,6 +148,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Called when the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) is started and pushed onto the dialog stack.
|
||||
*
|
||||
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
|
||||
* @param options Optional, initial information to pass to the [Dialog](xref:botbuilder-dialogs.Dialog).
|
||||
* @returns A Promise representing the asynchronous operation.
|
||||
|
@ -177,6 +181,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
/**
|
||||
* Called when the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) is _continued_, where it is the active dialog and the
|
||||
* user replies with a new [Activity](xref:botframework-schema.Activity).
|
||||
*
|
||||
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
|
||||
* @returns A Promise representing the asynchronous operation.
|
||||
* @remarks
|
||||
|
@ -196,6 +201,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Called when a child [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog) completed its turn, returning control to this dialog.
|
||||
*
|
||||
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of the conversation.
|
||||
* @param reason [Reason](xref:botbuilder-dialogs.DialogReason) why the dialog resumed.
|
||||
* @param result Optional, value returned from the dialog that was called. The type
|
||||
|
@ -224,6 +230,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
* }
|
||||
* ```
|
||||
* @param step Context object for the waterfall step to execute.
|
||||
* @returns A promise with the DialogTurnResult.
|
||||
*/
|
||||
protected async onStep(step: WaterfallStepContext<O>): Promise<DialogTurnResult> {
|
||||
// Log Waterfall Step event.
|
||||
|
@ -242,6 +249,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Executes a step of the [WaterfallDialog](xref:botbuilder-dialogs.WaterfallDialog).
|
||||
*
|
||||
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
|
||||
* @param index The index of the current waterfall step to execute.
|
||||
* @param reason The [Reason](xref:botbuilder-dialogs.DialogReason) the waterfall step is being executed.
|
||||
|
@ -320,6 +328,7 @@ export class WaterfallDialog<O extends object = {}> extends Dialog<O> {
|
|||
|
||||
/**
|
||||
* Identifies the step name by its position index.
|
||||
*
|
||||
* @param index Step position
|
||||
* @returns A string that identifies the step name.
|
||||
*/
|
||||
|
|
|
@ -40,6 +40,7 @@ export interface WaterfallStepInfo<O extends object> {
|
|||
|
||||
/**
|
||||
* Called to skip to the next waterfall step.
|
||||
*
|
||||
* @param result (Optional) result to pass to the next step.
|
||||
*/
|
||||
onNext(result?: any): Promise<DialogTurnResult>;
|
||||
|
@ -47,6 +48,7 @@ export interface WaterfallStepInfo<O extends object> {
|
|||
|
||||
/**
|
||||
* Context object passed in to a `WaterfallStep`.
|
||||
*
|
||||
* @param O (Optional) type of options passed to the steps waterfall dialog in the call to `DialogContext.beginDialog()`.
|
||||
*/
|
||||
export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
||||
|
@ -54,6 +56,7 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
|
||||
/**
|
||||
* Creates a new WaterfallStepContext instance.
|
||||
*
|
||||
* @param dc The dialog context for the current turn of conversation.
|
||||
* @param info Values to initialize the step context with.
|
||||
*/
|
||||
|
@ -65,6 +68,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
|
||||
/**
|
||||
* The index of the current waterfall step being executed.
|
||||
*
|
||||
* @returns The index of the current waterfall step being executed.
|
||||
*/
|
||||
get index(): number {
|
||||
return this._info.index;
|
||||
|
@ -73,6 +78,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
/**
|
||||
* Any options passed to the steps waterfall dialog when it was started with
|
||||
* `DialogContext.beginDialog()`.
|
||||
*
|
||||
* @returns Any options the waterfall dialog was called with.
|
||||
*/
|
||||
get options(): O {
|
||||
return this._info.options;
|
||||
|
@ -80,6 +87,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
|
||||
/**
|
||||
* The reason the waterfall step is being executed.
|
||||
*
|
||||
* @returns The reason the waterfall step is being executed.
|
||||
*/
|
||||
get reason(): DialogReason {
|
||||
return this._info.reason;
|
||||
|
@ -87,6 +96,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
|
||||
/**
|
||||
* Results returned by a dialog or prompt that was called in the previous waterfall step.
|
||||
*
|
||||
* @returns The result from the previous waterfall step.
|
||||
*/
|
||||
get result(): any {
|
||||
return this._info.result;
|
||||
|
@ -94,6 +105,8 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
|
||||
/**
|
||||
* A dictionary of values which will be persisted across all waterfall steps.
|
||||
*
|
||||
* @returns A dictionary of values which will be persisted across all waterfall steps.
|
||||
*/
|
||||
get values(): object {
|
||||
return this._info.values;
|
||||
|
@ -108,6 +121,7 @@ export class WaterfallStepContext<O extends object = {}> extends DialogContext {
|
|||
* return await step.skip();
|
||||
* ```
|
||||
* @param result (Optional) result to pass to the next step.
|
||||
* @returns A promise with the DialogTurnResult.
|
||||
*/
|
||||
async next(result?: any): Promise<DialogTurnResult> {
|
||||
return await this._info.onNext(result);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-core');
|
||||
const { ActivityPrompt, DialogReason, DialogSet, DialogTurnStatus } = require('../');
|
||||
const { ActivityPrompt, DialogReason, DialogSet, DialogTurnStatus } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
class SimpleActivityPrompt extends ActivityPrompt {
|
||||
|
@ -17,7 +17,7 @@ describe('ActivityPrompt', function () {
|
|||
|
||||
it('should call ActivityPrompt using dc.prompt().', async function () {
|
||||
// Initialize TestAdapter.
|
||||
const adapter = new TestAdapter(async turnContext => {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
|
@ -35,13 +35,16 @@ describe('ActivityPrompt', function () {
|
|||
// Create a DialogState property, DialogSet and TextPrompt.
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
|
||||
assert(prompt, `validator missing PromptValidatorContext.`);
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return true;
|
||||
}));
|
||||
dialogs.add(
|
||||
new SimpleActivityPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, 'validator missing PromptValidatorContext.');
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please send an activity.')
|
||||
.send('test')
|
||||
.assertReply('You said test')
|
||||
|
@ -49,7 +52,7 @@ describe('ActivityPrompt', function () {
|
|||
});
|
||||
|
||||
it('should re-prompt with original prompt if validator returned false.', async function () {
|
||||
const adapter = new TestAdapter(async turnContext => {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
|
@ -65,13 +68,16 @@ describe('ActivityPrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
|
||||
assert(prompt, `validator missing PromptValidatorContext.`);
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return false;
|
||||
}));
|
||||
dialogs.add(
|
||||
new SimpleActivityPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, 'validator missing PromptValidatorContext.');
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return false;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please send an activity.')
|
||||
.send('test')
|
||||
.assertReply('Please send an activity.')
|
||||
|
@ -79,7 +85,7 @@ describe('ActivityPrompt', function () {
|
|||
});
|
||||
|
||||
it('should re-prompt with custom retryPrompt if validator returned false.', async function () {
|
||||
const adapter = new TestAdapter(async turnContext => {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
|
@ -95,36 +101,41 @@ describe('ActivityPrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
|
||||
assert(prompt, `validator missing PromptValidatorContext.`);
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return false;
|
||||
}));
|
||||
dialogs.add(
|
||||
new SimpleActivityPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, 'validator missing PromptValidatorContext.');
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
return false;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please send activity.')
|
||||
.send('test')
|
||||
.assertReply('Activity not received.')
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('should see attemptCount increment.', async function() {
|
||||
it('should see attemptCount increment.', async function () {
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
|
||||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
|
||||
dialogs.add(new SimpleActivityPrompt('prompt', async prompt => {
|
||||
assert(prompt, `validator missing PromptValidatorContext.`);
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
if (prompt.recognized.value.type !== ActivityTypes.Event) {
|
||||
prompt.context.sendActivity(`attemptCount ${ prompt.attemptCount }`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
const adapter = new TestAdapter(async turnContext => {
|
||||
|
||||
dialogs.add(
|
||||
new SimpleActivityPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, 'validator missing PromptValidatorContext.');
|
||||
assert(typeof prompt.recognized.value === 'object', 'recognized.value was not an object.');
|
||||
if (prompt.recognized.value.type !== ActivityTypes.Event) {
|
||||
prompt.context.sendActivity(`attemptCount ${prompt.attemptCount}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
|
@ -132,12 +143,13 @@ describe('ActivityPrompt', function () {
|
|||
await dc.prompt('prompt', { prompt: 'Please send activity.', retryPrompt: 'Activity not received.' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const reply = results.result.type;
|
||||
await turnContext.sendActivity(`You sent a(n) ${ reply }`);
|
||||
await turnContext.sendActivity(`You sent a(n) ${reply}`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
||||
await adapter.send('Hello')
|
||||
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please send activity.')
|
||||
.send('100')
|
||||
.assertReply('attemptCount 1')
|
||||
|
@ -146,7 +158,7 @@ describe('ActivityPrompt', function () {
|
|||
.send('300')
|
||||
.assertReply('attemptCount 3')
|
||||
.send({ type: ActivityTypes.Event })
|
||||
.assertReply(`You sent a(n) ${ ActivityTypes.Event }`)
|
||||
.assertReply(`You sent a(n) ${ActivityTypes.Event}`)
|
||||
.send('Another!')
|
||||
.assertReply('Please send activity.')
|
||||
.send('100')
|
||||
|
@ -156,11 +168,11 @@ describe('ActivityPrompt', function () {
|
|||
.send('300')
|
||||
.assertReply('attemptCount 3')
|
||||
.send({ type: ActivityTypes.Event })
|
||||
.assertReply(`You sent a(n) ${ ActivityTypes.Event }`)
|
||||
.assertReply(`You sent a(n) ${ActivityTypes.Event}`)
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('should not have resumeDialog() use the retry prompt.', async function() {
|
||||
it('should not have resumeDialog() use the retry prompt.', async function () {
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
|
@ -172,28 +184,30 @@ describe('ActivityPrompt', function () {
|
|||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
switch (turnContext.activity.text) {
|
||||
case 'begin':
|
||||
case 'begin': {
|
||||
const options = {
|
||||
prompt: 'please send an event.',
|
||||
retryPrompt: 'Retrying - please send an event.'
|
||||
retryPrompt: 'Retrying - please send an event.',
|
||||
};
|
||||
|
||||
await dc.prompt('prompt', options);
|
||||
break;
|
||||
|
||||
case 'continue':
|
||||
}
|
||||
case 'continue': {
|
||||
await prompt.continueDialog(dc);
|
||||
break;
|
||||
|
||||
case 'resume':
|
||||
}
|
||||
case 'resume': {
|
||||
await prompt.resumeDialog(dc, DialogReason.nextCalled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
||||
await adapter.send('begin')
|
||||
await adapter
|
||||
.send('begin')
|
||||
.assertReply('please send an event.')
|
||||
.send('continue')
|
||||
.assertReply('Retrying - please send an event.')
|
||||
|
|
|
@ -3,11 +3,11 @@ const { AttachmentPrompt, DialogSet, DialogTurnStatus } = require('../');
|
|||
const assert = require('assert');
|
||||
|
||||
const answerMessage = {
|
||||
text: `here you go`,
|
||||
text: 'here you go',
|
||||
type: 'message',
|
||||
attachments: [{ contentType: 'test', content: 'test1' }],
|
||||
};
|
||||
const invalidMessage = { text: `what?`, type: 'message' };
|
||||
const invalidMessage = { text: 'what?', type: 'message' };
|
||||
|
||||
describe('AttachmentPrompt', function () {
|
||||
this.timeout(5000);
|
||||
|
|
|
@ -3,8 +3,8 @@ const { ChoicePrompt, ChoiceFactory, DialogSet, ListStyle, DialogTurnStatus } =
|
|||
const { PromptCultureModels } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const answerMessage = { text: `red`, type: 'message' };
|
||||
const invalidMessage = { text: `purple`, type: 'message' };
|
||||
const answerMessage = { text: 'red', type: 'message' };
|
||||
const invalidMessage = { text: 'purple', type: 'message' };
|
||||
|
||||
const stringChoices = ['red', 'green', 'blue'];
|
||||
|
||||
|
@ -292,7 +292,7 @@ describe('ChoicePrompt', function () {
|
|||
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message, locale: undefined })
|
||||
.assertReply((activity) => {
|
||||
.assertReply(() => {
|
||||
assert('Please choose a color. (1) red, (2) green, o (3) blue');
|
||||
})
|
||||
.send(invalidMessage)
|
||||
|
|
|
@ -57,13 +57,13 @@ describe('channel methods', function () {
|
|||
assert.strictEqual(supportsCardActions(Channels.Skype, 5), false);
|
||||
});
|
||||
|
||||
it('should return true for supportsCardActions() with teams and 50', function (){
|
||||
it('should return true for supportsCardActions() with teams and 50', function () {
|
||||
assert.strictEqual(supportsCardActions(Channels.Msteams, 50), true);
|
||||
})
|
||||
});
|
||||
|
||||
it('should return false for supportsCardActions() with teams and 51', function (){
|
||||
it('should return false for supportsCardActions() with teams and 51', function () {
|
||||
assert.strictEqual(supportsCardActions(Channels.Msteams, 51), false);
|
||||
})
|
||||
});
|
||||
|
||||
it('should return the channelId from context.activity.', function () {
|
||||
assert.strictEqual(getChannelId({ activity: { channelId: Channels.Facebook } }), Channels.Facebook);
|
||||
|
|
|
@ -121,21 +121,21 @@ describe('The ChoiceFactory', function () {
|
|||
it('should render choices inline.', function () {
|
||||
const activity = ChoiceFactory.inline(colorChoices, 'select from:');
|
||||
assertActivity(activity, {
|
||||
text: `select from: (1) red, (2) green, or (3) blue`,
|
||||
text: 'select from: (1) red, (2) green, or (3) blue',
|
||||
});
|
||||
});
|
||||
|
||||
it('should render choices as a list.', function () {
|
||||
const activity = ChoiceFactory.list(colorChoices, 'select from:');
|
||||
assertActivity(activity, {
|
||||
text: `select from:\n\n 1. red\n 2. green\n 3. blue`,
|
||||
text: 'select from:\n\n 1. red\n 2. green\n 3. blue',
|
||||
});
|
||||
});
|
||||
|
||||
it('should render choices as suggested actions.', function () {
|
||||
const activity = ChoiceFactory.suggestedAction(colorChoices, 'select from:');
|
||||
assertActivity(activity, {
|
||||
text: `select from:`,
|
||||
text: 'select from:',
|
||||
suggestedActions: {
|
||||
actions: [
|
||||
{ type: 'imBack', value: 'red', title: 'red' },
|
||||
|
@ -204,7 +204,7 @@ describe('The ChoiceFactory', function () {
|
|||
it('should automatically choose render style based on channel type.', function () {
|
||||
const activity = ChoiceFactory.forChannel('emulator', colorChoices, 'select from:');
|
||||
assertActivity(activity, {
|
||||
text: `select from:`,
|
||||
text: 'select from:',
|
||||
suggestedActions: {
|
||||
actions: [
|
||||
{ type: 'imBack', value: 'red', title: 'red' },
|
||||
|
|
|
@ -63,21 +63,21 @@ describe('findValues()', function () {
|
|||
this.timeout(5000);
|
||||
|
||||
it('should find a simple value in an single word utterance.', function () {
|
||||
const found = findValues(`red`, colorValues);
|
||||
const found = findValues('red', colorValues);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 0, 2, 'red');
|
||||
assertValue(found[0], 'red', 0, 1.0);
|
||||
});
|
||||
|
||||
it('should find a simple value in an utterance.', function () {
|
||||
const found = findValues(`the red one please.`, colorValues);
|
||||
const found = findValues('the red one please.', colorValues);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 6, 'red');
|
||||
assertValue(found[0], 'red', 0, 1.0);
|
||||
});
|
||||
|
||||
it('should find multiple values within an utterance.', function () {
|
||||
const found = findValues(`the red and blue ones please.`, colorValues);
|
||||
const found = findValues('the red and blue ones please.', colorValues);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 6, 'red');
|
||||
assertValue(found[0], 'red', 0, 1.0);
|
||||
|
@ -85,7 +85,7 @@ describe('findValues()', function () {
|
|||
});
|
||||
|
||||
it('should find multiple values that overlap.', function () {
|
||||
const found = findValues(`the bread pudding and bread please.`, overlappingValues);
|
||||
const found = findValues('the bread pudding and bread please.', overlappingValues);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 16, 'bread pudding');
|
||||
assertValue(found[0], 'bread pudding', 1, 1.0);
|
||||
|
@ -93,7 +93,7 @@ describe('findValues()', function () {
|
|||
});
|
||||
|
||||
it('should correctly disambiguate between very similar values.', function () {
|
||||
const found = findValues(`option B`, similarValues, { allowPartialMatches: true });
|
||||
const found = findValues('option B', similarValues, { allowPartialMatches: true });
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertValue(found[0], 'option B', 1, 1.0);
|
||||
});
|
||||
|
@ -118,14 +118,14 @@ describe('findChoices()', function () {
|
|||
this.timeout(5000);
|
||||
|
||||
it('should find a single choice in an utterance.', function () {
|
||||
const found = findChoices(`the red one please.`, colorChoices);
|
||||
const found = findChoices('the red one please.', colorChoices);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 6, 'red');
|
||||
assertChoice(found[0], 'red', 0, 1.0, 'red');
|
||||
});
|
||||
|
||||
it('should find multiple choices within an utterance.', function () {
|
||||
const found = findChoices(`the red and blue ones please.`, colorChoices);
|
||||
const found = findChoices('the red and blue ones please.', colorChoices);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 6, 'red');
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
|
@ -133,7 +133,7 @@ describe('findChoices()', function () {
|
|||
});
|
||||
|
||||
it('should find multiple choices that overlap.', function () {
|
||||
const found = findChoices(`the bread pudding and bread please.`, overlappingChoices);
|
||||
const found = findChoices('the bread pudding and bread please.', overlappingChoices);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 16, 'bread pudding');
|
||||
assertChoice(found[0], 'bread pudding', 1, 1.0);
|
||||
|
@ -149,59 +149,59 @@ describe('recognizeChoices()', function () {
|
|||
this.timeout(5000);
|
||||
|
||||
it('should find a choice in an utterance by name.', function () {
|
||||
const found = recognizeChoices(`the red one please.`, colorChoices);
|
||||
const found = recognizeChoices('the red one please.', colorChoices);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 6, 'red');
|
||||
assertChoice(found[0], 'red', 0, 1.0, 'red');
|
||||
});
|
||||
|
||||
it('should find a choice in an utterance by ordinal position.', function () {
|
||||
const found = recognizeChoices(`the first one please.`, colorChoices);
|
||||
const found = recognizeChoices('the first one please.', colorChoices);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 4, 8, 'first');
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
});
|
||||
|
||||
it('should find multiple choices in an utterance by ordinal position.', function () {
|
||||
const found = recognizeChoices(`the first and third one please.`, colorChoices);
|
||||
const found = recognizeChoices('the first and third one please.', colorChoices);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
assertChoice(found[1], 'blue', 2, 1.0);
|
||||
});
|
||||
|
||||
it('should find a choice in an utterance by numerical index (as digit.)', function () {
|
||||
const found = recognizeChoices(`1`, colorChoices);
|
||||
const found = recognizeChoices('1', colorChoices);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 0, 0, '1');
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
});
|
||||
|
||||
it('should find a choice in an utterance by numerical index (as text.)', function () {
|
||||
const found = recognizeChoices(`one`, colorChoices);
|
||||
const found = recognizeChoices('one', colorChoices);
|
||||
assert(found.length === 1, `Invalid token count of '${found.length}' returned.`);
|
||||
assertResult(found[0], 0, 2, 'one');
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
});
|
||||
|
||||
it('should find multiple choices in an utterance by numerical index.', function () {
|
||||
const found = recognizeChoices(`option one and 3.`, colorChoices);
|
||||
const found = recognizeChoices('option one and 3.', colorChoices);
|
||||
assert(found.length === 2, `Invalid token count of '${found.length}' returned.`);
|
||||
assertChoice(found[0], 'red', 0, 1.0);
|
||||
assertChoice(found[1], 'blue', 2, 1.0);
|
||||
});
|
||||
|
||||
it('should not find a choice if recognizeOrdinals option disabled.', function () {
|
||||
const found = recognizeChoices(`first`, colorChoices, { recognizeOrdinals: false });
|
||||
const found = recognizeChoices('first', colorChoices, { recognizeOrdinals: false });
|
||||
assert(found.length === 0, `Invalid token count of '${found.length}' returned.`);
|
||||
});
|
||||
|
||||
it('should not find a choice if recognizeNumbers option disabled.', function () {
|
||||
const found = recognizeChoices(`1`, colorChoices, { recognizeNumbers: false });
|
||||
const found = recognizeChoices('1', colorChoices, { recognizeNumbers: false });
|
||||
assert(found.length === 0, `Invalid token count of '${found.length}' returned.`);
|
||||
});
|
||||
|
||||
it('should not find a choice if both recognizeOrdinals and recognizeNumbers options are disabled.', function () {
|
||||
const found = recognizeChoices(`the first and third one please.`, colorChoices, {
|
||||
const found = recognizeChoices('the first and third one please.', colorChoices, {
|
||||
recognizeOrdinals: false,
|
||||
recognizeNumbers: false,
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ describe('defaultTokenizer()', function () {
|
|||
this.timeout(5000);
|
||||
|
||||
it('should break on spaces.', function () {
|
||||
const tokens = defaultTokenizer(`how now brown cow`);
|
||||
const tokens = defaultTokenizer('how now brown cow');
|
||||
assert(tokens.length === 4);
|
||||
assertToken(tokens[0], 0, 2, 'how');
|
||||
assertToken(tokens[1], 4, 6, 'now');
|
||||
|
@ -24,7 +24,7 @@ describe('defaultTokenizer()', function () {
|
|||
});
|
||||
|
||||
it('should break on punctuation.', function () {
|
||||
const tokens = defaultTokenizer(`how-now.brown:cow?`);
|
||||
const tokens = defaultTokenizer('how-now.brown:cow?');
|
||||
assert(tokens.length === 4);
|
||||
assertToken(tokens[0], 0, 2, 'how');
|
||||
assertToken(tokens[1], 4, 6, 'now');
|
||||
|
@ -33,7 +33,7 @@ describe('defaultTokenizer()', function () {
|
|||
});
|
||||
|
||||
it('should tokenize single character tokens.', function () {
|
||||
const tokens = defaultTokenizer(`a b c d`);
|
||||
const tokens = defaultTokenizer('a b c d');
|
||||
assert(tokens.length === 4);
|
||||
assertToken(tokens[0], 0, 0, 'a');
|
||||
assertToken(tokens[1], 2, 2, 'b');
|
||||
|
@ -42,24 +42,24 @@ describe('defaultTokenizer()', function () {
|
|||
});
|
||||
|
||||
it('should return a single token.', function () {
|
||||
const tokens = defaultTokenizer(`food`);
|
||||
const tokens = defaultTokenizer('food');
|
||||
assert(tokens.length === 1);
|
||||
assertToken(tokens[0], 0, 3, 'food');
|
||||
});
|
||||
|
||||
it('should return no tokens.', function () {
|
||||
const tokens = defaultTokenizer(`.?;-()`);
|
||||
const tokens = defaultTokenizer('.?;-()');
|
||||
assert(tokens.length === 0);
|
||||
});
|
||||
|
||||
it('should return a the normalized and original text for a token.', function () {
|
||||
const tokens = defaultTokenizer(`fOoD`);
|
||||
const tokens = defaultTokenizer('fOoD');
|
||||
assert(tokens.length === 1);
|
||||
assertToken(tokens[0], 0, 3, 'fOoD', 'food');
|
||||
});
|
||||
|
||||
it('should break on emojis.', function () {
|
||||
const tokens = defaultTokenizer(`food 💥👍😀`);
|
||||
const tokens = defaultTokenizer('food 💥👍😀');
|
||||
assert(tokens.length === 4);
|
||||
assertToken(tokens[0], 0, 3, 'food');
|
||||
assertToken(tokens[1], 5, 6, '💥');
|
||||
|
|
|
@ -1,23 +1,31 @@
|
|||
const { ConversationState, MemoryStorage, TestAdapter, Severity } = require('botbuilder-core');
|
||||
const { Dialog, DialogReason, DialogSet, DialogTurnStatus, DialogContextError, ComponentDialog, WaterfallDialog } = require('../');
|
||||
const {
|
||||
Dialog,
|
||||
DialogReason,
|
||||
DialogSet,
|
||||
DialogTurnStatus,
|
||||
DialogContextError,
|
||||
ComponentDialog,
|
||||
WaterfallDialog,
|
||||
} = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
function simpleStepContextCheck(step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(typeof step === 'object', `step is not a WaterfallStepContext.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(typeof step === 'object', 'step is not a WaterfallStepContext.');
|
||||
}
|
||||
|
||||
describe('ComponentDialog', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
it('should set initial dialog to be first dialog added via addDialog()', function () {
|
||||
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async (step) => {}]);
|
||||
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async () => {}]);
|
||||
|
||||
const simpleH2ofall = new WaterfallDialog('simpleH2ofall', [async (step) => {}]);
|
||||
const simpleH2ofall = new WaterfallDialog('simpleH2ofall', [async () => {}]);
|
||||
|
||||
const component = new ComponentDialog('component');
|
||||
component.addDialog(simpleWaterfall);
|
||||
assert(component.initialDialogId === 'simpleWaterfall', `unexpected initialDialogId`);
|
||||
assert(component.initialDialogId === 'simpleWaterfall', 'unexpected initialDialogId');
|
||||
component.addDialog(simpleH2ofall);
|
||||
assert(
|
||||
component.initialDialogId === 'simpleWaterfall',
|
||||
|
@ -101,7 +109,7 @@ describe('ComponentDialog', function () {
|
|||
await adapter.send('Hi').startTest();
|
||||
});
|
||||
|
||||
it(`should return Dialog.EndOfTurn if the dialog's turnResult.status === 'waiting'.`, async function () {
|
||||
it("should return Dialog.EndOfTurn if the dialog's turnResult.status === 'waiting'.", async function () {
|
||||
const conversationState = new ConversationState(new MemoryStorage());
|
||||
const dialogState = conversationState.createProperty('dialog');
|
||||
|
||||
|
@ -135,12 +143,12 @@ describe('ComponentDialog', function () {
|
|||
});
|
||||
|
||||
it('should return any found dialogs.', function () {
|
||||
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async (step) => {}]);
|
||||
const simpleWaterfall = new WaterfallDialog('simpleWaterfall', [async () => {}]);
|
||||
|
||||
const component = new ComponentDialog('component');
|
||||
component.addDialog(simpleWaterfall);
|
||||
const dialog = component.findDialog('simpleWaterfall');
|
||||
assert(dialog === simpleWaterfall, `unexpected dialog returned`);
|
||||
assert(dialog === simpleWaterfall, 'unexpected dialog returned');
|
||||
});
|
||||
|
||||
it('should return undefined for not found dialogs.', function () {
|
||||
|
@ -383,7 +391,7 @@ describe('ComponentDialog', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(component);
|
||||
dialogs.telemetryClient = {
|
||||
trackEvent: function (telemetry) {},
|
||||
trackEvent: function () {},
|
||||
trackTrace: function (telemetry) {
|
||||
if (telemetry.severityLevel === Severity.Warning) {
|
||||
assert.equal(telemetry.message, 'Unhandled dialog event: versionChanged. Active Dialog: test');
|
||||
|
|
|
@ -2,9 +2,7 @@ const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require
|
|||
const { ConfirmPrompt, DialogSet, DialogTurnStatus, ListStyle } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const beginMessage = { text: `begin`, type: 'message' };
|
||||
const answerMessage = { text: `yes`, type: 'message' };
|
||||
const invalidMessage = { text: `what?`, type: 'message' };
|
||||
const invalidMessage = { text: 'what?', type: 'message' };
|
||||
|
||||
describe('ConfirmPrompt', function () {
|
||||
this.timeout(5000);
|
||||
|
@ -18,7 +16,7 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please confirm.' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -31,10 +29,11 @@ describe('ConfirmPrompt', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new ConfirmPrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('yes')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -46,7 +45,7 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please confirm. Yes or No' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -56,16 +55,17 @@ describe('ConfirmPrompt', function () {
|
|||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, `PromptValidatorContext not found.`);
|
||||
assert(prompt, 'PromptValidatorContext not found.');
|
||||
return prompt.recognized.succeeded;
|
||||
});
|
||||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -77,10 +77,10 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please confirm. Yes or No',
|
||||
retryPrompt: `Please reply with 'Yes' or 'No'.`
|
||||
retryPrompt: "Please reply with 'Yes' or 'No'.",
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -93,13 +93,13 @@ describe('ConfirmPrompt', function () {
|
|||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('what?')
|
||||
.assertReply(`Please reply with 'Yes' or 'No'.`)
|
||||
.assertReply("Please reply with 'Yes' or 'No'.")
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -111,10 +111,10 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please confirm. Yes or No',
|
||||
retryPrompt: `Please reply with 'Yes' or 'No'.`
|
||||
retryPrompt: "Please reply with 'Yes' or 'No'.",
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -124,18 +124,19 @@ describe('ConfirmPrompt', function () {
|
|||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, `PromptValidatorContext not found.`);
|
||||
assert(prompt, 'PromptValidatorContext not found.');
|
||||
return prompt.recognized.succeeded;
|
||||
});
|
||||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('what?')
|
||||
.assertReply(`Please reply with 'Yes' or 'No'.`)
|
||||
.assertReply("Please reply with 'Yes' or 'No'.")
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -147,10 +148,10 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please confirm. Yes or No',
|
||||
retryPrompt: `Please reply with 'Yes' or 'No'.`
|
||||
retryPrompt: "Please reply with 'Yes' or 'No'.",
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -160,22 +161,22 @@ describe('ConfirmPrompt', function () {
|
|||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt, `PromptValidatorContext not found.`);
|
||||
assert(prompt, 'PromptValidatorContext not found.');
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('The correct response is either yes or no. Please choose one.')
|
||||
await prompt.context.sendActivity('The correct response is either yes or no. Please choose one.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
});
|
||||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('what?')
|
||||
.assertReply('The correct response is either yes or no. Please choose one.')
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -187,7 +188,7 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.beginDialog('prompt');
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -200,13 +201,13 @@ describe('ConfirmPrompt', function () {
|
|||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('')
|
||||
.send('what?')
|
||||
.assertReply('')
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -218,10 +219,10 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please confirm. Yes or No',
|
||||
retryPrompt: `Please reply with 'Yes' or 'No'.`
|
||||
retryPrompt: "Please reply with 'Yes' or 'No'.",
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -234,13 +235,13 @@ describe('ConfirmPrompt', function () {
|
|||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send({ type: ActivityTypes.Message, attachments: ['ignoreThis']})
|
||||
.assertReply(`Please reply with 'Yes' or 'No'.`)
|
||||
.send({ type: ActivityTypes.Message, attachments: ['ignoreThis'] })
|
||||
.assertReply("Please reply with 'Yes' or 'No'.")
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -252,10 +253,10 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please confirm. Yes or No',
|
||||
retryPrompt: `Please reply with 'Yes' or 'No'.`
|
||||
retryPrompt: "Please reply with 'Yes' or 'No'.",
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -268,15 +269,15 @@ describe('ConfirmPrompt', function () {
|
|||
confirmPrompt.style = ListStyle.none;
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('')
|
||||
.assertReply('Please reply with \'Yes\' or \'No\'.')
|
||||
.assertReply("Please reply with 'Yes' or 'No'.")
|
||||
.send({ type: ActivityTypes.Message, text: null })
|
||||
.assertReply('Please reply with \'Yes\' or \'No\'.')
|
||||
.assertReply("Please reply with 'Yes' or 'No'.")
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -301,16 +302,21 @@ describe('ConfirmPrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
}, 'ja-jp');
|
||||
const confirmPrompt = new ConfirmPrompt(
|
||||
'prompt',
|
||||
async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
},
|
||||
'ja-jp'
|
||||
);
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send({ text: 'Hello', type: ActivityTypes.Message })
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message })
|
||||
.assertReply('Please confirm. (1) はい または (2) いいえ')
|
||||
.send(invalidMessage)
|
||||
.assertReply('bad input.')
|
||||
|
@ -349,7 +355,8 @@ describe('ConfirmPrompt', function () {
|
|||
});
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
.assertReply('Please confirm. (1) はい または (2) いいえ')
|
||||
.send({ text: 'いいえ', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
.assertReply('false')
|
||||
|
@ -377,16 +384,21 @@ describe('ConfirmPrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
}, 'es-es');
|
||||
const confirmPrompt = new ConfirmPrompt(
|
||||
'prompt',
|
||||
async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
},
|
||||
'es-es'
|
||||
);
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
.assertReply('Please confirm. (1) はい または (2) いいえ')
|
||||
.send({ text: 'いいえ', type: ActivityTypes.Message, locale: 'ja-jp' })
|
||||
.assertReply('false')
|
||||
|
@ -394,20 +406,10 @@ describe('ConfirmPrompt', function () {
|
|||
});
|
||||
|
||||
it('should recognize locale variations of correct locales', async function () {
|
||||
const locales = [
|
||||
'es-es',
|
||||
'nl-nl',
|
||||
'en-us',
|
||||
'fr-fr',
|
||||
'de-de',
|
||||
'ja-jp',
|
||||
'it-it',
|
||||
'pt-br',
|
||||
'zh-cn'
|
||||
];
|
||||
const locales = ['es-es', 'nl-nl', 'en-us', 'fr-fr', 'de-de', 'ja-jp', 'it-it', 'pt-br', 'zh-cn'];
|
||||
// es-ES
|
||||
const capEnding = (locale) => {
|
||||
return `${ locale.split('-')[0] }-${ locale.split('-')[1].toUpperCase() }`;
|
||||
return `${locale.split('-')[0]}-${locale.split('-')[1].toUpperCase()}`;
|
||||
};
|
||||
// es-Es
|
||||
const titleEnding = (locale) => {
|
||||
|
@ -430,61 +432,70 @@ describe('ConfirmPrompt', function () {
|
|||
capEnding(locale),
|
||||
titleEnding(locale),
|
||||
capTwoLetter(locale),
|
||||
lowerTwoLetter(locale)
|
||||
lowerTwoLetter(locale),
|
||||
];
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
// Test each valid locale
|
||||
await Promise.all(Object.keys(localeTests).map(async (validLocale) => {
|
||||
// Hold the correct answer from when a valid locale is used
|
||||
let expectedAnswer;
|
||||
// Test each of the test locales
|
||||
await Promise.all(localeTests[validLocale].map(async (testLocale) => {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please confirm.' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const confirmed = results.result;
|
||||
if (confirmed) {
|
||||
await turnContext.sendActivity('true');
|
||||
} else {
|
||||
await turnContext.sendActivity('false');
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
}, testLocale);
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: testLocale })
|
||||
.assertReply((activity) => {
|
||||
// if the valid locale is tested, save the answer because then we can test to see
|
||||
// if the test locales produce the same answer
|
||||
if (validLocale === testLocale) {
|
||||
expectedAnswer = activity.text;
|
||||
}
|
||||
assert.strictEqual(activity.text, expectedAnswer);
|
||||
await Promise.all(
|
||||
Object.keys(localeTests).map(async (validLocale) => {
|
||||
// Hold the correct answer from when a valid locale is used
|
||||
let expectedAnswer;
|
||||
// Test each of the test locales
|
||||
await Promise.all(
|
||||
localeTests[validLocale].map(async (testLocale) => {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please confirm.' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const confirmed = results.result;
|
||||
if (confirmed) {
|
||||
await turnContext.sendActivity('true');
|
||||
} else {
|
||||
await turnContext.sendActivity('false');
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt(
|
||||
'prompt',
|
||||
async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
},
|
||||
testLocale
|
||||
);
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message, locale: testLocale })
|
||||
.assertReply((activity) => {
|
||||
// if the valid locale is tested, save the answer because then we can test to see
|
||||
// if the test locales produce the same answer
|
||||
if (validLocale === testLocale) {
|
||||
expectedAnswer = activity.text;
|
||||
}
|
||||
assert.strictEqual(activity.text, expectedAnswer);
|
||||
})
|
||||
.startTest();
|
||||
})
|
||||
.startTest();
|
||||
}));
|
||||
}));
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should accept and recognize custom locale dict', async function() {
|
||||
it('should accept and recognize custom locale dict', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -509,7 +520,7 @@ describe('ConfirmPrompt', function () {
|
|||
locale: 'custom-custom',
|
||||
separator: 'customSeparator',
|
||||
noInLanguage: 'customNo',
|
||||
yesInLanguage: 'customYes'
|
||||
yesInLanguage: 'customYes',
|
||||
};
|
||||
|
||||
const customDict = {
|
||||
|
@ -519,23 +530,29 @@ describe('ConfirmPrompt', function () {
|
|||
inlineSeparator: culture.separator,
|
||||
inlineOr: culture.inlineOr,
|
||||
inlineOrMore: culture.inlineOrMore,
|
||||
includeNumbers: true
|
||||
}
|
||||
}
|
||||
includeNumbers: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
const confirmPrompt = new ConfirmPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
}, culture.locale, customDict);
|
||||
const confirmPrompt = new ConfirmPrompt(
|
||||
'prompt',
|
||||
async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('bad input.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
},
|
||||
culture.locale,
|
||||
customDict
|
||||
);
|
||||
dialogs.add(confirmPrompt);
|
||||
|
||||
await adapter.send({ text: 'Hello', type: ActivityTypes.Message, locale: culture.locale })
|
||||
await adapter
|
||||
.send({ text: 'Hello', type: ActivityTypes.Message, locale: culture.locale })
|
||||
.assertReply('Please confirm. (1) customYes customOr (2) customNo')
|
||||
.send('customYes')
|
||||
.assertReply('true')
|
||||
|
@ -550,7 +567,7 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt');
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -563,12 +580,13 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply(' (1) Yes or (2) No')
|
||||
.send('lala')
|
||||
.assertReply(' (1) Yes or (2) No')
|
||||
.send('yes')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -580,10 +598,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -596,18 +617,18 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('lala')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('should recognize valid number and default to en if locale is null.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
|
||||
turnContext.activity.locale = null;
|
||||
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
@ -616,10 +637,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -632,18 +656,18 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('lala')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('should recognize valid number and default to en if locale invalid string.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
|
||||
turnContext.activity.locale = 'invalid-locale';
|
||||
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
@ -652,10 +676,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -668,28 +695,31 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('lala')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
it('should recognize valid number and default to en if defaultLocale invalid string.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -702,15 +732,16 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('lala')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
||||
it('should not recognize invalid number when choiceOptions.includeNumbers is true.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
@ -719,10 +750,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -735,12 +769,13 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: true };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. (1) Yes or (2) No')
|
||||
.send('400')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. (1) Yes or (2) No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -752,10 +787,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -768,12 +806,13 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: false, inlineSeparator: '~' };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('1')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. Yes or No')
|
||||
.send('no')
|
||||
.assertReply(`The result found is 'false'.`)
|
||||
.assertReply("The result found is 'false'.")
|
||||
.startTest();
|
||||
});
|
||||
|
||||
|
@ -785,10 +824,13 @@ describe('ConfirmPrompt', function () {
|
|||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', {
|
||||
prompt: { text: 'Please confirm.', type: ActivityTypes.Message },
|
||||
retryPrompt: { text: 'Please confirm, say "yes" or "no" or something like that.', type: ActivityTypes.Message }
|
||||
retryPrompt: {
|
||||
text: 'Please confirm, say "yes" or "no" or something like that.',
|
||||
type: ActivityTypes.Message,
|
||||
},
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
await turnContext.sendActivity(`The result found is '${ results.result }'.`);
|
||||
await turnContext.sendActivity(`The result found is '${results.result}'.`);
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -801,12 +843,13 @@ describe('ConfirmPrompt', function () {
|
|||
prompt.choiceOptions = { includeNumbers: undefined };
|
||||
dialogs.add(prompt);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please confirm. Yes or No')
|
||||
.send('lala')
|
||||
.assertReply('Please confirm, say "yes" or "no" or something like that. Yes or No')
|
||||
.send('1')
|
||||
.assertReply(`The result found is 'true'.`)
|
||||
.assertReply("The result found is 'true'.")
|
||||
.startTest();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,9 +2,9 @@ const { ActivityTypes, ConversationState, MemoryStorage, TestAdapter } = require
|
|||
const { DateTimePrompt, DialogSet, DialogTurnStatus } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const answerMessage = { text: `January 1st, 2018 at 9am`, type: ActivityTypes.Message };
|
||||
const answerMessage2 = { text: `September 2nd, 2012`, type: ActivityTypes.Message };
|
||||
const invalidMessage = { text: `I am not sure`, type: ActivityTypes.Message };
|
||||
const answerMessage = { text: 'January 1st, 2018 at 9am', type: ActivityTypes.Message };
|
||||
const answerMessage2 = { text: 'September 2nd, 2012', type: ActivityTypes.Message };
|
||||
const invalidMessage = { text: 'I am not sure', type: ActivityTypes.Message };
|
||||
|
||||
describe('DatetimePrompt', function () {
|
||||
this.timeout(5000);
|
||||
|
@ -31,7 +31,8 @@ describe('DatetimePrompt', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(answerMessage)
|
||||
.assertReply('2018-01-01T09')
|
||||
|
@ -57,7 +58,8 @@ describe('DatetimePrompt', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(answerMessage)
|
||||
.assertReply('2018-01-01T09')
|
||||
|
@ -82,12 +84,15 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
}));
|
||||
dialogs.add(
|
||||
new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(answerMessage)
|
||||
.assertReply('2018-01-01T09')
|
||||
|
@ -100,7 +105,10 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please say something.', retryPrompt: 'Please provide a valid datetime.' });
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please say something.',
|
||||
retryPrompt: 'Please provide a valid datetime.',
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const dates = results.result;
|
||||
await turnContext.sendActivity(dates[0].timex);
|
||||
|
@ -112,12 +120,15 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
}));
|
||||
dialogs.add(
|
||||
new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(invalidMessage)
|
||||
.assertReply('Please provide a valid datetime.')
|
||||
|
@ -132,7 +143,10 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Please say something.', retryPrompt: 'Please provide a valid datetime.' });
|
||||
await dc.prompt('prompt', {
|
||||
prompt: 'Please say something.',
|
||||
retryPrompt: 'Please provide a valid datetime.',
|
||||
});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const dates = results.result;
|
||||
await turnContext.sendActivity(dates[0].timex);
|
||||
|
@ -144,15 +158,18 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('That was a bad date.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
}));
|
||||
dialogs.add(
|
||||
new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
if (!prompt.recognized.succeeded) {
|
||||
await prompt.context.sendActivity('That was a bad date.');
|
||||
}
|
||||
return prompt.recognized.succeeded;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(invalidMessage)
|
||||
.assertReply('That was a bad date.')
|
||||
|
@ -179,16 +196,14 @@ describe('DatetimePrompt', function () {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
}));
|
||||
dialogs.add(
|
||||
new DateTimePrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.succeeded;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
.send(invalidMessage)
|
||||
.send(answerMessage2)
|
||||
.assertReply('2012-09-02')
|
||||
.startTest();
|
||||
await adapter.send('Hello').send(invalidMessage).send(answerMessage2).assertReply('2012-09-02').startTest();
|
||||
});
|
||||
|
||||
it('should not recognize, then re-prompt without error for falsy input.', async function () {
|
||||
|
@ -213,7 +228,8 @@ describe('DatetimePrompt', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new DateTimePrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Enter a date.')
|
||||
.send('')
|
||||
.assertReply('Enter a date.')
|
||||
|
|
|
@ -2,7 +2,7 @@ const { ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-co
|
|||
const { DialogSet, Dialog, DialogTurnStatus } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const beginMessage = { text: `begin`, type: 'message' };
|
||||
const beginMessage = { text: 'begin', type: 'message' };
|
||||
|
||||
class TestDialog extends Dialog {
|
||||
constructor(dialogId) {
|
||||
|
@ -20,7 +20,7 @@ class TestDialog extends Dialog {
|
|||
return Dialog.EndOfTurn;
|
||||
}
|
||||
|
||||
async continueDialog(dc, options) {
|
||||
async continueDialog(dc, _options) {
|
||||
return await dc.endDialog(120);
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,7 @@ describe('Dialog', function () {
|
|||
const dialog = new TestDialog('testDialog');
|
||||
dialogs.add(dialog);
|
||||
|
||||
await adapter.send(beginMessage)
|
||||
.assertReply('begin called')
|
||||
.startTest();
|
||||
await adapter.send(beginMessage).assertReply('begin called').startTest();
|
||||
});
|
||||
|
||||
it('should receive dialog options when beginning a dialog from a dialog set.', async function () {
|
||||
|
@ -64,9 +62,7 @@ describe('Dialog', function () {
|
|||
const dialog = new TestDialog('testDialog');
|
||||
dialogs.add(dialog);
|
||||
|
||||
await adapter.send(beginMessage)
|
||||
.assertReply('begin called')
|
||||
.startTest();
|
||||
await adapter.send(beginMessage).assertReply('begin called').startTest();
|
||||
});
|
||||
|
||||
it('should continue() a multi-turn dialog.', async function () {
|
||||
|
@ -75,14 +71,15 @@ describe('Dialog', function () {
|
|||
|
||||
const results = await dc.continueDialog();
|
||||
switch (results.status) {
|
||||
case DialogTurnStatus.empty:
|
||||
case DialogTurnStatus.empty: {
|
||||
await dc.beginDialog('testDialog');
|
||||
break;
|
||||
|
||||
case DialogTurnStatus.complete:
|
||||
}
|
||||
case DialogTurnStatus.complete: {
|
||||
const finalResult = results.result;
|
||||
await turnContext.sendActivity(finalResult.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -94,10 +91,6 @@ describe('Dialog', function () {
|
|||
const dialog = new TestDialog('testDialog');
|
||||
dialogs.add(dialog);
|
||||
|
||||
await adapter.send(beginMessage)
|
||||
.assertReply('begin called')
|
||||
.send('continue')
|
||||
.assertReply('120')
|
||||
.startTest();
|
||||
await adapter.send(beginMessage).assertReply('begin called').send('continue').assertReply('120').startTest();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,8 +2,8 @@ const { ConversationState, MemoryStorage, TestAdapter } = require('botbuilder-co
|
|||
const { Dialog, DialogContextError, DialogSet, WaterfallDialog, DialogTurnStatus } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const beginMessage = { text: `begin`, type: 'message' };
|
||||
const continueMessage = { text: `continue`, type: 'message' };
|
||||
const beginMessage = { text: 'begin', type: 'message' };
|
||||
const continueMessage = { text: 'continue', type: 'message' };
|
||||
|
||||
describe('DialogContext', function () {
|
||||
this.timeout(5000);
|
||||
|
@ -15,7 +15,7 @@ describe('DialogContext', function () {
|
|||
|
||||
const results = await dc.beginDialog('a');
|
||||
if (results.status === DialogTurnStatus.complete) {
|
||||
assert(results.result === true, `End result from WaterfallDialog was not expected value.`);
|
||||
assert(results.result === true, 'End result from WaterfallDialog was not expected value.');
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -29,7 +29,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog(true);
|
||||
},
|
||||
])
|
||||
|
@ -44,7 +44,7 @@ describe('DialogContext', function () {
|
|||
|
||||
const results = await dc.beginDialog('a', { z: 'z' });
|
||||
if (results.status === DialogTurnStatus.complete) {
|
||||
assert(results.result === true, `End result from WaterfallDialog was not expected value.`);
|
||||
assert(results.result === true, 'End result from WaterfallDialog was not expected value.');
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
@ -56,8 +56,8 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step.options.z === 'z', `Correct DialogOptions was not passed in to WaterfallDialog.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert(step.options.z === 'z', 'Correct DialogOptions was not passed in to WaterfallDialog.');
|
||||
return await step.endDialog(true);
|
||||
},
|
||||
])
|
||||
|
@ -78,7 +78,7 @@ describe('DialogContext', function () {
|
|||
(err) => {
|
||||
assert.strictEqual(
|
||||
err.message,
|
||||
`DialogContext.beginDialog(): A dialog with an id of 'b' wasn't found.`,
|
||||
"DialogContext.beginDialog(): A dialog with an id of 'b' wasn't found.",
|
||||
`unexpected error message thrown: "${err.message}"`
|
||||
);
|
||||
|
||||
|
@ -119,11 +119,11 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert.strictEqual(
|
||||
step.options.prompt,
|
||||
'test',
|
||||
`promptOrOptions arg was not correctly passed through.`
|
||||
'promptOrOptions arg was not correctly passed through.'
|
||||
);
|
||||
return await step.endDialog();
|
||||
},
|
||||
|
@ -148,7 +148,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog();
|
||||
},
|
||||
])
|
||||
|
@ -172,9 +172,9 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(Array.isArray(step.options.choices), `choices received in step is not an array.`);
|
||||
assert.strictEqual(step.options.choices.length, 3, `not all choices were passed in.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert(Array.isArray(step.options.choices), 'choices received in step is not an array.');
|
||||
assert.strictEqual(step.options.choices.length, 3, 'not all choices were passed in.');
|
||||
return await step.endDialog();
|
||||
},
|
||||
])
|
||||
|
@ -189,7 +189,7 @@ describe('DialogContext', function () {
|
|||
|
||||
const results = await dc.beginDialog('a');
|
||||
await convoState.saveChanges(turnContext);
|
||||
assert.strictEqual(results.result, 119, `unexpected results.result value received from 'a' dialog.`);
|
||||
assert.strictEqual(results.result, 119, "unexpected results.result value received from 'a' dialog.");
|
||||
});
|
||||
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
|
@ -199,12 +199,12 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.beginDialog('b');
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert.strictEqual(step.result, 120, `incorrect step.result value received from 'b' dialog.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert.strictEqual(step.result, 120, "incorrect step.result value received from 'b' dialog.");
|
||||
return await step.endDialog(119);
|
||||
},
|
||||
])
|
||||
|
@ -213,7 +213,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog(120);
|
||||
},
|
||||
])
|
||||
|
@ -233,7 +233,7 @@ describe('DialogContext', function () {
|
|||
break;
|
||||
|
||||
case DialogTurnStatus.complete:
|
||||
assert.strictEqual(results.result, true, `received unexpected final result from dialog.`);
|
||||
assert.strictEqual(results.result, true, 'received unexpected final result from dialog.');
|
||||
break;
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
|
@ -246,12 +246,12 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
await step.context.sendActivity(`foo`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
await step.context.sendActivity('foo');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog(true);
|
||||
},
|
||||
])
|
||||
|
@ -278,13 +278,13 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert.strictEqual(step.activeDialog.id, 'a', `incorrect value for step.activeDialog.id`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert.strictEqual(step.activeDialog.id, 'a', 'incorrect value for step.activeDialog.id');
|
||||
step.activeDialog.id = 'b';
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(false, `shouldn't continue`);
|
||||
async function () {
|
||||
assert(false, "shouldn't continue");
|
||||
},
|
||||
])
|
||||
);
|
||||
|
@ -292,10 +292,10 @@ describe('DialogContext', function () {
|
|||
await assert.rejects(
|
||||
async () => await adapter.send(beginMessage).send(continueMessage).startTest(),
|
||||
(err) => {
|
||||
assert(err, `Error not found.`);
|
||||
assert(err, 'Error not found.');
|
||||
assert.strictEqual(
|
||||
err.message,
|
||||
`DialogContext.continueDialog(): Can't continue dialog. A dialog with an id of 'b' wasn't found.`,
|
||||
"DialogContext.continueDialog(): Can't continue dialog. A dialog with an id of 'b' wasn't found.",
|
||||
`unexpected error message thrown: "${err.message}"`
|
||||
);
|
||||
|
||||
|
@ -306,12 +306,12 @@ describe('DialogContext', function () {
|
|||
);
|
||||
});
|
||||
|
||||
it(`should return a DialogTurnResult if continue() is called without an activeDialog.`, async function () {
|
||||
it('should return a DialogTurnResult if continue() is called without an activeDialog.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
const results = await dc.continueDialog();
|
||||
assert.strictEqual(typeof results, 'object', `results is not the expected object`);
|
||||
assert.strictEqual(results.status, DialogTurnStatus.empty, `results.status is not 'empty'.`);
|
||||
assert.strictEqual(typeof results, 'object', 'results is not the expected object');
|
||||
assert.strictEqual(results.status, DialogTurnStatus.empty, "results.status is not 'empty'.");
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
||||
|
@ -328,7 +328,7 @@ describe('DialogContext', function () {
|
|||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.beginDialog('a');
|
||||
assert.strictEqual(results.result, true, `received unexpected final result from dialog.`);
|
||||
assert.strictEqual(results.result, true, 'received unexpected final result from dialog.');
|
||||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
||||
|
@ -340,13 +340,13 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.beginDialog('b');
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step.context.activity.text, 'begin', `unexpected message received.`);
|
||||
assert(step.result, `ended dialog.`, `unexpected step.result received.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert(step.context.activity.text, 'begin', 'unexpected message received.');
|
||||
assert(step.result, 'ended dialog.', 'unexpected step.result received.');
|
||||
return await step.endDialog(true);
|
||||
},
|
||||
])
|
||||
|
@ -355,7 +355,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog('ended dialog.');
|
||||
},
|
||||
])
|
||||
|
@ -364,17 +364,17 @@ describe('DialogContext', function () {
|
|||
await adapter.send(beginMessage).startTest();
|
||||
});
|
||||
|
||||
it(`should accept calls to end when no activeDialogs or parent dialogs exist.`, async function () {
|
||||
it('should accept calls to end when no activeDialogs or parent dialogs exist.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.endDialog();
|
||||
await convoState.saveChanges(turnContext);
|
||||
assert.strictEqual(results.status, DialogTurnStatus.complete, `results.status not equal 'complete'.`);
|
||||
assert.strictEqual(results.status, DialogTurnStatus.complete, "results.status not equal 'complete'.");
|
||||
assert.strictEqual(
|
||||
results.result,
|
||||
undefined,
|
||||
`received unexpected value for results.result (expected undefined).`
|
||||
'received unexpected value for results.result (expected undefined).'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -386,7 +386,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.replaceDialog('b', { z: step.options.z });
|
||||
},
|
||||
])
|
||||
|
@ -395,13 +395,13 @@ describe('DialogContext', function () {
|
|||
await adapter.send(beginMessage).startTest();
|
||||
});
|
||||
|
||||
it(`should replace() dialog.`, async function () {
|
||||
it('should replace() dialog.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
const results = await dc.beginDialog('a', { z: 'z' });
|
||||
await convoState.saveChanges(turnContext);
|
||||
assert.strictEqual(results.result, 'z', `received unexpected final result from dialog.`);
|
||||
assert.strictEqual(results.result, 'z', 'received unexpected final result from dialog.');
|
||||
});
|
||||
|
||||
const convoState = new ConversationState(new MemoryStorage());
|
||||
|
@ -412,7 +412,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.replaceDialog('b', { z: step.options.z });
|
||||
},
|
||||
])
|
||||
|
@ -421,9 +421,9 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert.strictEqual(step.stack.length, 1, `current DialogContext.stack.length should be 1.`);
|
||||
assert.strictEqual(step.options.z, 'z', `incorrect step.options received.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
assert.strictEqual(step.stack.length, 1, 'current DialogContext.stack.length should be 1.');
|
||||
assert.strictEqual(step.options.z, 'z', 'incorrect step.options received.');
|
||||
return await step.endDialog(step.options.z);
|
||||
},
|
||||
])
|
||||
|
@ -432,7 +432,7 @@ describe('DialogContext', function () {
|
|||
await adapter.send(beginMessage).startTest();
|
||||
});
|
||||
|
||||
it(`should begin dialog if stack empty when replaceDialog() called with valid dialogId.`, async function () {
|
||||
it('should begin dialog if stack empty when replaceDialog() called with valid dialogId.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -447,7 +447,7 @@ describe('DialogContext', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `WaterfallStepContext not passed in to WaterfallStep.`);
|
||||
assert(step, 'WaterfallStepContext not passed in to WaterfallStep.');
|
||||
return await step.endDialog();
|
||||
},
|
||||
])
|
||||
|
|
|
@ -179,7 +179,7 @@ class ComponentDialogWithCancellation extends ComponentDialog {
|
|||
describe('runDialog()', function () {
|
||||
this.timeout(300);
|
||||
|
||||
describe('parameter validation', () => {
|
||||
describe('parameter validation', function () {
|
||||
it('should throw if missing dialog parameter', async function () {
|
||||
await assert.rejects(async () => runDialog(), {
|
||||
message: 'runDialog(): missing dialog',
|
||||
|
@ -205,7 +205,7 @@ describe('runDialog()', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('HandlesBotAndSkillsTestCases', () => {
|
||||
describe('HandlesBotAndSkillsTestCases', function () {
|
||||
this.beforeEach(() => {
|
||||
_eocSent = undefined;
|
||||
});
|
||||
|
@ -231,25 +231,25 @@ describe('runDialog()', function () {
|
|||
}
|
||||
}
|
||||
|
||||
it('rootBotOnly, no sent EoC', async () => {
|
||||
it('rootBotOnly, no sent EoC', async function () {
|
||||
await handlesBotAndSkillsTestCases(FlowTestCase.RootBotOnly, false);
|
||||
});
|
||||
|
||||
it('rootBotConsumingSkill, no sent EoC', async () => {
|
||||
it('rootBotConsumingSkill, no sent EoC', async function () {
|
||||
await handlesBotAndSkillsTestCases(FlowTestCase.RootBotConsumingSkill, false);
|
||||
});
|
||||
|
||||
it('middleSkill, sent EoC', async () => {
|
||||
it('middleSkill, sent EoC', async function () {
|
||||
await handlesBotAndSkillsTestCases(FlowTestCase.MiddleSkill, true);
|
||||
});
|
||||
|
||||
it('leafSkill, sent EoC', async () => {
|
||||
it('leafSkill, sent EoC', async function () {
|
||||
await handlesBotAndSkillsTestCases(FlowTestCase.LeafSkill, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('HandlesEarlyDialogEndings', () => {
|
||||
it('handles premature dialog ending', async () => {
|
||||
describe('HandlesEarlyDialogEndings', function () {
|
||||
it('handles premature dialog ending', async function () {
|
||||
const dialog = new ComponentDialogWithPrematureEnd();
|
||||
const testFlow = createTestFlow(dialog, FlowTestCase.MiddleSkill);
|
||||
await testFlow.send('Hi').startTest();
|
||||
|
@ -259,7 +259,7 @@ describe('runDialog()', function () {
|
|||
assert.strictEqual(_eocSent.type, ActivityTypes.EndOfConversation);
|
||||
assert.strictEqual(_eocSent.code, EndOfConversationCodes.CompletedSuccessfully);
|
||||
});
|
||||
it('handles premature dialog cancellation', async () => {
|
||||
it('handles premature dialog cancellation', async function () {
|
||||
const dialog = new ComponentDialogWithCancellation();
|
||||
const testFlow = createTestFlow(dialog, FlowTestCase.MiddleSkill);
|
||||
await testFlow.send('Hi').startTest();
|
||||
|
|
|
@ -2,8 +2,8 @@ const { ConversationState, MemoryStorage, TestAdapter, NullTelemetryClient } = r
|
|||
const { Dialog, DialogSet, WaterfallDialog, DialogTurnStatus, ComponentDialog } = require('../');
|
||||
const assert = require('assert');
|
||||
|
||||
const beginMessage = { text: `begin`, type: 'message' };
|
||||
const continueMessage = { text: `continue`, type: 'message' };
|
||||
const beginMessage = { text: 'begin', type: 'message' };
|
||||
const continueMessage = { text: 'continue', type: 'message' };
|
||||
|
||||
describe('DialogSet', function () {
|
||||
this.timeout(5000);
|
||||
|
@ -54,8 +54,8 @@ describe('DialogSet', function () {
|
|||
},
|
||||
])
|
||||
);
|
||||
assert(dialogs.find('A'), `dialog A not found.`);
|
||||
assert(dialogs.find('B'), `dialog B not found.`);
|
||||
assert(dialogs.find('A'), 'dialog A not found.');
|
||||
assert(dialogs.find('B'), 'dialog B not found.');
|
||||
});
|
||||
|
||||
it('should increment the dialog ID when adding the same dialog twice.', function () {
|
||||
|
@ -65,15 +65,15 @@ describe('DialogSet', function () {
|
|||
dialogs.add(new WaterfallDialog('a', [function () {}]));
|
||||
|
||||
assert(dialogs.find('a'));
|
||||
assert(dialogs.find('a2'), `second dialog didn't have ID incremented`);
|
||||
assert(dialogs.find('a2'), "second dialog didn't have ID incremented");
|
||||
});
|
||||
|
||||
it('should find() a dialog that was added.', function () {
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new WaterfallDialog('a', [function () {}]));
|
||||
|
||||
assert(dialogs.find('a'), `dialog not found.`);
|
||||
assert(!dialogs.find('b'), `dialog found that shouldn't exist.`);
|
||||
assert(dialogs.find('a'), 'dialog not found.');
|
||||
assert(!dialogs.find('b'), "dialog found that shouldn't exist.");
|
||||
});
|
||||
|
||||
it('should save dialog stack state between turns.', async function () {
|
||||
|
@ -85,7 +85,7 @@ describe('DialogSet', function () {
|
|||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step);
|
||||
await step.context.sendActivity(`Greetings`);
|
||||
await step.context.sendActivity('Greetings');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
|
@ -117,17 +117,17 @@ describe('DialogSet', function () {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new WaterfallDialog('A')).add(new WaterfallDialog('B'));
|
||||
const hash = dialogs.getVersion();
|
||||
assert(hash && hash.length > 0, `no hash generated.`);
|
||||
assert(hash && hash.length > 0, 'no hash generated.');
|
||||
});
|
||||
|
||||
it('Generated version hash should change when dialog set changes.', function () {
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new WaterfallDialog('A')).add(new WaterfallDialog('B'));
|
||||
const hash = dialogs.getVersion();
|
||||
assert(hash && hash.length > 0, `no hash generated.`);
|
||||
assert(hash && hash.length > 0, 'no hash generated.');
|
||||
|
||||
dialogs.add(new WaterfallDialog('C'));
|
||||
assert(hash != dialogs.getVersion(), `hash not updated.`);
|
||||
assert(hash != dialogs.getVersion(), 'hash not updated.');
|
||||
});
|
||||
|
||||
it('Cyclical dialog structures', function () {
|
||||
|
|
|
@ -11,7 +11,7 @@ const {
|
|||
} = require('../..');
|
||||
|
||||
const beginMessage = {
|
||||
text: `begin`,
|
||||
text: 'begin',
|
||||
type: 'message',
|
||||
channelId: 'test',
|
||||
from: { id: 'user' },
|
||||
|
@ -122,9 +122,9 @@ describe('Dialog State Manager', function () {
|
|||
|
||||
it('create a standard configuration by default.', function () {
|
||||
const config = this.dc.state.configuration;
|
||||
assert(config, `No config returned`);
|
||||
assert(config.pathResolvers.length > 0, `No path resolvers`);
|
||||
assert(config.memoryScopes.length > 0, `No memory scopes`);
|
||||
assert(config, 'No config returned');
|
||||
assert(config.pathResolvers.length > 0, 'No path resolvers');
|
||||
assert(config.memoryScopes.length > 0, 'No memory scopes');
|
||||
});
|
||||
|
||||
it('read values from the SETTINGS memory scope.', function () {
|
||||
|
@ -315,7 +315,7 @@ describe('Dialog State Manager', function () {
|
|||
},
|
||||
});
|
||||
|
||||
const value = this.dc.state.getValue(`turn.addresses['work'].zip`);
|
||||
const value = this.dc.state.getValue("turn.addresses['work'].zip");
|
||||
assert(value == '98052');
|
||||
});
|
||||
|
||||
|
@ -329,7 +329,7 @@ describe('Dialog State Manager', function () {
|
|||
},
|
||||
});
|
||||
|
||||
const value = this.dc.state.getValue(`turn.addresses["work"].zip`);
|
||||
const value = this.dc.state.getValue('turn.addresses["work"].zip');
|
||||
assert(value == '98052');
|
||||
});
|
||||
|
||||
|
@ -343,7 +343,7 @@ describe('Dialog State Manager', function () {
|
|||
},
|
||||
});
|
||||
|
||||
const value = this.dc.state.getValue(`turn.addresses['\\"work\\"'].zip`);
|
||||
const value = this.dc.state.getValue('turn.addresses[\'\\"work\\"\'].zip');
|
||||
assert(value == '98052');
|
||||
});
|
||||
|
||||
|
@ -358,7 +358,7 @@ describe('Dialog State Manager', function () {
|
|||
},
|
||||
});
|
||||
|
||||
this.dc.state.getValue(`turn.addresses['work"].zip`);
|
||||
this.dc.state.getValue('turn.addresses[\'work"].zip');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -373,23 +373,23 @@ describe('Dialog State Manager', function () {
|
|||
},
|
||||
});
|
||||
|
||||
this.dc.state.getValue(`turn.addresses.~work.zip`);
|
||||
this.dc.state.getValue('turn.addresses.~work.zip');
|
||||
});
|
||||
});
|
||||
|
||||
it('raise an error for assignments to a negative array index.', function () {
|
||||
assert.throws(() => this.dc.state.setValue(`turn.foo[-1]`, 'test'));
|
||||
assert.throws(() => this.dc.state.setValue('turn.foo[-1]', 'test'));
|
||||
});
|
||||
|
||||
it('raise an error for array assignments to non-array values.', function () {
|
||||
assert.throws(() => {
|
||||
this.dc.state.setValue('turn.foo', 'bar');
|
||||
this.dc.state.setValue(`turn.foo[3]`, 'test');
|
||||
this.dc.state.setValue('turn.foo[3]', 'test');
|
||||
});
|
||||
});
|
||||
|
||||
it('raise an error for un-matched brackets.', function () {
|
||||
assert.throws(() => this.dc.state.setValue(`turn.foo[0`, 'test'));
|
||||
assert.throws(() => this.dc.state.setValue('turn.foo[0', 'test'));
|
||||
});
|
||||
|
||||
it('alow indexer based path lookups.', function () {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const _ = require('lodash');
|
||||
const pick = require('lodash/pick');
|
||||
const assert = require('assert');
|
||||
const { ConversationState, UserState, MemoryStorage, TurnContext, TestAdapter } = require('botbuilder-core');
|
||||
|
||||
|
@ -19,7 +19,7 @@ const {
|
|||
} = require('../..');
|
||||
|
||||
const beginMessage = {
|
||||
text: `begin`,
|
||||
text: 'begin',
|
||||
type: 'message',
|
||||
channelId: 'test',
|
||||
from: { id: 'user' },
|
||||
|
@ -106,7 +106,7 @@ describe('Memory Scopes', function () {
|
|||
it('finds registered dialog', async function () {
|
||||
const { memory } = await initialize();
|
||||
|
||||
assert.deepStrictEqual(_.pick(memory, 'message', 'expression'), {
|
||||
assert.deepStrictEqual(pick(memory, 'message', 'expression'), {
|
||||
message: 'test message',
|
||||
expression: 'resolved value',
|
||||
});
|
||||
|
@ -151,7 +151,7 @@ describe('Memory Scopes', function () {
|
|||
const dc = await dialogs.createContext(context);
|
||||
const scope = new ConversationMemoryScope();
|
||||
const memory = scope.getMemory(dc);
|
||||
assert.deepStrictEqual(_.pick(memory, 'conversation'), { conversation: { foo: 'bar' } });
|
||||
assert.deepStrictEqual(pick(memory, 'conversation'), { conversation: { foo: 'bar' } });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -195,7 +195,7 @@ describe('Memory Scopes', function () {
|
|||
|
||||
await scope.load(dc);
|
||||
memory = scope.getMemory(dc);
|
||||
assert.deepStrictEqual(_.pick(memory, 'user'), { user: { foo: 'bar' } });
|
||||
assert.deepStrictEqual(pick(memory, 'user'), { user: { foo: 'bar' } });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -218,7 +218,7 @@ describe('Memory Scopes', function () {
|
|||
|
||||
it('returns containers state', async function () {
|
||||
const { memory } = await initialize();
|
||||
assert.deepStrictEqual(_.pick(memory, 'isContainer'), { isContainer: true });
|
||||
assert.deepStrictEqual(pick(memory, 'isContainer'), { isContainer: true });
|
||||
});
|
||||
|
||||
it('returns parent containers state for children', async function () {
|
||||
|
@ -228,12 +228,12 @@ describe('Memory Scopes', function () {
|
|||
assert(dc.child);
|
||||
|
||||
const memory = scope.getMemory(dc.child);
|
||||
assert.deepStrictEqual(_.pick(memory, 'isContainer'), { isContainer: true });
|
||||
assert.deepStrictEqual(pick(memory, 'isContainer'), { isContainer: true });
|
||||
});
|
||||
|
||||
it('returns childs state when no parent', async function () {
|
||||
const { memory } = await initialize(new TestDialog('test', 'test message'));
|
||||
assert.deepStrictEqual(_.pick(memory, 'isDialog'), { isDialog: true });
|
||||
assert.deepStrictEqual(pick(memory, 'isDialog'), { isDialog: true });
|
||||
});
|
||||
|
||||
it('overwrites parents memory', async function () {
|
||||
|
@ -245,7 +245,7 @@ describe('Memory Scopes', function () {
|
|||
scope.setMemory(dc.child, { foo: 'bar' });
|
||||
const memory = scope.getMemory(dc);
|
||||
|
||||
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
|
||||
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
|
||||
});
|
||||
|
||||
it('overwrites active dialogs memory', async function () {
|
||||
|
@ -254,7 +254,7 @@ describe('Memory Scopes', function () {
|
|||
scope.setMemory(dc, { foo: 'bar' });
|
||||
const memory = scope.getMemory(dc);
|
||||
|
||||
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
|
||||
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
|
||||
});
|
||||
|
||||
it('raises error if setMemory() called without memory', async function () {
|
||||
|
@ -291,7 +291,7 @@ describe('Memory Scopes', function () {
|
|||
dc.context.turnState.set('settings', require('../test.settings.json'));
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(_.pick(memory, 'string', 'int', 'array'), {
|
||||
assert.deepStrictEqual(pick(memory, 'string', 'int', 'array'), {
|
||||
string: 'test',
|
||||
int: 3,
|
||||
array: ['zero', 'one', 'two', 'three'],
|
||||
|
@ -320,7 +320,7 @@ describe('Memory Scopes', function () {
|
|||
});
|
||||
|
||||
assert.deepStrictEqual(
|
||||
_.pick(memory, 'array', 'object', 'simple', 'MicrosoftAppPassword', 'runtimeSettings', 'BlobsStorage'),
|
||||
pick(memory, 'array', 'object', 'simple', 'MicrosoftAppPassword', 'runtimeSettings', 'BlobsStorage'),
|
||||
{
|
||||
array: ['one', 'two'],
|
||||
object: {
|
||||
|
@ -357,7 +357,7 @@ describe('Memory Scopes', function () {
|
|||
});
|
||||
|
||||
assert.deepStrictEqual(
|
||||
_.pick(
|
||||
pick(
|
||||
memory,
|
||||
'array',
|
||||
'object',
|
||||
|
@ -456,13 +456,13 @@ describe('Memory Scopes', function () {
|
|||
|
||||
it('returns active dialogs state', async function () {
|
||||
const { memory } = await initialize({ dialog: new TestDialog('test', 'test message') });
|
||||
assert(_.pick(memory, 'isDialog'), { isDialog: true });
|
||||
assert(pick(memory, 'isDialog'), { isDialog: true });
|
||||
});
|
||||
|
||||
it('overwrites active dialogs memory', async function () {
|
||||
const { dc, memory, scope } = await initialize();
|
||||
scope.setMemory(dc, { foo: 'bar' });
|
||||
assert(_.pick(memory, 'foo'), { foo: 'bar' });
|
||||
assert(pick(memory, 'foo'), { foo: 'bar' });
|
||||
});
|
||||
|
||||
it('raises error if setMemory() called without memory', async function () {
|
||||
|
@ -520,7 +520,7 @@ describe('Memory Scopes', function () {
|
|||
scope.setMemory(dc, { foo: 'bar' });
|
||||
|
||||
const memory = scope.getMemory(dc);
|
||||
assert.deepStrictEqual(_.pick(memory, 'foo'), { foo: 'bar' });
|
||||
assert.deepStrictEqual(pick(memory, 'foo'), { foo: 'bar' });
|
||||
});
|
||||
|
||||
it('raises error when setMemory() called without memory', async function () {
|
||||
|
|
|
@ -46,7 +46,7 @@ describe('NumberPrompt', function () {
|
|||
(turnContext, result) => turnContext.sendActivity(result.toString()),
|
||||
(prompt) => {
|
||||
assert(prompt);
|
||||
let value = prompt.recognized.value;
|
||||
const value = prompt.recognized.value;
|
||||
return value !== undefined && value >= 1 && value <= 100;
|
||||
}
|
||||
);
|
||||
|
@ -71,7 +71,7 @@ describe('NumberPrompt', function () {
|
|||
(turnContext, result) => turnContext.sendActivity(result.toString()),
|
||||
(prompt) => {
|
||||
assert(prompt);
|
||||
let value = prompt.recognized.value;
|
||||
const value = prompt.recognized.value;
|
||||
return value !== undefined && value >= 1 && value <= 100;
|
||||
}
|
||||
);
|
||||
|
@ -96,7 +96,7 @@ describe('NumberPrompt', function () {
|
|||
(turnContext, result) => turnContext.sendActivity(result.toString()),
|
||||
async (prompt) => {
|
||||
assert(prompt);
|
||||
let value = prompt.recognized.value;
|
||||
const value = prompt.recognized.value;
|
||||
const valid = value !== undefined && value >= 1 && value <= 100;
|
||||
if (!valid) {
|
||||
await prompt.context.sendActivity('out of range');
|
||||
|
@ -121,7 +121,7 @@ describe('NumberPrompt', function () {
|
|||
(turnContext, result) => turnContext.sendActivity(result.toString()),
|
||||
(prompt) => {
|
||||
assert(prompt);
|
||||
let value = prompt.recognized.value;
|
||||
const value = prompt.recognized.value;
|
||||
return value !== undefined && value >= 1 && value <= 100;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
const assert = require('assert');
|
||||
const { spy } = require('sinon');
|
||||
const { ok, strictEqual } = require('assert');
|
||||
const { ok } = require('assert');
|
||||
const { OAuthPrompt, DialogSet, DialogTurnStatus } = require('../');
|
||||
const {
|
||||
AuthenticationConstants,
|
||||
|
@ -42,9 +42,9 @@ describe('OAuthPrompt', function () {
|
|||
await dc.prompt('prompt', {});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
if (results.result.token) {
|
||||
await turnContext.sendActivity(`Logged in.`);
|
||||
await turnContext.sendActivity('Logged in.');
|
||||
} else {
|
||||
await turnContext.sendActivity(`Failed`);
|
||||
await turnContext.sendActivity('Failed');
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
|
@ -106,9 +106,9 @@ describe('OAuthPrompt', function () {
|
|||
await dc.prompt('prompt', {});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
if (results.result.token) {
|
||||
await turnContext.sendActivity(`Logged in.`);
|
||||
await turnContext.sendActivity('Logged in.');
|
||||
} else {
|
||||
await turnContext.sendActivity(`Failed`);
|
||||
await turnContext.sendActivity('Failed');
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
|
@ -350,9 +350,9 @@ describe('OAuthPrompt', function () {
|
|||
await dc.prompt('prompt', {});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
if (results.result.token) {
|
||||
await turnContext.sendActivity(`Logged in.`);
|
||||
await turnContext.sendActivity('Logged in.');
|
||||
} else {
|
||||
await turnContext.sendActivity(`Failed`);
|
||||
await turnContext.sendActivity('Failed');
|
||||
}
|
||||
}
|
||||
await convoState.saveChanges(turnContext);
|
||||
|
@ -455,7 +455,7 @@ describe('OAuthPrompt', function () {
|
|||
async exchangeToken() {}
|
||||
}
|
||||
|
||||
it(`should fail if adapter does not have 'getUserToken'`, async function () {
|
||||
it("should fail if adapter does not have 'getUserToken'", async function () {
|
||||
const fakeAdapter = {};
|
||||
const context = new TurnContext(fakeAdapter, {
|
||||
activity: {
|
||||
|
@ -869,7 +869,7 @@ describe('OAuthPrompt', function () {
|
|||
await dc.prompt('OAuthPrompt', {});
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
if (results.result.token) {
|
||||
await turnContext.sendActivity(`Logged in.`);
|
||||
await turnContext.sendActivity('Logged in.');
|
||||
} else {
|
||||
await turnContext.sendActivity('Failed');
|
||||
}
|
||||
|
@ -1089,8 +1089,8 @@ class ClaimsIdentity {
|
|||
/**w
|
||||
* Each claim should be { type: 'type', value: 'value' }
|
||||
*
|
||||
* @param {*} claims
|
||||
* @param {*} isAuthenticated
|
||||
* @param {*} claims The claims with which to populate the claims identity.
|
||||
* @param {*} isAuthenticated True if the identity has been authenticated; otherwise, false.
|
||||
*/
|
||||
constructor(claims = [], isAuthenticated = false) {
|
||||
this.claims = claims;
|
||||
|
|
|
@ -1,24 +1,14 @@
|
|||
const assert = require('assert');
|
||||
const { PromptCultureModels } = require('../lib')
|
||||
const { PromptCultureModels } = require('../lib');
|
||||
|
||||
describe('Prompt Culture Models Tests', function() {
|
||||
describe('Prompt Culture Models Tests', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
it('should correctly map to nearest language', function() {
|
||||
const locales = [
|
||||
'es-es',
|
||||
'nl-nl',
|
||||
'en-us',
|
||||
'fr-fr',
|
||||
'de-de',
|
||||
'ja-jp',
|
||||
'it-it',
|
||||
'pt-br',
|
||||
'zh-cn'
|
||||
];
|
||||
|
||||
it('should correctly map to nearest language', function () {
|
||||
const locales = ['es-es', 'nl-nl', 'en-us', 'fr-fr', 'de-de', 'ja-jp', 'it-it', 'pt-br', 'zh-cn'];
|
||||
// es-ES
|
||||
const capEnding = (locale) => {
|
||||
return `${ locale.split('-')[0] }-${ locale.split('-')[1].toUpperCase() }`;
|
||||
return `${locale.split('-')[0]}-${locale.split('-')[1].toUpperCase()}`;
|
||||
};
|
||||
// es-Es
|
||||
const titleEnding = (locale) => {
|
||||
|
@ -41,7 +31,7 @@ describe('Prompt Culture Models Tests', function() {
|
|||
capEnding(locale),
|
||||
titleEnding(locale),
|
||||
capTwoLetter(locale),
|
||||
lowerTwoLetter(locale)
|
||||
lowerTwoLetter(locale),
|
||||
];
|
||||
return obj;
|
||||
}, {});
|
||||
|
@ -52,13 +42,13 @@ describe('Prompt Culture Models Tests', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw when locale is null or undefined', function() {
|
||||
|
||||
it('should not throw when locale is null or undefined', function () {
|
||||
assert.doesNotThrow(() => PromptCultureModels.mapToNearestLanguage(null));
|
||||
assert.doesNotThrow(() => PromptCultureModels.mapToNearestLanguage(undefined));
|
||||
});
|
||||
|
||||
it('should return all supported cultures', function() {
|
||||
it('should return all supported cultures', function () {
|
||||
const expected = [
|
||||
PromptCultureModels.Chinese,
|
||||
PromptCultureModels.Dutch,
|
||||
|
@ -68,11 +58,11 @@ describe('Prompt Culture Models Tests', function() {
|
|||
PromptCultureModels.Italian,
|
||||
PromptCultureModels.Japanese,
|
||||
PromptCultureModels.Portuguese,
|
||||
PromptCultureModels.Spanish
|
||||
PromptCultureModels.Spanish,
|
||||
];
|
||||
|
||||
const supportedCultures = PromptCultureModels.getSupportedCultures();
|
||||
|
||||
assert.deepEqual(supportedCultures, expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -41,7 +41,7 @@ describe('SkillDialog', function () {
|
|||
* @remarks
|
||||
* Port of BeginDialogShouldCallSkill from C#
|
||||
* https://github.com/microsoft/botbuilder-dotnet/blob/41120728b22c709ec2d9247393505fdc778b2de1/tests/Microsoft.Bot.Builder.Dialogs.Tests/SkillDialogTests.cs#L47-L49
|
||||
* @param {string} deliveryMode
|
||||
* @param {string} deliveryMode The delivery mode to test.
|
||||
*/
|
||||
async function beginDialogShouldCallSkill(deliveryMode, useCreateSkillConversationId = false) {
|
||||
let activitySent; // Activity
|
||||
|
@ -313,7 +313,7 @@ describe('SkillDialog', function () {
|
|||
});
|
||||
|
||||
describe('(private) sendToSkill()', function () {
|
||||
it(`should rethrow the error if its message is not "Not Implemented" error`, async function () {
|
||||
it('should rethrow the error if its message is not "Not Implemented" error', async function () {
|
||||
const adapter = new TestAdapter(/* logic param not required */);
|
||||
const activity = { type: ActivityTypes.Message, channelId: Channels.Directline, conversation: { id: '1' } };
|
||||
const context = new TurnContext(adapter, activity);
|
||||
|
@ -576,7 +576,7 @@ describe('SkillDialog', function () {
|
|||
* @remarks
|
||||
* captureAction should match the below signature:
|
||||
* `(fromBotId: string, toBotId: string, toUrl: string, serviceUrl: string, conversationId: string, activity: Activity) => void`
|
||||
* @param {Function} captureAction
|
||||
* @param {Function} captureAction Callback to capture the parameters sent to the skill.
|
||||
* @param {StatusCodes} returnStatusCode Defaults to StatusCodes.OK
|
||||
* @returns [BotFrameworkHttpClient, postActivityStub]
|
||||
*/
|
||||
|
@ -615,7 +615,7 @@ function createSkillClientAndStub(captureAction, returnStatusCode = StatusCodes.
|
|||
|
||||
/**
|
||||
*
|
||||
* @param {string} uri
|
||||
* @param {string} uri Uri for the token exchange.
|
||||
*/
|
||||
function createOAuthCardAttachmentActivity(uri) {
|
||||
const oauthCard = {
|
||||
|
@ -635,8 +635,8 @@ function createOAuthCardAttachmentActivity(uri) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {*} conversationState
|
||||
* @param {*} mockSkillClient
|
||||
* @param {*} conversationState The conversation state object.
|
||||
* @param {*} mockSkillClient The skill client mock.
|
||||
* @returns A Skill Dialog Options object.
|
||||
*/
|
||||
function createSkillDialogOptions(conversationState, mockSkillClient, connectionName, useCreateSkillConversationId) {
|
||||
|
|
|
@ -6,10 +6,10 @@ const path = require('path');
|
|||
|
||||
const invalidMessage = { type: ActivityTypes.Message, text: '' };
|
||||
|
||||
describe('TextPrompt', function() {
|
||||
describe('TextPrompt', function () {
|
||||
this.timeout(5000);
|
||||
|
||||
it('should call TextPrompt using dc.prompt().', async function() {
|
||||
it('should call TextPrompt using dc.prompt().', async function () {
|
||||
// Initialize TestAdapter.
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
@ -31,14 +31,10 @@ describe('TextPrompt', function() {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new TextPrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send('test')
|
||||
.assertReply('test')
|
||||
.startTest();
|
||||
await adapter.send('Hello').assertReply('Please say something.').send('test').assertReply('test').startTest();
|
||||
});
|
||||
|
||||
it('should call TextPrompt with custom validator.', async function() {
|
||||
it('should call TextPrompt with custom validator.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -56,12 +52,15 @@ describe('TextPrompt', function() {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new TextPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.value.length >= 3;
|
||||
}));
|
||||
dialogs.add(
|
||||
new TextPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
return prompt.recognized.value.length >= 3;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send('i')
|
||||
.assertReply('Please say something.')
|
||||
|
@ -70,7 +69,7 @@ describe('TextPrompt', function() {
|
|||
.startTest();
|
||||
});
|
||||
|
||||
it('should call TextPrompt with naughty strings.', async function() {
|
||||
it('should call TextPrompt with naughty strings.', async function () {
|
||||
const filePath = path.join(__dirname, 'Resources', 'naughtyStrings.txt');
|
||||
|
||||
lineReader.eachLine(filePath, async (naughtyString) => {
|
||||
|
@ -83,8 +82,8 @@ describe('TextPrompt', function() {
|
|||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
const results = await dc.continueDialog();
|
||||
if (results.status === DialogTurnStatus.empty){
|
||||
await dc.prompt('prompt', { prompt: 'Enter some text'});
|
||||
if (results.status === DialogTurnStatus.empty) {
|
||||
await dc.prompt('prompt', { prompt: 'Enter some text' });
|
||||
} else if (results.status === DialogTurnStatus.complete) {
|
||||
const reply = results.result;
|
||||
await turnContext.sendActivity(reply);
|
||||
|
@ -92,7 +91,8 @@ describe('TextPrompt', function() {
|
|||
await convoState.saveChanges(turnContext);
|
||||
});
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Enter some text')
|
||||
.send(naughtyString)
|
||||
.assertReply(naughtyString)
|
||||
|
@ -101,7 +101,7 @@ describe('TextPrompt', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should send custom retryPrompt.', async function() {
|
||||
it('should send custom retryPrompt.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -121,7 +121,8 @@ describe('TextPrompt', function() {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new TextPrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send(invalidMessage)
|
||||
.assertReply('Text is required.')
|
||||
|
@ -130,7 +131,7 @@ describe('TextPrompt', function() {
|
|||
.startTest();
|
||||
});
|
||||
|
||||
it('should send ignore retryPrompt if validator replies.', async function() {
|
||||
it('should send ignore retryPrompt if validator replies.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -148,16 +149,19 @@ describe('TextPrompt', function() {
|
|||
|
||||
const dialogState = convoState.createProperty('dialogState');
|
||||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new TextPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
const valid = prompt.recognized.value.length >= 3;
|
||||
if (!valid) {
|
||||
await prompt.context.sendActivity('too short');
|
||||
}
|
||||
return valid;
|
||||
}));
|
||||
dialogs.add(
|
||||
new TextPrompt('prompt', async (prompt) => {
|
||||
assert(prompt);
|
||||
const valid = prompt.recognized.value.length >= 3;
|
||||
if (!valid) {
|
||||
await prompt.context.sendActivity('too short');
|
||||
}
|
||||
return valid;
|
||||
})
|
||||
);
|
||||
|
||||
await adapter.send('Hello')
|
||||
await adapter
|
||||
.send('Hello')
|
||||
.assertReply('Please say something.')
|
||||
.send('i')
|
||||
.assertReply('too short')
|
||||
|
@ -166,7 +170,7 @@ describe('TextPrompt', function() {
|
|||
.startTest();
|
||||
});
|
||||
|
||||
it('should not send any retryPrompt no prompt specified.', async function() {
|
||||
it('should not send any retryPrompt no prompt specified.', async function () {
|
||||
const adapter = new TestAdapter(async (turnContext) => {
|
||||
const dc = await dialogs.createContext(turnContext);
|
||||
|
||||
|
@ -186,10 +190,6 @@ describe('TextPrompt', function() {
|
|||
const dialogs = new DialogSet(dialogState);
|
||||
dialogs.add(new TextPrompt('prompt'));
|
||||
|
||||
await adapter.send('Hello')
|
||||
.send(invalidMessage)
|
||||
.send('test')
|
||||
.assertReply('test')
|
||||
.startTest();
|
||||
await adapter.send('Hello').send(invalidMessage).send('test').assertReply('test').startTest();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ const { Dialog, DialogReason, DialogSet, DialogTurnStatus, WaterfallDialog, Comp
|
|||
|
||||
const assert = require('assert');
|
||||
|
||||
const beginMessage = { text: `begin`, type: 'message' };
|
||||
const beginMessage = { text: 'begin', type: 'message' };
|
||||
|
||||
class MyWaterfall extends WaterfallDialog {
|
||||
constructor(dialogId) {
|
||||
|
@ -171,7 +171,7 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step.options && step.options.test === 'test', `step.options not found.`);
|
||||
assert(step.options && step.options.test === 'test', 'step.options not found.');
|
||||
await step.context.sendActivity('bot responding.');
|
||||
return await step.next(step.options.test);
|
||||
},
|
||||
|
@ -212,8 +212,8 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test,
|
||||
'test',
|
||||
|
@ -260,8 +260,8 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test,
|
||||
'test1',
|
||||
|
@ -272,8 +272,8 @@ describe('WaterfallDialog', function () {
|
|||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test,
|
||||
'test2',
|
||||
|
@ -284,7 +284,7 @@ describe('WaterfallDialog', function () {
|
|||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test,
|
||||
'test3',
|
||||
|
@ -328,15 +328,15 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert.equal(typeof step.values, 'object', `initial step.values should be an object.`);
|
||||
assert(step, 'step not found.');
|
||||
assert.equal(typeof step.values, 'object', 'initial step.values should be an object.');
|
||||
step.values.test = 'test1';
|
||||
await step.context.sendActivity('bot responding.');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.values, `step.values not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.values, 'step.values not found.');
|
||||
assert.strictEqual(
|
||||
step.values.test,
|
||||
'test1',
|
||||
|
@ -347,8 +347,8 @@ describe('WaterfallDialog', function () {
|
|||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.values, `step.values not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.values, 'step.values not found.');
|
||||
assert.strictEqual(
|
||||
step.values.test,
|
||||
'test1',
|
||||
|
@ -397,15 +397,15 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert.equal(typeof step.values, 'object', `initial step.values should be an object.`);
|
||||
assert(step, 'step not found.');
|
||||
assert.equal(typeof step.values, 'object', 'initial step.values should be an object.');
|
||||
step.values.test = 'test1';
|
||||
await step.context.sendActivity('bot responding.');
|
||||
return await step.beginDialog('b');
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.values, `step.values not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.values, 'step.values not found.');
|
||||
assert.strictEqual(
|
||||
step.values.test,
|
||||
'test1',
|
||||
|
@ -414,7 +414,7 @@ describe('WaterfallDialog', function () {
|
|||
assert.strictEqual(
|
||||
step.values.test_b,
|
||||
undefined,
|
||||
`step.values.test_b should not be available in WaterfallDialog('a').`
|
||||
"step.values.test_b should not be available in WaterfallDialog('a')."
|
||||
);
|
||||
return await step.endDialog('ending WaterfallDialog.');
|
||||
},
|
||||
|
@ -424,15 +424,15 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert.equal(
|
||||
typeof step.values,
|
||||
'object',
|
||||
`new step.values for second WaterfallDialog should be an object.`
|
||||
'new step.values for second WaterfallDialog should be an object.'
|
||||
);
|
||||
assert(
|
||||
!step.values.test,
|
||||
`new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values.`
|
||||
"new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values."
|
||||
);
|
||||
|
||||
// Add a new value to this WaterfallDialog's step.values.
|
||||
|
@ -441,20 +441,20 @@ describe('WaterfallDialog', function () {
|
|||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert.equal(
|
||||
typeof step.values,
|
||||
'object',
|
||||
`step.values for second WaterfallDialog should be an object.`
|
||||
'step.values for second WaterfallDialog should be an object.'
|
||||
);
|
||||
assert(
|
||||
!step.values.test,
|
||||
`new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values.`
|
||||
"new WaterfallDialog's step.values shouldn't have values from parent dialog's step.values."
|
||||
);
|
||||
assert.strictEqual(
|
||||
step.values.test_b,
|
||||
'test_b',
|
||||
`step.values.test_b should not be available in WaterfallDialog 'a'.`
|
||||
"step.values.test_b should not be available in WaterfallDialog 'a'."
|
||||
);
|
||||
|
||||
return await step.endDialog();
|
||||
|
@ -493,8 +493,8 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test_a,
|
||||
'test_a',
|
||||
|
@ -504,8 +504,8 @@ describe('WaterfallDialog', function () {
|
|||
return await step.beginDialog('b');
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test_a,
|
||||
'test_a',
|
||||
|
@ -519,8 +519,8 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('b', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test_a,
|
||||
undefined,
|
||||
|
@ -530,8 +530,8 @@ describe('WaterfallDialog', function () {
|
|||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step.options, `step.options not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(step.options, 'step.options not found.');
|
||||
assert.strictEqual(
|
||||
step.options.test_b,
|
||||
'test_b',
|
||||
|
@ -573,12 +573,12 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
await step.context.sendActivity('bot responding.');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
])
|
||||
|
@ -616,7 +616,7 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
await step.context.sendActivity('bot responding.');
|
||||
try {
|
||||
await step.next();
|
||||
|
@ -624,17 +624,17 @@ describe('WaterfallDialog', function () {
|
|||
} catch (err) {
|
||||
assert(
|
||||
err.message ===
|
||||
`WaterfallStepContext.next(): method already called for dialog and step 'a[0]'.`,
|
||||
"WaterfallStepContext.next(): method already called for dialog and step 'a[0]'.",
|
||||
err.message
|
||||
);
|
||||
}
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
},
|
||||
])
|
||||
);
|
||||
|
@ -664,12 +664,12 @@ describe('WaterfallDialog', function () {
|
|||
dialogs.add(
|
||||
new WaterfallDialog('a', [
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
await step.context.sendActivity('bot responding.');
|
||||
return Dialog.EndOfTurn;
|
||||
},
|
||||
async function (step) {
|
||||
assert(step, `step not found.`);
|
||||
assert(step, 'step not found.');
|
||||
assert(
|
||||
step.context.activity.text === 'continue.',
|
||||
`expected "continue." not ${step.context.activity.text}`
|
||||
|
|
Загрузка…
Ссылка в новой задаче