Spaces:
Build error
Build error
| # Copyright (c) Microsoft Corporation. All rights reserved. | |
| # Licensed under the MIT License. | |
| from typing import Callable | |
| import aiounittest | |
| from recognizers_text import Culture | |
| from botbuilder.dialogs import DialogContext, DialogTurnResult | |
| from botbuilder.dialogs.prompts import ( | |
| NumberPrompt, | |
| PromptOptions, | |
| PromptValidatorContext, | |
| ) | |
| from botbuilder.core import ( | |
| MemoryStorage, | |
| ConversationState, | |
| TurnContext, | |
| MessageFactory, | |
| ) | |
| from botbuilder.core.adapters import TestAdapter, TestFlow | |
| from botbuilder.dialogs import DialogSet, DialogTurnStatus | |
| from botbuilder.schema import Activity, ActivityTypes | |
| class NumberPromptMock(NumberPrompt): | |
| def __init__( | |
| self, | |
| dialog_id: str, | |
| validator: Callable[[PromptValidatorContext], bool] = None, | |
| default_locale=None, | |
| ): | |
| super().__init__(dialog_id, validator, default_locale) | |
| async def on_prompt_null_context(self, options: PromptOptions): | |
| # Should throw TypeError | |
| await self.on_prompt( | |
| turn_context=None, state=None, options=options, is_retry=False | |
| ) | |
| async def on_prompt_null_options(self, dialog_context: DialogContext): | |
| # Should throw TypeError | |
| await self.on_prompt( | |
| dialog_context.context, state=None, options=None, is_retry=False | |
| ) | |
| async def on_recognize_null_context(self): | |
| # Should throw TypeError | |
| await self.on_recognize(turn_context=None, state=None, options=None) | |
| class NumberPromptTests(aiounittest.AsyncTestCase): | |
| def test_empty_id_should_fail(self): | |
| # pylint: disable=no-value-for-parameter | |
| empty_id = "" | |
| self.assertRaises(TypeError, lambda: NumberPrompt(empty_id)) | |
| def test_none_id_should_fail(self): | |
| # pylint: disable=no-value-for-parameter | |
| self.assertRaises(TypeError, lambda: NumberPrompt(dialog_id=None)) | |
| async def test_with_null_turn_context_should_fail(self): | |
| number_prompt_mock = NumberPromptMock("NumberPromptMock") | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Please send a number.") | |
| ) | |
| with self.assertRaises(TypeError): | |
| await number_prompt_mock.on_prompt_null_context(options) | |
| async def test_on_prompt_with_null_options_fails(self): | |
| conver_state = ConversationState(MemoryStorage()) | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| number_prompt_mock = NumberPromptMock( | |
| dialog_id="NumberPromptMock", validator=None, default_locale=Culture.English | |
| ) | |
| dialogs.add(number_prompt_mock) | |
| with self.assertRaises(TypeError): | |
| await number_prompt_mock.on_recognize_null_context() | |
| async def test_number_prompt(self): | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| conver_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet and register the WaterfallDialog. | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| # Create and add number prompt to DialogSet. | |
| number_prompt = NumberPrompt("NumberPrompt", None, Culture.English) | |
| dialogs.add(number_prompt) | |
| async def exec_test(turn_context: TurnContext) -> None: | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| await dialog_context.begin_dialog( | |
| "NumberPrompt", | |
| PromptOptions( | |
| prompt=MessageFactory.text("Enter quantity of cable") | |
| ), | |
| ) | |
| else: | |
| if results.status == DialogTurnStatus.Complete: | |
| number_result = results.result | |
| await turn_context.send_activity( | |
| MessageFactory.text( | |
| f"You asked me for '{number_result}' meters of cable." | |
| ) | |
| ) | |
| await conver_state.save_changes(turn_context) | |
| adapter = TestAdapter(exec_test) | |
| test_flow = TestFlow(None, adapter) | |
| test_flow2 = await test_flow.send("Hello") | |
| test_flow3 = await test_flow2.assert_reply("Enter quantity of cable") | |
| test_flow4 = await test_flow3.send("Give me twenty meters of cable") | |
| await test_flow4.assert_reply("You asked me for '20' meters of cable.") | |
| async def test_number_prompt_retry(self): | |
| async def exec_test(turn_context: TurnContext) -> None: | |
| dialog_context: DialogContext = 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="Enter a number."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, text="You must enter a number." | |
| ), | |
| ) | |
| await dialog_context.prompt("NumberPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| number_result = results.result | |
| await turn_context.send_activity( | |
| MessageFactory.text(f"Bot received the number '{number_result}'.") | |
| ) | |
| await convo_state.save_changes(turn_context) | |
| adapter = TestAdapter(exec_test) | |
| convo_state = ConversationState(MemoryStorage()) | |
| dialog_state = convo_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| number_prompt = NumberPrompt( | |
| dialog_id="NumberPrompt", validator=None, default_locale=Culture.English | |
| ) | |
| dialogs.add(number_prompt) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Enter a number.") | |
| step3 = await step2.send("hello") | |
| step4 = await step3.assert_reply("You must enter a number.") | |
| step5 = await step4.send("64") | |
| await step5.assert_reply("Bot received the number '64'.") | |
| async def test_number_uses_locale_specified_in_constructor(self): | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| conver_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet and register the WaterfallDialog. | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| # Create and add number prompt to DialogSet. | |
| number_prompt = NumberPrompt( | |
| "NumberPrompt", None, default_locale=Culture.Spanish | |
| ) | |
| dialogs.add(number_prompt) | |
| async def exec_test(turn_context: TurnContext) -> None: | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| await dialog_context.begin_dialog( | |
| "NumberPrompt", | |
| PromptOptions( | |
| prompt=MessageFactory.text( | |
| "How much money is in your gaming account?" | |
| ) | |
| ), | |
| ) | |
| else: | |
| if results.status == DialogTurnStatus.Complete: | |
| number_result = results.result | |
| await turn_context.send_activity( | |
| MessageFactory.text( | |
| f"You say you have ${number_result} in your gaming account." | |
| ) | |
| ) | |
| await conver_state.save_changes(turn_context) | |
| adapter = TestAdapter(exec_test) | |
| test_flow = TestFlow(None, adapter) | |
| test_flow2 = await test_flow.send("Hello") | |
| test_flow3 = await test_flow2.assert_reply( | |
| "How much money is in your gaming account?" | |
| ) | |
| test_flow4 = await test_flow3.send("I've got $1.200.555,42 in my account.") | |
| await test_flow4.assert_reply( | |
| "You say you have $1200555.42 in your gaming account." | |
| ) | |
| async def test_number_prompt_validator(self): | |
| async def exec_test(turn_context: TurnContext) -> None: | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Enter a number."), | |
| retry_prompt=Activity( | |
| type=ActivityTypes.message, | |
| text="You must enter a positive number less than 100.", | |
| ), | |
| ) | |
| await dialog_context.prompt("NumberPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| number_result = int(results.result) | |
| await turn_context.send_activity( | |
| MessageFactory.text(f"Bot received the number '{number_result}'.") | |
| ) | |
| await conver_state.save_changes(turn_context) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| conver_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet and register the WaterfallDialog. | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| # Create and add number prompt to DialogSet. | |
| async def validator(prompt_context: PromptValidatorContext): | |
| result = prompt_context.recognized.value | |
| if 0 < result < 100: | |
| return True | |
| return False | |
| number_prompt = NumberPrompt( | |
| "NumberPrompt", validator, default_locale=Culture.English | |
| ) | |
| dialogs.add(number_prompt) | |
| adapter = TestAdapter(exec_test) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Enter a number.") | |
| step3 = await step2.send("150") | |
| step4 = await step3.assert_reply( | |
| "You must enter a positive number less than 100." | |
| ) | |
| step5 = await step4.send("64") | |
| await step5.assert_reply("Bot received the number '64'.") | |
| async def test_float_number_prompt(self): | |
| async def exec_test(turn_context: TurnContext) -> None: | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Enter a number.") | |
| ) | |
| await dialog_context.prompt("NumberPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| number_result = float(results.result) | |
| await turn_context.send_activity( | |
| MessageFactory.text(f"Bot received the number '{number_result}'.") | |
| ) | |
| await conver_state.save_changes(turn_context) | |
| # Create new ConversationState with MemoryStorage and register the state as middleware. | |
| conver_state = ConversationState(MemoryStorage()) | |
| # Create a DialogState property, DialogSet and register the WaterfallDialog. | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| # Create and add number prompt to DialogSet. | |
| number_prompt = NumberPrompt( | |
| "NumberPrompt", validator=None, default_locale=Culture.English | |
| ) | |
| dialogs.add(number_prompt) | |
| adapter = TestAdapter(exec_test) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Enter a number.") | |
| step3 = await step2.send("3.14") | |
| await step3.assert_reply("Bot received the number '3.14'.") | |
| async def test_number_prompt_uses_locale_specified_in_activity(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Enter a number.") | |
| ) | |
| await dialog_context.prompt("NumberPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| number_result = float(results.result) | |
| self.assertEqual(3.14, number_result) | |
| await conver_state.save_changes(turn_context) | |
| conver_state = ConversationState(MemoryStorage()) | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| number_prompt = NumberPrompt("NumberPrompt", None, None) | |
| dialogs.add(number_prompt) | |
| adapter = TestAdapter(exec_test) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Enter a number.") | |
| await step2.send( | |
| Activity(type=ActivityTypes.message, text="3,14", locale=Culture.Spanish) | |
| ) | |
| async def test_number_prompt_defaults_to_en_us_culture(self): | |
| async def exec_test(turn_context: TurnContext): | |
| dialog_context = await dialogs.create_context(turn_context) | |
| results = await dialog_context.continue_dialog() | |
| if results.status == DialogTurnStatus.Empty: | |
| options = PromptOptions( | |
| prompt=Activity(type=ActivityTypes.message, text="Enter a number.") | |
| ) | |
| await dialog_context.prompt("NumberPrompt", options) | |
| elif results.status == DialogTurnStatus.Complete: | |
| number_result = float(results.result) | |
| await turn_context.send_activity( | |
| MessageFactory.text(f"Bot received the number '{number_result}'.") | |
| ) | |
| await conver_state.save_changes(turn_context) | |
| conver_state = ConversationState(MemoryStorage()) | |
| dialog_state = conver_state.create_property("dialogState") | |
| dialogs = DialogSet(dialog_state) | |
| number_prompt = NumberPrompt("NumberPrompt") | |
| dialogs.add(number_prompt) | |
| adapter = TestAdapter(exec_test) | |
| step1 = await adapter.send("hello") | |
| step2 = await step1.assert_reply("Enter a number.") | |
| step3 = await step2.send("3.14") | |
| await step3.assert_reply("Bot received the number '3.14'.") | |