UNPKG

botbuilder-core

Version:

Core components for Microsoft Bot Builder. Components in this library can run either in a browser or on the server.

444 lines 21.4 kB
import { Activity, ConversationReference, ResourceResponse, TokenResponse, TokenExchangeRequest, SignInUrlResponse } from 'botframework-schema'; import { BotAdapter } from './botAdapter'; import { ExtendedUserTokenProvider } from './extendedUserTokenProvider'; import { TurnContext } from './turnContext'; /** * Signature for a function that can be used to inspect individual activities returned by a bot * that's being tested using the `TestAdapter`. * * ```TypeScript * type TestActivityInspector = (activity: Partial<Activity>, description: string) => void; * ``` * * @param TestActivityInspector.activity The activity being inspected. * @param TestActivityInspector.description Text to log in the event of an error. */ export declare type TestActivityInspector = (activity: Partial<Activity>, description?: string) => void; /** * Test adapter used for unit tests. This adapter can be used to simulate sending messages from the * user to the bot. * * @remarks * The following example sets up the test adapter and then executes a simple test: * * ```JavaScript * const { TestAdapter } = require('botbuilder'); * * const adapter = new TestAdapter(async (context) => { * await context.sendActivity(`Hello World`); * }); * * adapter.test(`hi`, `Hello World`) * .then(() => done()); * ``` */ export declare class TestAdapter extends BotAdapter implements ExtendedUserTokenProvider { /** * Creates a new TestAdapter instance. * * @param logicOrConversation The bots logic that's under test. * @param template (Optional) activity containing default values to assign to all test messages received. * @param sendTraceActivity Indicates whether the adapter should add to its queue any trace activities generated by the bot. */ constructor(logicOrConversation?: ((context: TurnContext) => Promise<void>) | ConversationReference, template?: Partial<Activity>, sendTraceActivity?: boolean); /** * @private * INTERNAL: used to drive the promise chain forward when running tests. */ get activityBuffer(): Partial<Activity>[]; /** * Gets a value indicating whether to send trace activities. * * @returns A value indicating whether to send trace activities. */ get enableTrace(): boolean; /** * Sets a value inidicating whether to send trace activities. */ set enableTrace(value: boolean); /** * Gets or sets the locale for the conversation. */ locale: string; /** * Gets the queue of responses from the bot. */ readonly activeQueue: Partial<Activity>[]; /** * Gets or sets a reference to the current conversation. */ conversation: ConversationReference; /** * Create a ConversationReference. * * @param name name of the conversation (also id). * @param user name of the user (also id) default: User1. * @param bot name of the bot (also id) default: Bot. * @returns The [ConversationReference](xref:botframework-schema.ConversationReference). */ static createConversation(name: string, user?: string, bot?: string): ConversationReference; /** * Dequeues and returns the next bot response from the activeQueue. * * @returns The next activity in the queue; or undefined, if the queue is empty. */ getNextReply(): Partial<Activity>; /** * Creates a message activity from text and the current conversational context. * * @param text The message text. * @returns An appropriate message activity. */ makeActivity(text?: string): Partial<Activity>; /** * Processes a message activity from a user. * * @param userSays The text of the user's message. * @param callback The bot logic to invoke. * @returns {Promise<any>} A promise representing the async operation. */ sendTextToBot(userSays: string, callback: (context: TurnContext) => Promise<any>): Promise<any>; /** * `Activity` template that will be merged with all activities sent to the logic under test. */ readonly template: Partial<Activity>; private _logic; private _sendTraceActivity; private _nextId; private readonly ExceptionExpected; /** * Receives an activity and runs it through the middleware pipeline. * * @param activity The activity to process. * @param callback The bot logic to invoke. * @returns {Promise<any>} A promise representing the async operation. */ processActivity(activity: string | Partial<Activity>, callback?: (context: TurnContext) => Promise<any>): Promise<any>; /** * @private * Sends activities to the conversation. * @param context Context object for the current turn of conversation with the user. * @param activities Set of activities sent by logic under test. */ sendActivities(context: TurnContext, activities: Partial<Activity>[]): Promise<ResourceResponse[]>; /** * @private * Replaces an existing activity in the activeQueue. * @param context Context object for the current turn of conversation with the user. * @param activity Activity being updated. * @returns promise representing async operation */ updateActivity(context: TurnContext, activity: Partial<Activity>): Promise<ResourceResponse | void>; /** * @private * Deletes an existing activity in the activeQueue. * @param context Context object for the current turn of conversation with the user. * @param reference `ConversationReference` for activity being deleted. */ deleteActivity(context: TurnContext, reference: Partial<ConversationReference>): Promise<void>; /** * @private * INTERNAL: called by a `TestFlow` instance to simulate a user sending a message to the bot. * This will cause the adapters middleware pipe to be run and it's logic to be called. * @param activity Text or activity from user. The current conversation reference [template](#template) will be merged the passed in activity to properly address the activity. Fields specified in the activity override fields in the template. */ receiveActivity(activity: string | Partial<Activity>): Promise<void>; /** * The `TestAdapter` doesn't implement `continueConversation()` and will return an error if it's * called. * * @param _reference A reference to the conversation to continue. * @param _logic The asynchronous method to call after the adapter middleware runs. * @returns {Promise<void>} A promise representing the async operation. */ continueConversation(_reference: Partial<ConversationReference>, _logic: (revocableContext: TurnContext) => Promise<void>): Promise<void>; /** * Creates a turn context. * * @param request An incoming request body. * @returns The created [TurnContext](xref:botbuilder-core.TurnContext). * @remarks * Override this in a derived class to modify how the adapter creates a turn context. */ protected createContext(request: Partial<Activity>): TurnContext; /** * Sends something to the bot. This returns a new `TestFlow` instance which can be used to add * additional steps for inspecting the bots reply and then sending additional activities. * * @remarks * This example shows how to send a message and then verify that the response was as expected: * * ```JavaScript * adapter.send('hi') * .assertReply('Hello World') * .then(() => done()); * ``` * @param userSays Text or activity simulating user input. * @returns a new [TestFlow](xref:botbuilder-core.TestFlow) instance which can be used to add additional steps * for inspecting the bots reply and then sending additional activities. */ send(userSays: string | Partial<Activity>): TestFlow; /** * Send something to the bot and expects the bot to return with a given reply. * * @remarks * This is simply a wrapper around calls to `send()` and `assertReply()`. This is such a * common pattern that a helper is provided. * * ```JavaScript * adapter.test('hi', 'Hello World') * .then(() => done()); * ``` * @param userSays Text or activity simulating user input. * @param expected Expected text or activity of the reply sent by the bot. * @param description (Optional) Description of the test case. If not provided one will be generated. * @param _timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ test(userSays: string | Partial<Activity>, expected: string | Partial<Activity> | ((activity: Partial<Activity>, description?: string) => void), description?: string, _timeout?: number): TestFlow; /** * Test a list of activities. * * @remarks * Each activity with the "bot" role will be processed with assertReply() and every other * activity will be processed as a user message with send(). * @param activities Array of activities. * @param description (Optional) Description of the test case. If not provided one will be generated. * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ testActivities(activities: Partial<Activity>[], description?: string, timeout?: number): TestFlow; private _userTokens; private _magicCodes; /** * Adds a fake user token so it can later be retrieved. * * @param connectionName The connection name. * @param channelId The channel id. * @param userId The user id. * @param token The token to store. * @param magicCode (Optional) The optional magic code to associate with this token. */ addUserToken(connectionName: string, channelId: string, userId: string, token: string, magicCode?: string): void; /** * Asynchronously retrieves the token status for each configured connection for the given user. * In testAdapter, retrieves tokens which were previously added via addUserToken. * * @param context The context object for the turn. * @param userId The ID of the user to retrieve the token status for. * @param includeFilter Optional. A comma-separated list of connection's to include. If present, * the `includeFilter` parameter limits the tokens this method returns. * @param _oAuthAppCredentials AppCredentials for OAuth. * @returns The [TokenStatus](xref:botframework-connector.TokenStatus) objects retrieved. */ getTokenStatus(context: TurnContext, userId: string, includeFilter?: string, _oAuthAppCredentials?: any): Promise<any[]>; /** * Retrieves the OAuth token for a user that is in a sign-in flow. * * @param context Context for the current turn of conversation with the user. * @param connectionName Name of the auth connection to use. * @param magicCode (Optional) Optional user entered code to validate. * @returns The OAuth token for a user that is in a sign-in flow. */ getUserToken(context: TurnContext, connectionName: string, magicCode?: string): Promise<TokenResponse>; /** * Signs the user out with the token server. * * @param context Context for the current turn of conversation with the user. * @param connectionName Name of the auth connection to use. * @param userId User ID to sign out. */ signOutUser(context: TurnContext, connectionName?: string, userId?: string): Promise<void>; /** * Gets a signin link from the token server that can be sent as part of a SigninCard. * * @param context Context for the current turn of conversation with the user. * @param connectionName Name of the auth connection to use. * @returns A signin link from the token server that can be sent as part of a SigninCard. */ getSignInLink(context: TurnContext, connectionName: string): Promise<string>; /** * Signs the user out with the token server. * * @param _context Context for the current turn of conversation with the user. * @param _connectionName Name of the auth connection to use. * @param _resourceUrls The list of resource URLs to retrieve tokens for. * @returns A Dictionary of resourceUrl to the corresponding TokenResponse. */ getAadTokens(_context: TurnContext, _connectionName: string, _resourceUrls: string[]): Promise<{ [propertyName: string]: TokenResponse; }>; private exchangeableTokens; /** * Adds a fake exchangeable token so it can be exchanged later. * * @param connectionName Name of the auth connection to use. * @param channelId Channel ID. * @param userId User ID. * @param exchangeableItem Exchangeable token or resource URI. * @param token Token to store. */ addExchangeableToken(connectionName: string, channelId: string, userId: string, exchangeableItem: string, token: string): void; /** * Gets a sign-in resource. * * @param context [TurnContext](xref:botbuilder-core.TurnContext) for the current turn of conversation with the user. * @param connectionName Name of the auth connection to use. * @param userId User ID * @param _finalRedirect Final redirect URL. * @returns A `Promise` with a new [SignInUrlResponse](xref:botframework-schema.SignInUrlResponse) object. */ getSignInResource(context: TurnContext, connectionName: string, userId?: string, _finalRedirect?: string): Promise<SignInUrlResponse>; /** * Performs a token exchange operation such as for single sign-on. * * @param context [TurnContext](xref:botbuilder-core.TurnContext) for the current turn of conversation with the user. * @param connectionName Name of the auth connection to use. * @param userId User id associated with the token. * @param tokenExchangeRequest Exchange request details, either a token to exchange or a uri to exchange. * @returns If the promise completes, the exchanged token is returned. */ exchangeToken(context: TurnContext, connectionName: string, userId: string, tokenExchangeRequest: TokenExchangeRequest): Promise<TokenResponse>; /** * Adds an instruction to throw an exception during exchange requests. * * @param connectionName The connection name. * @param channelId The channel id. * @param userId The user id. * @param exchangeableItem The exchangeable token or resource URI. */ throwOnExchangeRequest(connectionName: string, channelId: string, userId: string, exchangeableItem: string): void; /** * Indicates if the activity is a reply from the bot (role == 'bot') * * @remarks * Checks to see if the from property and if from.role exists on the Activity before * checking to see who the activity is from. Otherwise returns false by default. * @param activity Activity to check. * @returns True if the activity is a reply from the bot, otherwise, false. */ private isReply; } /** * Support class for `TestAdapter` that allows for the simple construction of a sequence of tests. * * @remarks * Calling `adapter.send()` or `adapter.test()` will create a new test flow which you can chain * together additional tests using a fluent syntax. * * ```JavaScript * const { TestAdapter } = require('botbuilder'); * * const adapter = new TestAdapter(async (context) => { * if (context.text === 'hi') { * await context.sendActivity(`Hello World`); * } else if (context.text === 'bye') { * await context.sendActivity(`Goodbye`); * } * }); * * adapter.test(`hi`, `Hello World`) * .test(`bye`, `Goodbye`) * .then(() => done()); * ``` */ export declare class TestFlow { previous: Promise<void>; private adapter; private callback?; /** * @private * INTERNAL: creates a new TestFlow instance. * @param previous Promise chain for the current test sequence. * @param adapter Adapter under tested. * @param callback The bot turn processing logic to test. */ constructor(previous: Promise<void>, adapter: TestAdapter, callback?: (turnContext: TurnContext) => Promise<unknown>); /** * Send something to the bot and expects the bot to return with a given reply. This is simply a * wrapper around calls to `send()` and `assertReply()`. This is such a common pattern that a * helper is provided. * * @param userSays Text or activity simulating user input. * @param expected Expected text or activity of the reply sent by the bot. * @param description (Optional) Description of the test case. If not provided one will be generated. * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ test(userSays: string | Partial<Activity>, expected: string | Partial<Activity> | ((activity: Partial<Activity>, description?: string) => void), description?: string, timeout?: number): TestFlow; /** * Sends something to the bot. * * @param userSays Text or activity simulating user input. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ send(userSays: string | Partial<Activity>): TestFlow; /** * Creates a conversation update activity and process the activity. * * @returns {TestFlow} A new TestFlow object. */ sendConversationUpdate(): TestFlow; /** * Generates an assertion if the bots response doesn't match the expected text/activity. * * @param expected Expected text or activity from the bot. Can be a callback to inspect the response using custom logic. * @param description (Optional) Description of the test case. If not provided one will be generated. * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ assertReply(expected: string | Partial<Activity> | TestActivityInspector, description?: string, timeout?: number): TestFlow; /** * Generates an assertion that the turn processing logic did not generate a reply from the bot, as expected. * * @param description (Optional) Description of the test case. If not provided one will be generated. * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ assertNoReply(description?: string, timeout?: number): TestFlow; /** * Generates an assertion if the bots response is not one of the candidate strings. * * @param candidates List of candidate responses. * @param description (Optional) Description of the test case. If not provided one will be generated. * @param timeout (Optional) number of milliseconds to wait for a response from bot. Defaults to a value of `3000`. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ assertReplyOneOf(candidates: string[], description?: string, timeout?: number): TestFlow; /** * Inserts a delay before continuing. * * @param ms ms to wait. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ delay(ms: number): TestFlow; /** * Adds a `then()` step to the tests promise chain. * * @param onFulfilled Code to run if the test is currently passing. * @param onRejected Code to run if the test has thrown an error. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ then(onFulfilled?: () => void, onRejected?: (err: any) => void): TestFlow; /** * Adds a finally clause. Note that you can't keep chaining afterwards. * * @param onFinally Code to run after the test chain. * @returns {Promise<void>} A promise representing the async operation. */ finally(onFinally: () => void): Promise<void>; /** * Adds a `catch()` clause to the tests promise chain. * * @param onRejected Code to run if the test has thrown an error. * @returns A new [TestFlow](xref:botbuilder-core.TestFlow) object that appends this exchange to the modeled exchange. */ catch(onRejected?: (reason: any) => void): TestFlow; /** * Start the test sequence, returning a promise to await. * * @returns {Promise<void>} A promise representing the async operation. */ startTest(): Promise<void>; } //# sourceMappingURL=testAdapter.d.ts.map