Spaces:
Build error
Build error
Validify-testbot-1
/
botbuilder-python
/libraries
/botbuilder-dialogs
/tests
/test_confirm_prompt.py
| # Copyright (c) Microsoft Corporation. All rights reserved. | |
| # Licensed under the MIT License. | |
| from typing import List | |
| import aiounittest | |
| from botbuilder.core import ( | |
| ConversationState, | |
| MemoryStorage, | |
| TurnContext, | |
| MessageFactory, | |
| ) | |
| from botbuilder.core.adapters import TestAdapter | |
| from botbuilder.dialogs import DialogSet, DialogTurnResult, DialogTurnStatus | |
| from botbuilder.dialogs.choices import Choice, ChoiceFactoryOptions, ListStyle | |
| from botbuilder.dialogs.prompts import ( | |
| ConfirmPrompt, | |
| PromptCultureModel, | |
| PromptOptions, | |
| PromptValidatorContext, | |
| ) | |
| from botbuilder.schema import Activity, ActivityTypes | |
| class ConfirmPromptTest(aiounittest.AsyncTestCase): | |
| def test_confirm_prompt_with_empty_id_should_fail(self): | |
| empty_id = "" | |
| with self.assertRaises(TypeError): | |
| ConfirmPrompt(empty_id) | |
| def test_confirm_prompt_with_none_id_should_fail(self): | |
| none_id = None | |
| with self.assertRaises(TypeError): | |
| ConfirmPrompt(none_id) | |
| async def test_confirm_prompt(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm.") | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Please confirm. (1) Yes or (2) No") | |
| step3 = await step2.send("yes") | |
| await step3.assert_reply("Confirmed") | |
| async def test_confirm_prompt_retry(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="Please confirm, say 'yes' or 'no' or something like that.", | |
| ), | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Please confirm. (1) Yes or (2) No") | |
| step3 = await step2.send("lala") | |
| step4 = await step3.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No" | |
| ) | |
| step5 = await step4.send("no") | |
| await step5.assert_reply("Not confirmed") | |
| async def test_confirm_prompt_no_options(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| await dialog_context.prompt("ConfirmPrompt", PromptOptions()) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply(" (1) Yes or (2) No") | |
| step3 = await step2.send("lala") | |
| step4 = await step3.assert_reply(" (1) Yes or (2) No") | |
| step5 = await step4.send("no") | |
| await step5.assert_reply("Not confirmed") | |
| async def test_confirm_prompt_choice_options_numbers(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="Please confirm, say 'yes' or 'no' or something like that.", | |
| ), | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| confirm_prompt.choice_options = ChoiceFactoryOptions(include_numbers=True) | |
| confirm_prompt.style = ListStyle.in_line | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Please confirm. (1) Yes or (2) No") | |
| step3 = await step2.send("lala") | |
| step4 = await step3.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No" | |
| ) | |
| step5 = await step4.send("2") | |
| await step5.assert_reply("Not confirmed") | |
| async def test_confirm_prompt_choice_options_multiple_attempts(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="Please confirm, say 'yes' or 'no' or something like that.", | |
| ), | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| confirm_prompt.choice_options = ChoiceFactoryOptions(include_numbers=True) | |
| confirm_prompt.style = ListStyle.in_line | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Please confirm. (1) Yes or (2) No") | |
| step3 = await step2.send("lala") | |
| step4 = await step3.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No" | |
| ) | |
| step5 = await step4.send("what") | |
| step6 = await step5.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No" | |
| ) | |
| step7 = await step6.send("2") | |
| await step7.assert_reply("Not confirmed") | |
| async def test_confirm_prompt_options_no_numbers(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="Please confirm, say 'yes' or 'no' or something like that.", | |
| ), | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt", default_locale="English") | |
| confirm_prompt.choice_options = ChoiceFactoryOptions( | |
| include_numbers=False, inline_separator="~" | |
| ) | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Please confirm. Yes or No") | |
| step3 = await step2.send("2") | |
| step4 = await step3.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. Yes or No" | |
| ) | |
| step5 = await step4.send("no") | |
| await step5.assert_reply("Not confirmed") | |
| async def test_confirm_prompt_should_default_to_english_locale(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="Please confirm, say 'yes' or 'no' or something like that.", | |
| ), | |
| ) | |
| await dialog_context.prompt("ConfirmPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| message_text = "Confirmed" if results.result else "Not confirmed" | |
| await turn_context.send_activity(MessageFactory.text(message_text)) | |
| await convo_state.save_changes(turn_context) | |
| locales = [None, "", "not-supported"] | |
| for locale in locales: | |
| # Initialize TestAdapter. | |
| adapter = TestAdapter(exec_test) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| convo_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet, and ChoicePrompt. | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| confirm_prompt = ConfirmPrompt("ConfirmPrompt") | |
| confirm_prompt.choice_options = ChoiceFactoryOptions(include_numbers=True) | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send( | |
| Activity(type=ActivityTypes.message, text="Hello", locale=locale) | |
| ) | |
| step2 = await step1.assert_reply("Please confirm. (1) Yes or (2) No") | |
| step3 = await step2.send("lala") | |
| step4 = await step3.assert_reply( | |
| "Please confirm, say 'yes' or 'no' or something like that. (1) Yes or (2) No" | |
| ) | |
| step5 = await step4.send("2") | |
| await step5.assert_reply("Not confirmed") | |
| async def test_should_recognize_locale_variations_of_correct_locales(self): | |
| def cap_ending(locale: str) -> str: | |
| return f"{locale.split('-')[0]}-{locale.split('-')[1].upper()}" | |
| def title_ending(locale: str) -> str: | |
| return locale[:3] + locale[3].upper() + locale[4:] | |
| def cap_two_letter(locale: str) -> str: | |
| return locale.split("-")[0].upper() | |
| def lower_two_letter(locale: str) -> str: | |
| return locale.split("-")[0].upper() | |
| async def exec_test_for_locale(valid_locale: str, locale_variations: List): | |
| # Hold the correct answer from when a valid locale is used | |
| expected_answer = None | |
| def inspector(activity: Activity, description: str): | |
| nonlocal expected_answer | |
| assert not description | |
| if valid_locale == test_locale: | |
| expected_answer = activity.text | |
| else: | |
| # Ensure we're actually testing a variation. | |
| assert activity.locale != valid_locale | |
| assert activity.text == expected_answer | |
| return True | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity( | |
| type=ActivityTypes.message, text="Please confirm." | |
| ) | |
| ) | |
| await dialog_context.prompt("prompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| confirmed = results.result | |
| if confirmed: | |
| await turn_context.send_activity("true") | |
| else: | |
| await turn_context.send_activity("false") | |
| await convo_state.save_changes(turn_context) | |
| async def validator(prompt: PromptValidatorContext) -> bool: | |
| assert prompt | |
| if not prompt.recognized.succeeded: | |
| await prompt.context.send_activity("Bad input.") | |
| return prompt.recognized.succeeded | |
| test_locale = None | |
| for test_locale in locale_variations: | |
| adapter = TestAdapter(exec_test) | |
| convo_state = ConversationState(MemoryStorage()) | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| choice_prompt = ConfirmPrompt("prompt", validator) | |
| dialogs.add(choice_prompt) | |
| step1 = await adapter.send( | |
| Activity( | |
| type=ActivityTypes.message, text="Hello", locale=test_locale | |
| ) | |
| ) | |
| await step1.assert_reply(inspector) | |
| locales = [ | |
| "zh-cn", | |
| "nl-nl", | |
| "en-us", | |
| "fr-fr", | |
| "de-de", | |
| "it-it", | |
| "ja-jp", | |
| "ko-kr", | |
| "pt-br", | |
| "es-es", | |
| "tr-tr", | |
| "de-de", | |
| ] | |
| locale_tests = [] | |
| for locale in locales: | |
| locale_tests.append( | |
| [ | |
| locale, | |
| cap_ending(locale), | |
| title_ending(locale), | |
| cap_two_letter(locale), | |
| lower_two_letter(locale), | |
| ] | |
| ) | |
| # Test each valid locale | |
| for locale_tests in locale_tests: | |
| await exec_test_for_locale(locale_tests[0], locale_tests) | |
| async def test_should_recognize_and_use_custom_locale_dict( | |
| self, | |
| ): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results: DialogTurnResult = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please confirm.") | |
| ) | |
| await dialog_context.prompt("prompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| selected_choice = results.result | |
| await turn_context.send_activity(selected_choice.value) | |
| await convo_state.save_changes(turn_context) | |
| async def validator(prompt: PromptValidatorContext) -> bool: | |
| assert prompt | |
| if not prompt.recognized.succeeded: | |
| await prompt.context.send_activity("Bad input.") | |
| return prompt.recognized.succeeded | |
| adapter = TestAdapter(exec_test) | |
| convo_state = ConversationState(MemoryStorage()) | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| culture = PromptCultureModel( | |
| locale="custom-locale", | |
| no_in_language="customNo", | |
| yes_in_language="customYes", | |
| separator="customSeparator", | |
| inline_or="customInlineOr", | |
| inline_or_more="customInlineOrMore", | |
| ) | |
| custom_dict = { | |
| culture.locale: ( | |
| Choice(culture.yes_in_language), | |
| Choice(culture.no_in_language), | |
| ChoiceFactoryOptions( | |
| culture.separator, culture.inline_or, culture.inline_or_more, True | |
| ), | |
| ) | |
| } | |
| confirm_prompt = ConfirmPrompt("prompt", validator, choice_defaults=custom_dict) | |
| dialogs.add(confirm_prompt) | |
| step1 = await adapter.send( | |
| Activity(type=ActivityTypes.message, text="Hello", locale=culture.locale) | |
| ) | |
| await step1.assert_reply( | |
| "Please confirm. (1) customYescustomInlineOr(2) customNo" | |
| ) | |