diff --git a/libraries/botbuilder-dialogs-adaptive-testing/etc/botbuilder-dialogs-adaptive-testing.api.md b/libraries/botbuilder-dialogs-adaptive-testing/etc/botbuilder-dialogs-adaptive-testing.api.md index e04c3d30f2..1683116aa6 100644 --- a/libraries/botbuilder-dialogs-adaptive-testing/etc/botbuilder-dialogs-adaptive-testing.api.md +++ b/libraries/botbuilder-dialogs-adaptive-testing/etc/botbuilder-dialogs-adaptive-testing.api.md @@ -75,6 +75,7 @@ export class TestRunner { export class TestScript { description: string; dialog: DialogExpression; + languagePolicy: LanguagePolicy; enableTrace: boolean; execute(resourceExplorer: ResourceExplorer, testName?: string, testAdapter?: TestAdapter): Promise; locale: string; diff --git a/libraries/botbuilder-dialogs-adaptive-testing/src/testScript.ts b/libraries/botbuilder-dialogs-adaptive-testing/src/testScript.ts index d61f03fcb7..3724402180 100644 --- a/libraries/botbuilder-dialogs-adaptive-testing/src/testScript.ts +++ b/libraries/botbuilder-dialogs-adaptive-testing/src/testScript.ts @@ -8,7 +8,7 @@ import { ConversationState, MemoryStorage, UserState, useBotState, TestAdapter } from 'botbuilder-core'; import { Configurable, Converter, ConverterFactory, Dialog, DialogManager } from 'botbuilder-dialogs'; -import { LanguageGeneratorExtensions, ResourceExtensions } from 'botbuilder-dialogs-adaptive'; +import { LanguageGeneratorExtensions, LanguagePolicy, LanguagePolicyConverter, ResourceExtensions } from 'botbuilder-dialogs-adaptive'; import { ResourceExplorer } from 'botbuilder-dialogs-declarative'; import { TestAction } from './testAction'; import { UserTokenMock, UserTokenMocksConverter } from './userTokenMocks'; @@ -41,6 +41,7 @@ export interface TestScriptConfiguration { userTokenMocks?: string[] | UserTokenMock[]; script?: TestAction[]; enableTrace?: boolean; + languagePolicy?: Record | LanguagePolicy; } /** @@ -64,6 +65,11 @@ export class TestScript extends Configurable implements TestScriptConfiguration */ public locale = 'en-us'; + /** + * Language policy. + */ + public languagePolicy: LanguagePolicy; + /** * The mock data for Microsoft.OAuthInput. */ @@ -85,6 +91,8 @@ export class TestScript extends Configurable implements TestScriptConfiguration return DialogConverter; case 'userTokenMocks': return UserTokenMocksConverter; + case 'languagePolicy': + return new LanguagePolicyConverter(); default: return super.getConverter(property); } @@ -116,6 +124,10 @@ export class TestScript extends Configurable implements TestScriptConfiguration ResourceExtensions.useResourceExplorer(bot, resourceExplorer); LanguageGeneratorExtensions.useLanguageGeneration(bot); + if (this.languagePolicy) { + LanguageGeneratorExtensions.useLanguagePolicy(bot, this.languagePolicy); + } + this.userTokenMocks.forEach((userTokenMock) => { userTokenMock.setup(testAdapter); }); diff --git a/libraries/botbuilder-dialogs-adaptive-testing/tests/multiLanguageRecognizer.test.js b/libraries/botbuilder-dialogs-adaptive-testing/tests/multiLanguageRecognizer.test.js index d43bee0fa7..24507f2402 100644 --- a/libraries/botbuilder-dialogs-adaptive-testing/tests/multiLanguageRecognizer.test.js +++ b/libraries/botbuilder-dialogs-adaptive-testing/tests/multiLanguageRecognizer.test.js @@ -24,4 +24,8 @@ describe('MultiLanguageRecognizerTests', function() { it('EnUsFallback_AcitivtyLocaleCasing', async () => { await testRunner.runTestScript('MultiLanguageRecognizerTest_EnUsFallback_ActivityLocaleCasing'); }); + + it('LanguagePolicy', async () => { + await testRunner.runTestScript('MultiLanguageRecognizerTest_LanguagePolicy'); + }); }); diff --git a/libraries/botbuilder-dialogs-adaptive-testing/tests/resources/MultiLanguageRecognizerTests/MultiLanguageRecognizerTest_LanguagePolicy.test.dialog b/libraries/botbuilder-dialogs-adaptive-testing/tests/resources/MultiLanguageRecognizerTests/MultiLanguageRecognizerTest_LanguagePolicy.test.dialog new file mode 100644 index 0000000000..bb5dc7b157 --- /dev/null +++ b/libraries/botbuilder-dialogs-adaptive-testing/tests/resources/MultiLanguageRecognizerTests/MultiLanguageRecognizerTest_LanguagePolicy.test.dialog @@ -0,0 +1,126 @@ +{ + "$schema": "../../../../schemas/sdk.schema", + "$kind": "Microsoft.Test.Script", + "dialog": { + "$kind": "Microsoft.AdaptiveDialog", + "recognizer": { + "$kind": "Microsoft.MultiLanguageRecognizer", + "recognizers": { + "en-us": { + "$kind": "Microsoft.RegexRecognizer", + "intents": [ + { + "intent": "Greeting", + "pattern": "(?i)howdy" + }, + { + "intent": "Goodbye", + "pattern": "(?i)bye" + } + ] + }, + "en-gb": { + "$kind": "Microsoft.RegexRecognizer", + "intents": [ + { + "intent": "Greeting", + "pattern": "(?i)hiya" + }, + { + "intent": "Goodbye", + "pattern": "(?i)cheerio" + } + ] + }, + "en": { + "$kind": "Microsoft.RegexRecognizer", + "intents": [ + { + "intent": "Greeting", + "pattern": "(?i)hello" + }, + { + "intent": "Goodbye", + "pattern": "(?i)goodbye" + } + ] + }, + "": { + "$kind": "Microsoft.RegexRecognizer", + "intents": [ + { + "intent": "Greeting", + "pattern": "(?i)salve" + }, + { + "intent": "Goodbye", + "pattern": "(?i)vale dicere" + } + ] + } + } + }, + "triggers": [ + { + "$kind": "Microsoft.OnIntent", + "intent": "Greeting", + "actions": [ + { + "$kind": "Microsoft.SendActivity", + "activity": "greeting intent" + } + ] + }, + { + "$kind": "Microsoft.OnIntent", + "intent": "Goodbye", + "actions": [ + { + "$kind": "Microsoft.SendActivity", + "activity": "goodbye intent" + } + ] + }, + { + "$kind": "Microsoft.OnUnknownIntent", + "actions": [ + { + "$kind": "Microsoft.SendActivity", + "activity": "default rule" + } + ] + } + ], + "defaultResultProperty": "dialog.result" + }, + "languagePolicy": { + "": [ "en-gb", "" ] + }, + "locale": "", + "script": [ + { + "$kind": "Microsoft.Test.UserSays", + "text": "hiya" + }, + { + "$kind": "Microsoft.Test.AssertReply", + "text": "greeting intent" + }, + { + "$kind": "Microsoft.Test.UserSays", + "text": "howdy" + }, + { + "$kind": "Microsoft.Test.AssertReply", + "text": "default rule" + }, + { + "$kind": "Microsoft.Test.UserSays", + "text": "cheerio" + }, + { + "$kind": "Microsoft.Test.AssertReply", + "text": "goodbye intent" + } + ] +} diff --git a/libraries/botbuilder-dialogs-adaptive/src/recognizers/multiLanguageRecognizer.ts b/libraries/botbuilder-dialogs-adaptive/src/recognizers/multiLanguageRecognizer.ts index 52b704b582..aaf001fda5 100644 --- a/libraries/botbuilder-dialogs-adaptive/src/recognizers/multiLanguageRecognizer.ts +++ b/libraries/botbuilder-dialogs-adaptive/src/recognizers/multiLanguageRecognizer.ts @@ -11,6 +11,7 @@ import { Converter, ConverterFactory, DialogContext } from 'botbuilder-dialogs'; import { Recognizer, RecognizerConfiguration } from './recognizer'; import { LanguagePolicy, LanguagePolicyConverter } from '../languagePolicy'; import { MultiLanguageRecognizerConverter } from '../converters'; +import { languagePolicyKey } from '../languageGeneratorExtensions'; export interface MultiLanguageRecognizerConfiguration extends RecognizerConfiguration { languagePolicy?: Record | LanguagePolicy; @@ -20,7 +21,7 @@ export interface MultiLanguageRecognizerConfiguration extends RecognizerConfigur export class MultiLanguageRecognizer extends Recognizer implements MultiLanguageRecognizerConfiguration { public static $kind = 'Microsoft.MultiLanguageRecognizer'; - public languagePolicy: LanguagePolicy = new LanguagePolicy(); + public languagePolicy: LanguagePolicy; public recognizers: { [locale: string]: Recognizer }; @@ -41,15 +42,23 @@ export class MultiLanguageRecognizer extends Recognizer implements MultiLanguage telemetryProperties?: { [key: string]: string }, telemetryMetrics?: { [key: string]: number } ): Promise { + let languagepolicy: LanguagePolicy = this.languagePolicy; + if (!languagepolicy) { + languagepolicy = dialogContext.services.get(languagePolicyKey); + if (!languagepolicy) { + languagepolicy = new LanguagePolicy(); + } + } + const locale = activity.locale || ''; const policy: string[] = []; - if (this.languagePolicy.has(locale)) { - this.languagePolicy.get(locale).forEach((u: string): number => policy.push(u)); + if (languagepolicy.has(locale)) { + languagepolicy.get(locale).forEach((u: string): number => policy.push(u)); } - if (locale !== '' && this.languagePolicy.has('')) { + if (locale !== '' && languagepolicy.has('')) { // we now explictly add defaultPolicy instead of coding that into target's policy - this.languagePolicy.get('').forEach((u: string): number => policy.push(u)); + languagepolicy.get('').forEach((u: string): number => policy.push(u)); } for (let i = 0; i < policy.length; i++) {