def test_state_none_name(self): # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) # Act with self.assertRaises(TypeError) as _: user_state.create_property(None)
async def test_state_multiple_loads(self): """Should be able to load multiple times""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act user_state.create_property("property_a") await user_state.load(context) await user_state.load(context)
def __init__( self, config: DefaultConfig, conversation_state: ConversationState, user_state: UserState, dialog: Dialog ): luis_application = LuisApplication( config.LUIS_APP_ID, config.LUIS_API_KEY, "https://" + config.LUIS_API_HOST_NAME ) luis_options = LuisPredictionOptions(include_all_intents=True, include_instance_data=True) self.recognizer = LuisRecognizer(luis_application, luis_options, True) self.subscription_key = config.LUIS_API_KEY self.version_id = config.LUIS_APP_VERSION_ID # 可空白或直接填寫一個現有的luis app,不過需要注意其version_id是否與config.py裡的一樣 self.luis_appid = '' # 激活dialog_data.py裡的資訊 self.user_profile_accessor = user_state.create_property("DialogData") if conversation_state is None: raise TypeError("[DialogBot]: Missing parameter. conversation_state is required but None was given") if user_state is None: raise TypeError("[DialogBot]: Missing parameter. user_state is required but None was given") if dialog is None: raise Exception("[DialogBot]: Missing parameter. dialog is required") self.conversation_state = conversation_state self.user_state = user_state self.dialog = dialog
def __init__(self, user_state: UserState, luis_recognizer: InsuranceQueryRecognizer, insurance_renewal_dialog: InsuranceRenewalDialog, reservation_booking_dialog: ReservationBookingDialog): super(MainDialog, self).__init__(MainDialog.__name__) self.qna_maker = QnAMaker( QnAMakerEndpoint(knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID, endpoint_key=config.QNA_ENDPOINT_KEY, host=config.QNA_ENDPOINT_HOST)) self.user_profile_accessor = user_state.create_property("UserData") self.insurance_renewal_dialog_id = insurance_renewal_dialog.id self.reservation_booking_dialog_id = reservation_booking_dialog.id self._luis_recognizer = luis_recognizer self.user_state = user_state self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog(ChoicePrompt(INS_PROMPT_OPTIONS)) self.add_dialog(insurance_renewal_dialog) self.add_dialog(reservation_booking_dialog) self.add_dialog( WaterfallDialog("WFDialog", [ self.intro_step, self.name_process_step, self.luis_query_step, self.closing_step ])) self.initial_dialog_id = "WFDialog"
def __init__(self, nlu_recognizer: NLU, user_state: UserState): super(BookingRoomDialog, self).__init__(BookingRoomDialog.__name__) # Load the NLU module self._nlu_recognizer = nlu_recognizer # Load the RoomReservation class self.room_reservation_accessor = user_state.create_property( "RoomReservation") # Setup the waterfall dialog self.add_dialog( WaterfallDialog("WFBookingDialog", [ self.people_step, self.duration_step, self.breakfast_step, self.summary_step, ])) # Append the prompts and custom prompts self.add_dialog( NumberPrompt("PeoplePrompt", BookingRoomDialog.people_prompt_validator)) self.add_dialog( NumberPrompt("DurationPrompt", BookingRoomDialog.duration_prompt_validator)) self.add_dialog(ConfirmPrompt("IsTakingBreakfastPrompt")) self.initial_dialog_id = "WFBookingDialog"
def __init__(self, user_state: UserState, course: Course, luis_recognizer: Recognizer, dialog_id: str = None): super(StudentProfileDialog, self).__init__(dialog_id or StudentProfileDialog.__name__) self.course = course self.luis_recognizer = luis_recognizer # create accessor self.student_profile_accessor: StatePropertyAccessor = user_state.create_property("StudentProfile") # add dialogs self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.name_step, self.admission_number_step, self.picture_step, self.courses_step, self.summary_step ] ), ) self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) self.add_dialog(AttachmentPrompt(AttachmentPrompt.__name__, StudentProfileDialog.picture_prompt_validator)) self.add_dialog(CourseQueryDialog(course, luis_recognizer, CourseQueryDialog.__name__)) self.initial_dialog_id = WaterfallDialog.__name__
def __init__(self, user_state: UserState): super(UserProfileDialog, self).__init__(UserProfileDialog.__name__) self.user_profile_accessor = user_state.create_property("UserProfile") self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.transport_step, self.name_step, self.name_confirm_step, self.age_step, self.picture_step, self.confirm_step, self.summary_step, ], )) self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog( NumberPrompt(NumberPrompt.__name__, UserProfileDialog.age_prompt_validator)) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) self.add_dialog( AttachmentPrompt(AttachmentPrompt.__name__, UserProfileDialog.picture_prompt_validator)) self.initial_dialog_id = WaterfallDialog.__name__
def __init__(self, user_state: UserState): super(WaterfallMain, self).__init__(WaterfallMain.__name__) self.user_profile_accessor = user_state.create_property("UserProfile") luisRecognizer = CalcoloImportoRecognizer(configuration=DefaultConfig) calcoloDialog = CalcoloDialog() cancellaDialogo = CancellaDialogo() self.add_dialog( WaterfallQuery(luis_recognizer=luisRecognizer, calcolo_dialog=calcoloDialog, cancella_dialogo=cancellaDialogo)) self.add_dialog(WaterfallPhoto(WaterfallPhoto.__name__)) self.add_dialog(WaterfallText(WaterfallText.__name__)) self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.what_step, self.summary_step, self.replace_step, ], )) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.initial_dialog_id = WaterfallDialog.__name__
def __init__(self, user_state: UserState): super(UserProfileDialog, self).__init__(UserProfileDialog.__name__) self.user_profile_accessor = user_state.create_property("UserProfile") self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.first_step, self.second_step, self.third_step, self.fourth_step, self.fifth_step, self.sixth_step, self.seventh_step, self.eighth_step, ], )) self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog( NumberPrompt(NumberPrompt.__name__, UserProfileDialog.age_prompt_validator)) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) self.add_dialog( AttachmentPrompt(AttachmentPrompt.__name__, UserProfileDialog.picture_prompt_validator)) self.initial_dialog_id = WaterfallDialog.__name__
def __init__(self, dialog_id: str, connection_name: str, user_state: UserState, logged_users: Dict[str, str]): super(LogoutDialog, self).__init__(dialog_id) self.connection_name = connection_name self.user_profile_accessor = user_state.create_property("UserProfile") self.logged_users = logged_users
async def test_user_state_bad_from_throws(self): dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() context.activity.from_property = None test_property = user_state.create_property("test") with self.assertRaises(AttributeError): await test_property.get(context)
async def test_state_set_no_load(self): """Should be able to set a property with no Load""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property_a") await property_a.set(context, "hello")
async def test_state_get_no_load_with_default(self): """Should be able to get a property with no Load and default""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property_a") value_a = await property_a.get(context, lambda: "Default!") self.assertEqual("Default!", value_a)
async def test_state_bool_no_default(self): """Cannot get a bool with no default set""" # Arange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act test_property = user_state.create_property("test") value = await test_property.get(context) # Assert self.assertFalse(value)
async def test_load_set_save_twice(self): # Arrange dictionary = {} context = TestUtilities.create_empty_context() # Act user_state = UserState(MemoryStorage(dictionary)) property_a = user_state.create_property("property-a") property_b = user_state.create_property("property-b") property_c = user_state.create_property("property-c") await user_state.load(context) await property_a.set(context, "hello") await property_b.set(context, "world") await property_c.set(context, "test") await user_state.save_changes(context) # Assert obj = dictionary["EmptyContext/users/[email protected]"] self.assertEqual("hello", obj["property-a"]) self.assertEqual("world", obj["property-b"]) # Act 2 user_state2 = UserState(MemoryStorage(dictionary)) property_a2 = user_state2.create_property("property-a") property_b2 = user_state2.create_property("property-b") await user_state2.load(context) await property_a2.set(context, "hello-2") await property_b2.set(context, "world-2") await user_state2.save_changes(context) # Assert 2 obj2 = dictionary["EmptyContext/users/[email protected]"] self.assertEqual("hello-2", obj2["property-a"]) self.assertEqual("world-2", obj2["property-b"]) self.assertEqual("test", obj2["property-c"])
async def test_state_get_no_load_no_default(self): """Cannot get a string with no default set""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property_a") value_a = await property_a.get(context) # Assert self.assertIsNone(value_a)
async def test_load_save_delete(self): # Arrange dictionary = {} context = TestUtilities.create_empty_context() # Act user_state = UserState(MemoryStorage(dictionary)) property_a = user_state.create_property("property-a") property_b = user_state.create_property("property-b") await user_state.load(context) await property_a.set(context, "hello") await property_b.set(context, "world") await user_state.save_changes(context) # Assert obj = dictionary["EmptyContext/users/[email protected]"] self.assertEqual("hello", obj["property-a"]) self.assertEqual("world", obj["property-b"]) # Act 2 user_state2 = UserState(MemoryStorage(dictionary)) property_a2 = user_state2.create_property("property-a") property_b2 = user_state2.create_property("property-b") await user_state2.load(context) await property_a2.set(context, "hello-2") await property_b2.delete(context) await user_state2.save_changes(context) # Assert 2 obj2 = dictionary["EmptyContext/users/[email protected]"] self.assertEqual("hello-2", obj2["property-a"]) with self.assertRaises(KeyError) as _: obj2["property-b"] # pylint: disable=pointless-statement
async def test_storage_not_called_no_changes(self): """Verify storage not called when no changes are made""" # Mock a storage provider, which counts read/writes dictionary = {} async def mock_write_result(self): # pylint: disable=unused-argument return async def mock_read_result(self): # pylint: disable=unused-argument return {} mock_storage = MemoryStorage(dictionary) mock_storage.write = MagicMock(side_effect=mock_write_result) mock_storage.read = MagicMock(side_effect=mock_read_result) # Arrange user_state = UserState(mock_storage) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property_a") self.assertEqual(mock_storage.write.call_count, 0) await user_state.save_changes(context) await property_a.set(context, "hello") self.assertEqual(mock_storage.read.call_count, 1) # Initial save bumps count self.assertEqual(mock_storage.write.call_count, 0) # Initial save bumps count await property_a.set(context, "there") self.assertEqual(mock_storage.write.call_count, 0) # Set on property should not bump await user_state.save_changes(context) self.assertEqual(mock_storage.write.call_count, 1) # Explicit save should bump value_a = await property_a.get(context) self.assertEqual("there", value_a) self.assertEqual(mock_storage.write.call_count, 1) # Gets should not bump await user_state.save_changes(context) self.assertEqual(mock_storage.write.call_count, 1) await property_a.delete(context) # Delete alone no bump self.assertEqual(mock_storage.write.call_count, 1) await user_state.save_changes(context) # Save when dirty should bump self.assertEqual(mock_storage.write.call_count, 2) self.assertEqual(mock_storage.read.call_count, 1) await user_state.save_changes(context ) # Save not dirty should not bump self.assertEqual(mock_storage.write.call_count, 2) self.assertEqual(mock_storage.read.call_count, 1)
def __init__(self, user_state: UserState): super(AddUtteranceDialog, self).__init__(AddUtteranceDialog.__name__) self.user_profile_accessor = user_state.create_property("DialogData") ### add_dialog --> 增加來回對話的round self.add_dialog( WaterfallDialog(WaterfallDialog.__name__, [ self.enter_a_training_utterance, self.enter_the_specified_intent, self.enter_the_specified_entity, self.enter_the_tagged_entity, self.inquire_keep_going_or_not, self.final_step ])) #依照本次dialog對話需要的方法,增加方法(yes/no問題、選項問題、純文字題等等) self.add_dialog(TextPrompt(TextPrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__))
def __init__(self, user_state: UserState): super(Dialog, self).__init__(Dialog.__name__) self.user_profile_accesor = user_state.create_property("UserProfile") self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.options_step, ], ) ) self.add_dialog(ChoicePrompt("options_step")) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) self.initial_dialog_id = WaterfallDialog.__name__ self.add_dialog(TextPrompt(TextPrompt.__name__))
async def test_state_set_after_save(self): """Verify setting property after save""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property-a") property_b = user_state.create_property("property-b") await user_state.load(context) await property_a.set(context, "hello") await property_b.set(context, "world") await user_state.save_changes(context) await property_a.set(context, "hello2")
async def test_LoadSetSave(self): # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property-a") property_b = user_state.create_property("property-b") await user_state.load(context) await property_a.set(context, "hello") await property_b.set(context, "world") await user_state.save_changes(context) # Assert obj = dictionary["EmptyContext/users/[email protected]"] self.assertEqual("hello", obj["property-a"]) self.assertEqual("world", obj["property-b"])
async def test_state_multiple_save(self): """Verify multiple saves""" # Arrange dictionary = {} user_state = UserState(MemoryStorage(dictionary)) context = TestUtilities.create_empty_context() # Act property_a = user_state.create_property("property-a") property_b = user_state.create_property("property-b") await user_state.load(context) await property_a.set(context, "hello") await property_b.set(context, "world") await user_state.save_changes(context) await property_a.set(context, "hello2") await user_state.save_changes(context) value_a = await property_a.get(context) self.assertEqual("hello2", value_a)
def __init__(self, user_state: UserState): super(OrderDialog, self).__init__(OrderDialog.__name__) self.current_order: Order = None self.order_list: List[Order] = list() self.user_profile_accesor = user_state.create_property("UserProfile") self.add_dialog( WaterfallDialog( WaterfallDialog.__name__, [ self.options_step, self.interpret_user_intention, self.goodbye_step, ], )) self.add_dialog(ChoicePrompt("options_step")) self.add_dialog(TextPrompt("interpret_user_intention")) self.add_dialog(ChoicePrompt(ChoicePrompt.__name__)) self.add_dialog(ConfirmPrompt(ConfirmPrompt.__name__)) self.initial_dialog_id = WaterfallDialog.__name__ self.add_dialog(TextPrompt(TextPrompt.__name__))
def __init__( self, user_state: UserState, connection_name: str, site_url: str, ): if user_state is None: raise Exception( "[TeamsMessagingExtensionsSearchAuthConfigBot]: Missing parameter. user_state is required" ) if connection_name is None: raise Exception( "[TeamsMessagingExtensionsSearchAuthConfigBot]: Missing parameter. connection_name is required" ) if site_url is None: raise Exception( "[TeamsMessagingExtensionsSearchAuthConfigBot]: Missing parameter. site_url is required" ) self.user_state = user_state self.connection_name = connection_name self.site_url = site_url self.user_config_property = user_state.create_property( "UserConfiguration")
def __init__(self, user_state: UserState): super(RootDialog, self).__init__(RootDialog.__name__) self.user_state_accessor = user_state.create_property("result") # Rather than explicitly coding a Waterfall we have only to declare what properties we want collected. # In this example we will want two text prompts to run, one for the first name and one for the last fullname_slots = [ SlotDetails(name="first", dialog_id="text", prompt="Please enter your first name."), SlotDetails(name="last", dialog_id="text", prompt="Please enter your last name."), ] # This defines an address dialog that collects street, city and zip properties. address_slots = [ SlotDetails( name="street", dialog_id="text", prompt="Please enter the street address.", ), SlotDetails(name="city", dialog_id="text", prompt="Please enter the city."), SlotDetails(name="zip", dialog_id="text", prompt="Please enter the zip."), ] # Dialogs can be nested and the slot filling dialog makes use of that. In this example some of the child # dialogs are slot filling dialogs themselves. slots = [ SlotDetails( name="fullname", dialog_id="fullname", ), SlotDetails(name="age", dialog_id="number", prompt="Please enter your age."), SlotDetails( name="shoesize", dialog_id="shoesize", prompt="Please enter your shoe size.", retry_prompt= "You must enter a size between 0 and 16. Half sizes are acceptable.", ), SlotDetails(name="address", dialog_id="address"), ] # Add the various dialogs that will be used to the DialogSet. self.add_dialog(SlotFillingDialog("address", address_slots)) self.add_dialog(SlotFillingDialog("fullname", fullname_slots)) self.add_dialog(TextPrompt("text")) self.add_dialog(NumberPrompt("number", default_locale=Culture.English)) self.add_dialog( NumberPrompt( "shoesize", RootDialog.shoe_size_validator, default_locale=Culture.English, )) self.add_dialog(SlotFillingDialog("slot-dialog", slots)) # Defines a simple two step Waterfall to test the slot dialog. self.add_dialog( WaterfallDialog("waterfall", [self.start_dialog, self.process_result])) # The initial child Dialog to run. self.initial_dialog_id = "waterfall"
TurnContext, UserState, MemoryStorage, ) from botbuilder.schema import Activity, ActivityTypes, ConversationReference from botbuilder.testing import DialogTestClient from unittest.mock import Mock, MagicMock import aiounittest from helpers import Messages MEMORY = MemoryStorage() USER_STATE = UserState(MEMORY) CONVERSATION_STATE = ConversationState(MEMORY) ACCESSOR = USER_STATE.create_property("RemindersState") DIALOG = RemindersDialog(USER_STATE, CONVERSATION_STATE, ACCESSOR) class TestRemindersDialog(aiounittest.AsyncTestCase): async def test_show_reminders_with_no_reminders(self): testClient = DialogTestClient("test", DIALOG) reply = await testClient.send_activity("show reminders") assert reply.text == "You don't have any reminders!" async def test_create_reminder(self): testClient = DialogTestClient("test", DIALOG) reply = await testClient.send_activity("remind me to go in 10 seconds") assert reply.text == "I have set the reminder!"
async def test_should_replicate_activity_data_to_listening_emulator_following_open_and_attach( self ): inbound_expectation, outbound_expectation, state_expectation = ( False, False, False, ) with requests_mock.Mocker() as mocker: # set up our expectations in nock - each corresponds to a trace message we expect to receive in the emulator def match_response(request): nonlocal inbound_expectation, outbound_expectation, state_expectation r_json = loads(request.text) if r_json.get("type", None) != "trace": return None if r_json.get("value", {}).get("text", None) == "hi": inbound_expectation = True return inbound_expectation if r_json.get("value", {}).get("text", None) == "echo: hi": outbound_expectation = True return outbound_expectation x_property = ( r_json.get("value", {}) .get("user_state", {}) .get("x", {}) .get("property", None) ) y_property = ( r_json.get("value", {}) .get("conversation_state", {}) .get("y", {}) .get("property", None) ) state_expectation = x_property == "hello" and y_property == "world" return state_expectation mocker.post( "https://test.com/v3/conversations/Convo1/activities", additional_matcher=match_response, json={"id": "test"}, status_code=200, ) # create the various storage and middleware objects we will be using storage = MemoryStorage() inspection_state = InspectionState(storage) user_state = UserState(storage) conversation_state = ConversationState(storage) inspection_middleware = InspectionMiddleware( inspection_state, user_state, conversation_state ) # the emulator sends an /INSPECT open command - we can use another adapter here open_activity = MessageFactory.text("/INSPECT open") async def exec_test(turn_context): await inspection_middleware.process_command(turn_context) inspection_adapter = TestAdapter(exec_test, None, True) await inspection_adapter.receive_activity(open_activity) inspection_open_result_activity = inspection_adapter.activity_buffer[0] attach_command = inspection_open_result_activity.value # the logic of teh bot including replying with a message and updating user and conversation state x_prop = user_state.create_property("x") y_prop = conversation_state.create_property("y") async def exec_test2(turn_context): await turn_context.send_activity( MessageFactory.text(f"echo: { turn_context.activity.text }") ) (await x_prop.get(turn_context, {"property": ""}))["property"] = "hello" (await y_prop.get(turn_context, {"property": ""}))["property"] = "world" await user_state.save_changes(turn_context) await conversation_state.save_changes(turn_context) application_adapter = TestAdapter(exec_test2, None, True) # IMPORTANT add the InspectionMiddleware to the adapter that is running our bot application_adapter.use(inspection_middleware) await application_adapter.receive_activity( MessageFactory.text(attach_command) ) # the attach command response is a informational message await application_adapter.receive_activity(MessageFactory.text("hi")) # trace activities should be sent to the emulator using the connector and the conversation reference # verify that all our expectations have been met assert inbound_expectation assert outbound_expectation assert state_expectation assert mocker.call_count, 3
def __init__(self, translator: MicrosoftTranslator, user_state: UserState): self.translator = translator self.language_preference_accessor = user_state.create_property( "LanguagePreference")