Ejemplo n.º 1
0
 def test_response_serialization(self):
     response = TextMessage(text="Hello, world!")
     model = ChatMessage()
     model.response_dict = response
     assert isinstance(model.response, MessageElement)
     assert isinstance(model.serialized_response, dict)
     assert model.serialized_response[
         '__type__'] == response.__module__ + "." + response.__class__.__name__
Ejemplo n.º 2
0
    def make_default_action(action_dict):
        """
        Creates an action from a non-function definition.
        :param action_dict:
        :return: The created action, a function pointer.
        """
        from botshot.core.responses import TextMessage
        next = action_dict.get("next")
        message = None
        if 'type' in action_dict:
            type = action_dict['type'].lower()
            if type == 'qa':
                if 'context' not in action_dict:
                    raise ValueError("QA context not set")
                # TODO
            elif type == 'free_input': pass
            elif type == 'seq2seq': pass
            message = TextMessage("TO DO")
        elif 'text' in action_dict:
            message = TextMessage(action_dict['text'])
            if 'replies' in action_dict:
                message.with_replies(action_dict['replies'])
        elif 'image_url' in action_dict:
            message = AttachmentMessage('image', action_dict['image_url'])

        if not message:
            raise ValueError("Unknown action: {}".format(action_dict))
        return dynamic_response_fn(message, next)
Ejemplo n.º 3
0
 def test_serialize_deserialize_message(self):
     from botshot.core.responses import TextMessage
     from botshot.core.responses import LinkButton
     obj = TextMessage(text="foo",
                       buttons=[
                           LinkButton(title="foo",
                                      url="http://example.com",
                                      webview=True)
                       ])
     obj.__hidden__ = 'bar'
     data = json_serialize(obj)
     assert data and data[
         '__type__'] == obj.__class__.__module__ + "." + obj.__class__.__name__
     assert data['text'] == 'foo' and data['buttons'][0]['title'] == 'foo'
     obj = json_deserialize(data)
     assert obj and isinstance(obj, TextMessage)
     assert obj.buttons[0] and isinstance(obj.buttons[0], LinkButton)
     assert obj.text == "foo" and obj.buttons[0].url == "http://example.com"
     assert not hasattr(obj, '__hidden__')
Ejemplo n.º 4
0
 def process_responses(responses):
     if responses is None:
         return []
     if not isinstance(responses, (list, tuple)):
         responses = [responses]
     for i in range(0, len(responses)):
         if isinstance(responses[i], str):
             responses[i] = TextMessage(text=responses[i])
         elif not isinstance(responses[i], MessageElement):
             raise ValueError("Invalid message element of type %s" % type(responses[i]))
     return responses
Ejemplo n.º 5
0
    def test_send_messages(self):
        message, context, logger = mock.Mock(), mock.Mock(), mock.Mock()
        chat_mgr = ChatManager()
        dialog = Dialog(message, context, chat_mgr, logger)

        chat_mgr.send = mock.Mock()
        dialog.send("Hello world")
        assert chat_mgr.send.called

        chat_mgr.send = mock.Mock()
        dialog.send(TextMessage("Hi"))
        assert chat_mgr.send.called

        with pytest.raises(ValueError):
            dialog.send(105)

        with pytest.raises(ValueError):
            dialog.send([None, None])
Ejemplo n.º 6
0
    def _move_to(self, new_state_name, save_identical=False):
        """Moves to a state by its full name."""
        logging.info("Trying to move to {}".format(new_state_name))

        # if flow prefix is not present, add the current one
        if isinstance(new_state_name, int):
            new_state = self.context.get_history_state(new_state_name - 1)
            new_state_name = new_state['name'] if new_state else None
        if not new_state_name:
            new_state_name = self.current_state_name

        if new_state_name.count(':'):
            new_state_name, action = new_state_name.split(':', 1)
            action = True
        else:
            action = False

        if '.' not in new_state_name:
            new_state_name = self.current_state_name.split(
                '.')[0] + '.' + new_state_name
        if not self.get_state(new_state_name):
            logging.warning('Error: State %s does not exist! Staying at %s.' %
                            (new_state_name, self.current_state_name))
            return False
        identical = new_state_name == self.current_state_name
        if not identical or save_identical:
            self.context.add_state(new_state_name)
        if not new_state_name:
            return False
        previous_state = self.current_state_name
        self.current_state_name = new_state_name
        self.logging_service.log_state_change(self.message,
                                              state=self.current_state_name)

        try:
            if previous_state != new_state_name and action:
                logging.info(
                    "Moving from {} to {} and executing action".format(
                        previous_state, new_state_name))
                self._run_accept()
            elif action:
                logging.info("Staying in state {} and executing action".format(
                    previous_state))
                self._run_accept()
            elif previous_state != new_state_name:
                logging.info("Moving from {} to {} and doing nothing".format(
                    previous_state, new_state_name))
            else:
                logging.info("Staying in state {} and doing nothing".format(
                    previous_state))

        except Exception as e:
            import traceback
            self.context.debug(level=logging.INFO)
            logging.error(
                '*****************************************************\n'
                'Exception occurred in state {}\n'
                'Message: {}\n'
                'User: {}\n'
                'Conversation: {}\n'
                '*****************************************************'.format(
                    new_state_name, self.message.__dict__,
                    self.message.user.__dict__,
                    self.message.conversation.__dict__))

            self.logging_service.log_error(self.message,
                                           self.current_state_name, e)

            traceback_str = traceback.format_exc()

            if self.send_exceptions:
                self.dialog.send([
                    TextMessage('Debug: ' + str(e)),
                    TextMessage('Debug: ' + traceback_str)
                ])

            # Raise the exception again, conversation state won't be saved.
            raise e

        return True
Ejemplo n.º 7
0
 def intercept(self, dialog: Dialog) -> bool:
     if dialog.message.text == '/admin':
         #if not dialog.message.user.is_admin:
         #    dialog.send('You are not admin.')
         #    return False
         response = TextMessage('Admin actions')
         if dialog.context.get(ConversationTestRecorder.ENTITY_KEY):
             response.add_button(
                 PayloadButton(
                     'Stop recording',
                     payload={ConversationTestRecorder.ENTITY_KEY: False}))
         else:
             response.add_button(
                 PayloadButton(
                     'Start recording',
                     payload={ConversationTestRecorder.ENTITY_KEY: True}))
         dialog.send(response)
         return True
     test_recording = dialog.context.get_value(
         ConversationTestRecorder.ENTITY_KEY, max_age=0)
     if test_recording:
         response = TextMessage('Test conversation recording started.')
         response.add_button(
             PayloadButton(
                 'Stop recording',
                 payload={ConversationTestRecorder.ENTITY_KEY: False}))
         dialog.send(response)
         ConversationTestRecorder.restart()
         return True
     elif test_recording == False:
         response = TextMessage(
             'Test conversation recording done. View Botshot Recording tab.'
         )
         response.add_button(
             PayloadButton(
                 'Start again',
                 payload={ConversationTestRecorder.ENTITY_KEY: True}))
         dialog.send(response)
         return True
     return False
Ejemplo n.º 8
0
 def test_send(self, chat_mgr, conversation):
     responses = [TextMessage("Hello world!")]
     chat_mgr.send(conversation, responses, None)