コード例 #1
0
 async def test_should_work_as_a_middleware_plugin(self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     autosave_middleware = AutoSaveStateMiddleware().add(foo_state)
     await autosave_middleware.on_turn(context, aux_func)
     assert foo_state.write_called, "save_all_changes() not called."
コード例 #2
0
 async def test_should_add_and_call_load_all_on_multiple_plugins(self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     bar_state = BotStateMock({"bar": "foo"})
     bot_state_set = AutoSaveStateMiddleware([foo_state, bar_state])
     await bot_state_set.bot_state_set.load_all(context)
コード例 #3
0
 async def test_should_pass_force_flag_through_in_load_all_call(self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     foo_state.assert_force = True
     autosave_middleware = AutoSaveStateMiddleware().add(foo_state)
     await autosave_middleware.bot_state_set.load_all(context, True)
コード例 #4
0
    def use_state(
        adapter: BotAdapter,
        user_state: UserState,
        conversation_state: ConversationState,
        auto: bool = True,
    ) -> BotAdapter:
        """
        Registers user and conversation state objects with the adapter. These objects will be available via
        the turn context's `turn_state` property.

        :param adapter: The BotAdapter on which to register the state objects.
        :param user_state: The UserState object to register.
        :param conversation_state: The ConversationState object to register.
        :param auto: True to automatically persist state each turn.
        :return: The BotAdapter
        """
        if not adapter:
            raise TypeError("BotAdapter is required")

        if not user_state:
            raise TypeError("UserState is required")

        if not conversation_state:
            raise TypeError("ConversationState is required")

        adapter.use(RegisterClassMiddleware(user_state))
        adapter.use(RegisterClassMiddleware(conversation_state))

        if auto:
            adapter.use(AutoSaveStateMiddleware([user_state, conversation_state]))

        return adapter
コード例 #5
0
 async def test_should_add_and_call_save_all_changes_on_a_single_plugin(
         self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     bot_state_set = AutoSaveStateMiddleware().add(foo_state)
     await bot_state_set.bot_state_set.save_all_changes(context)
     assert foo_state.write_called, "write not called for plugin."
コード例 #6
0
 async def test_should_add_and_call_save_all_changes_on_multiple_plugins(
         self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     bar_state = BotStateMock({"bar": "foo"})
     autosave_middleware = AutoSaveStateMiddleware([foo_state, bar_state])
     await autosave_middleware.bot_state_set.save_all_changes(context)
     assert (foo_state.write_called or
             bar_state.write_called), "write not called for either plugin."
     assert foo_state.write_called, "write not called for 'foo_state' plugin."
     assert bar_state.write_called, "write not called for 'bar_state' plugin."
コード例 #7
0
    def __init__(
        self,
        channel_or_adapter: Union[str, TestAdapter],
        target_dialog: Dialog,
        initial_dialog_options: object = None,
        middlewares: List[Middleware] = None,
        conversation_state: ConversationState = None,
    ):
        """
        Create a DialogTestClient to test a dialog without having to create a full-fledged adapter.

        ```python
        client = DialogTestClient("test", MY_DIALOG, MY_OPTIONS)
        reply = await client.send_activity("first message")
        self.assertEqual(reply.text, "first reply", "reply failed")
        ```

        :param channel_or_adapter: The channel Id or test adapter to be used for the test.
        For channel Id, use 'emulator' or 'test' if you are uncertain of the channel you are targeting.
        Otherwise, it is recommended that you use the id for the channel(s) your bot will be using and
        write a test case for each channel.
        Or, a test adapter instance can be used.
        :type channel_or_adapter: Union[str, TestAdapter]
        :param target_dialog: The dialog to be tested. This will be the root dialog for the test client.
        :type target_dialog: Dialog
        :param initial_dialog_options: (Optional) additional argument(s) to pass to the dialog being started.
        :type initial_dialog_options: object
        :param middlewares: (Optional) The test adapter to use. If this parameter is not provided, the test client will
        use a default TestAdapter.
        :type middlewares: List[Middleware]
        :param conversation_state: (Optional) A ConversationState instance to use in the test client.
        :type conversation_state: ConversationState
        """
        self.dialog_turn_result: DialogTurnResult = None
        self.conversation_state: ConversationState = (ConversationState(
            MemoryStorage()) if conversation_state is None else
                                                      conversation_state)
        dialog_state = self.conversation_state.create_property("DialogState")
        self._callback = self._get_default_callback(target_dialog,
                                                    initial_dialog_options,
                                                    dialog_state)

        if isinstance(channel_or_adapter, str):
            conversation_reference = ConversationReference(
                channel_id=channel_or_adapter)
            self.test_adapter = TestAdapter(self._callback,
                                            conversation_reference)
            self.test_adapter.use(AutoSaveStateMiddleware().add(
                self.conversation_state))
        else:
            self.test_adapter = channel_or_adapter

        self._add_user_middlewares(middlewares)
コード例 #8
0
    def use_bot_state(bot_adapter: BotAdapter,
                      *bot_states: BotState,
                      auto: bool = True) -> BotAdapter:
        """
        Registers bot state object into the TurnContext. The botstate will be available via the turn context.

        :param bot_adapter: The BotAdapter on which to register the state objects.
        :param bot_states: One or more BotState objects to register.
        :return: The updated adapter.
        """
        if not bot_states:
            raise TypeError("At least one BotAdapter is required")

        for bot_state in bot_states:
            bot_adapter.use(
                RegisterClassMiddleware(bot_state,
                                        AdapterExtensions.fullname(bot_state)))

        if auto:
            bot_adapter.use(AutoSaveStateMiddleware(bot_states))

        return bot_adapter
コード例 #9
0
    def use_state(
        adapter: BotAdapter,
        user_state: UserState,
        conversation_state: ConversationState,
        auto: bool = True,
    ) -> BotAdapter:
        """
        [DEPRECATED] Registers user and conversation state objects with the adapter. These objects will be available via
        the turn context's `turn_state` property.

        :param adapter: The BotAdapter on which to register the state objects.
        :param user_state: The UserState object to register.
        :param conversation_state: The ConversationState object to register.
        :param auto: True to automatically persist state each turn.
        :return: The BotAdapter
        """
        warn(
            "This method is deprecated in 4.9. You should use the method .use_bot_state() instead.",
            DeprecationWarning,
        )

        if not adapter:
            raise TypeError("BotAdapter is required")

        if not user_state:
            raise TypeError("UserState is required")

        if not conversation_state:
            raise TypeError("ConversationState is required")

        adapter.use(RegisterClassMiddleware(user_state))
        adapter.use(RegisterClassMiddleware(conversation_state))

        if auto:
            adapter.use(
                AutoSaveStateMiddleware([user_state, conversation_state]))

        return adapter
コード例 #10
0
 async def test_should_add_and_call_load_all_on_single_plugin(self):
     adapter = TestAdapter()
     context = TurnContext(adapter, Activity())
     foo_state = BotStateMock({"foo": "bar"})
     bot_state_set = AutoSaveStateMiddleware().add(foo_state)
     await bot_state_set.bot_state_set.load_all(context)
コード例 #11
0
 async def test_should_not_add_any_bot_state_on_construction_if_none_are_passed_in(
         self):
     middleware = AutoSaveStateMiddleware()
     assert (not middleware.bot_state_set.bot_states
             ), "should not have added any BotState."
コード例 #12
0
    async def create_test_flow(
        dialog: Dialog,
        test_case: SkillFlowTestCase = SkillFlowTestCase.root_bot_only,
        enabled_trace=False,
    ) -> TestAdapter:
        conversation_id = "testFlowConversationId"
        storage = MemoryStorage()
        conversation_state = ConversationState(storage)
        user_state = UserState(storage)

        activity = Activity(
            channel_id="test",
            service_url="https://test.com",
            from_property=ChannelAccount(id="user1", name="User1"),
            recipient=ChannelAccount(id="bot", name="Bot"),
            conversation=ConversationAccount(is_group=False,
                                             conversation_type=conversation_id,
                                             id=conversation_id),
        )

        dialog_manager = DialogManager(dialog)
        dialog_manager.user_state = user_state
        dialog_manager.conversation_state = conversation_state

        async def logic(context: TurnContext):
            if test_case != SkillFlowTestCase.root_bot_only:
                # Create a skill ClaimsIdentity and put it in turn_state so isSkillClaim() returns True.
                claims_identity = ClaimsIdentity({}, False)
                claims_identity.claims[
                    "ver"] = "2.0"  # AuthenticationConstants.VersionClaim
                claims_identity.claims["aud"] = (
                    SimpleComponentDialog.skill_bot_id
                )  # AuthenticationConstants.AudienceClaim
                claims_identity.claims["azp"] = (
                    SimpleComponentDialog.parent_bot_id
                )  # AuthenticationConstants.AuthorizedParty
                context.turn_state[
                    BotAdapter.BOT_IDENTITY_KEY] = claims_identity

                if test_case == SkillFlowTestCase.root_bot_consuming_skill:
                    # Simulate the SkillConversationReference with a channel OAuthScope stored in turn_state.
                    # This emulates a response coming to a root bot through SkillHandler.
                    context.turn_state[
                        SkillHandler.
                        SKILL_CONVERSATION_REFERENCE_KEY] = SkillConversationReference(
                            None, AuthenticationConstants.
                            TO_CHANNEL_FROM_BOT_OAUTH_SCOPE)

                if test_case == SkillFlowTestCase.middle_skill:
                    # Simulate the SkillConversationReference with a parent Bot ID stored in turn_state.
                    # This emulates a response coming to a skill from another skill through SkillHandler.
                    context.turn_state[
                        SkillHandler.
                        SKILL_CONVERSATION_REFERENCE_KEY] = SkillConversationReference(
                            None, SimpleComponentDialog.parent_bot_id)

            async def aux(
                turn_context: TurnContext,  # pylint: disable=unused-argument
                activities: List[Activity],
                next: Callable,
            ):
                for activity in activities:
                    if activity.type == ActivityTypes.end_of_conversation:
                        SimpleComponentDialog.eoc_sent = activity
                        break

                return await next()

            # Interceptor to capture the EoC activity if it was sent so we can assert it in the tests.
            context.on_send_activities(aux)

            SimpleComponentDialog.dm_turn_result = await dialog_manager.on_turn(
                context)

        adapter = TestAdapter(logic, activity, enabled_trace)
        adapter.use(AutoSaveStateMiddleware([user_state, conversation_state]))

        return adapter