ChoicePrompt handles null locales

This commit is contained in:
mdrichardson 2019-11-08 09:39:30 -08:00
Родитель b885980d85
Коммит 3559ebbebe
3 изменённых файлов: 84 добавлений и 4 удалений

Просмотреть файл

@ -123,10 +123,10 @@ namespace Microsoft.Bot.Builder.Dialogs
}
// Determine culture
var culture = MapToNearestLanguage(turnContext.Activity.Locale ?? DefaultLocale);
if (string.IsNullOrEmpty(culture) || !_choiceDefaults.ContainsKey(culture))
var culture = turnContext.Activity.Locale ?? DefaultLocale ?? English.Locale;
if (!_choiceDefaults.ContainsKey(culture))
{
culture = English.Locale;
culture = MapToNearestLanguage(culture);
}
// Format prompt to send

Просмотреть файл

@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Linq;
using Microsoft.Recognizers.Text;
namespace Microsoft.Bot.Builder.Dialogs.Prompts
@ -10,6 +12,8 @@ namespace Microsoft.Bot.Builder.Dialogs.Prompts
/// </summary>
public static class PromptCultureModels
{
private static readonly string[] SupportedLocales = GetSupportedCultures().Select(c => c.Locale).ToArray();
public static PromptCultureModel Chinese =>
new PromptCultureModel
{
@ -103,7 +107,35 @@ namespace Microsoft.Bot.Builder.Dialogs.Prompts
/// </summary>
/// <param name="cultureCode">Represents locale. Examples: "en-US, en-us, EN".</param>
/// <returns>Normalized locale.</returns>
public static string MapToNearestLanguage(string cultureCode) => Culture.MapToNearestLanguage(cultureCode);
public static string MapToNearestLanguage(string cultureCode)
{
cultureCode = cultureCode.ToLowerInvariant();
if (SupportedLocales.All(o => o != cultureCode))
{
// Handle cases like EnglishOthers with cultureCode "en-*"
var fallbackCultureCodes = SupportedLocales
.Where(o => o.EndsWith("*", StringComparison.Ordinal) &&
cultureCode.StartsWith(o.Split('-').First(), StringComparison.Ordinal)).ToList();
if (fallbackCultureCodes.Count == 1)
{
return fallbackCultureCodes.First();
}
// If there is no cultureCode like "-*", map only the prefix
// For example, "es-mx" will be mapped to "es-es"
fallbackCultureCodes = SupportedLocales
.Where(o => cultureCode.StartsWith(o.Split('-').First(), StringComparison.Ordinal)).ToList();
if (fallbackCultureCodes.Any())
{
return fallbackCultureCodes.First();
}
}
return cultureCode;
}
public static PromptCultureModel[] GetSupportedCultures() => new PromptCultureModel[]
{

Просмотреть файл

@ -654,6 +654,54 @@ namespace Microsoft.Bot.Builder.Dialogs.Tests
.StartTestAsync();
}
[TestMethod]
public async Task ShouldDefaultToEnglishLocale()
{
var convoState = new ConversationState(new MemoryStorage());
var dialogState = convoState.CreateProperty<DialogState>("dialogState");
var adapter = new TestAdapter()
.Use(new AutoSaveStateMiddleware(convoState));
// Create new DialogSet.
var dialogs = new DialogSet(dialogState);
dialogs.Add(new ChoicePrompt("ChoicePrompt", defaultLocale: null));
var helloLocale = MessageFactory.Text("hello");
helloLocale.Locale = null;
await new TestFlow(adapter, async (turnContext, cancellationToken) =>
{
var dc = await dialogs.CreateContextAsync(turnContext, cancellationToken);
var results = await dc.ContinueDialogAsync(cancellationToken);
if (results.Status == DialogTurnStatus.Empty)
{
await dc.PromptAsync(
"ChoicePrompt",
new PromptOptions
{
Prompt = new Activity { Type = ActivityTypes.Message, Text = "favorite color?", Locale = null },
Choices = _colorChoices,
},
cancellationToken);
}
})
.Send(helloLocale)
.AssertReply((activity) =>
{
// Use ChoiceFactory to build the expected answer, manually
var expectedChoices = ChoiceFactory.Inline(_colorChoices, null, null, new ChoiceFactoryOptions()
{
InlineOr = English.InlineOr,
InlineOrMore = English.InlineOrMore,
InlineSeparator = English.Separator,
}).Text;
Assert.AreEqual($"favorite color?{expectedChoices}", activity.AsMessageActivity().Text);
})
.StartTestAsync();
}
[TestMethod]
public async Task ShouldAcceptAndRecognizeCustomLocaleDict()
{