def test_event_to_dict(self):
        expected = {
            'scenario': 'name',
            'scenario_version': 'version',
            'node': 'node',
            'results': 'true',
            'type': 'type',
            'content': {
                'foo': 'bar'
            },
            'created_time': time()
        }
        event = Event(**expected)

        self.assertDictEqual(event.to_dict(), expected)
Example #2
0
 def _extract(self, form, text_normalization_result, user, params):
     result = {}
     for field_key, field_descr in form.description.fields.items():
         field = form.fields[field_key]
         if field.available:
             check = field_descr.requirement.check(
                 text_normalization_result, user, params)
             log_params = self._log_params()
             log_params[
                 "requirement"] = field_descr.requirement.__class__.__name__,
             log_params["requirement_check_result"] = check
             log_params["field_key"] = str(field_key)
             message = "FormFillingScenario.extract: field %(field_key)s requirement %(requirement)s return value: %(requirement_check_result)s"
             log(message, user, log_params)
             if check:
                 result[field_key] = field_descr.filler.run(
                     user, text_normalization_result, params)
                 event = Event(
                     type=HistoryConstants.types.FIELD_EVENT,
                     scenario=self.root_id,
                     content={
                         HistoryConstants.content_fields.FIELD: field_key
                     },
                     results=HistoryConstants.event_results.FILLED)
                 user.history.add_event(event)
     return result
    def test_history_add_event(self):
        descriptions = PicklableMock()
        item = {'type': 'event_type', 'content': {'foo': 'bar'}}
        history = History({}, descriptions, None)
        expected = Event(**item)

        history.add_event(expected)

        self.assertEqual(len(history.get_raw_events()), 1)
        self.assertEqual(history.get_raw_events()[0], expected)
    def test_history_event_formatter(self):
        events = [
            Event(type='field_event',
                  scenario='name',
                  node='node',
                  results='filled',
                  content={'field': 'foo'}),
            Event(type='field_event',
                  scenario='name',
                  node='node',
                  results='filled',
                  content={'field': 'bar'}),
        ]
        expected = [{
            'no': 1,
            'scenarioName': 'name',
            'scenarioVersion': None,
            'results': 'filled',
            'eventType': 'field_event',
            'eventContent': {
                'field': 'foo'
            }
        }, {
            'no': 2,
            'scenarioName': 'name',
            'scenarioVersion': None,
            'results': 'filled',
            'eventType': 'field_event',
            'eventContent': {
                'field': 'bar'
            }
        }]

        formatter = HistoryEventFormatter()

        self.assertListEqual(formatter.format(events), expected)
Example #5
0
    def ask_again(self, text_preprocessing_result, user, params):
        form = user.forms[self.form_type]
        question_field = self._field(form, text_preprocessing_result, user,
                                     params)
        question = question_field.description.ask_again_requests[
            question_field.ask_again_counter]
        question_field.ask_again_counter += 1

        user.history.add_event(
            Event(type=HistoryConstants.types.FIELD_EVENT,
                  scenario=self.root_id,
                  content={
                      HistoryConstants.content_fields.FIELD:
                      question_field.description.id
                  },
                  results=HistoryConstants.event_results.ASK_QUESTION))

        return question.run(user, text_preprocessing_result, params)
Example #6
0
    def run(self,
            text_preprocessing_result,
            user,
            params: Dict[str, Any] = None):
        form = self._get_form(user)
        user.last_scenarios.add(self.id, text_preprocessing_result)
        user.preprocessing_messages_for_scenarios.add(
            text_preprocessing_result)

        data_extracted = self._extract_data(form, text_preprocessing_result,
                                            user, params)
        logging_params = {"data_extracted_str": str(data_extracted)}
        logging_params.update(self._log_params())
        log("Extracted data=%(data_extracted_str)s", user, logging_params)

        validation_error_msg = self._validate_extracted_data(
            user, text_preprocessing_result, form, data_extracted, params)
        if validation_error_msg:
            reply_messages = validation_error_msg
        else:
            reply_messages, is_break = self._fill_form(
                user, text_preprocessing_result, form, data_extracted)
            if not is_break:
                field = self._field(form, text_preprocessing_result, user,
                                    params)
                if field:
                    user.history.add_event(
                        Event(type=HistoryConstants.types.FIELD_EVENT,
                              scenario=self.root_id,
                              content={
                                  HistoryConstants.content_fields.FIELD:
                                  field.description.id
                              },
                              results=HistoryConstants.event_results.
                              ASK_QUESTION))
                reply = self.get_reply(user, text_preprocessing_result,
                                       self.actions, field, form)
                reply_messages.extend(reply)

        if not reply_messages:
            reply_messages = self.get_no_commands_action(
                user, text_preprocessing_result)

        return reply_messages
    def test_event(self):
        item = {
            'scenario': 'name',
            'scenario_version': 'version',
            'node': 'node',
            'results': 'true',
            'type': 'type',
            'content': {
                'foo': 'bar'
            }
        }
        event = Event(**item)

        self.assertEqual(event.scenario, item['scenario'])
        self.assertEqual(event.scenario_version, item['scenario_version'])
        self.assertEqual(event.node, item['node'])
        self.assertEqual(event.results, item['results'])
        self.assertEqual(event.type, item['type'])
        self.assertDictEqual(event.content, item['content'])
Example #8
0
    def run(self,
            text_preprocessing_result,
            user,
            params: Dict[str, Any] = None):
        form = self._get_form(user)
        user.last_scenarios.add(self.id, text_preprocessing_result)
        user.preprocessing_messages_for_scenarios.add(
            text_preprocessing_result)
        data_extracted = self._extract(form, text_preprocessing_result, user,
                                       params)
        log("Extracted data={}".format(data_extracted), user,
            self._log_params())
        validation_error_msg = self._get_validation_error_msg(
            user, text_preprocessing_result, form, data_extracted, params)
        if validation_error_msg:
            # got validation msg, ask question
            reply_messages = validation_error_msg
        else:
            reply_messages, is_break = self._fill_form(
                user, text_preprocessing_result, form, data_extracted)
            if not is_break:
                question_field = self._question_field(
                    form, text_preprocessing_result, user, params)
                if question_field:
                    user.history.add_event(
                        Event(type=HistoryConstants.types.FIELD_EVENT,
                              scenario=self.root_id,
                              content={
                                  HistoryConstants.content_fields.FIELD:
                                  question_field.description.id
                              },
                              results=HistoryConstants.event_results.
                              ASK_QUESTION))
                reply = self.get_reply(user, text_preprocessing_result,
                                       self.actions, question_field, form)
                reply_messages.extend(reply)

        if not reply_messages:
            reply_messages = self.get_no_commands_action(
                user, text_preprocessing_result)

        return reply_messages
Example #9
0
    def run(self, user: User, text_preprocessing_result: BaseTextPreprocessingResult,
            params: Optional[Dict[str, Union[str, float, int]]] = None) -> None:
        last_scenario_id = user.last_scenarios.last_scenario_name
        scenario = user.descriptions["scenarios"].get(last_scenario_id)
        if scenario:

            params = user.parametrizer.collect(text_preprocessing_result)

            if self.event_content:
                for key, template in self.event_content.items():
                    self.event_content[key] = template.render(params)
            self.event_type = self.event_type.render(params)
            self.results = self.results.render(params)

            event = Event(
                type=self.event_type,
                scenario=scenario.id,
                scenario_version=scenario.version,
                results=self.results,
                content=self.event_content
            )
            user.history.add_event(event)
Example #10
0
    def test_action_with_jinja(self):
        scenario = Mock()
        scenario.id = 'name'
        scenario.version = '1.0'
        self.user.descriptions = {'scenarios': {'test_scenario': scenario}}
        items = {
            'event_type': 'type',
            'event_content': {
                'field_1': '{{ main_form.field_1 }}'
            },
            'results': '{{ message.name }}'
        }
        expected = Event(type='type',
                         results='CLIENT_INFO_RESPONSE',
                         content={'field_1': 'value_1'},
                         scenario='name',
                         scenario_version='1.0')

        action = AddHistoryEventAction(items)
        action.run(self.user, None, None)

        self.user.history.add_event.assert_called_once()
        self.user.history.add_event.assert_called_once_with(expected)
Example #11
0
    def test_action_with_non_empty_scenario(self):
        scenario = Mock()
        scenario.id = 'name'
        scenario.version = '1.0'
        self.user.descriptions = {'scenarios': {'test_scenario': scenario}}
        items = {
            'event_type': 'type',
            'event_content': {
                'foo': 'bar'
            },
            'results': 'result'
        }
        expected = Event(type='type',
                         results='result',
                         content={'foo': 'bar'},
                         scenario='name',
                         scenario_version='1.0')

        action = AddHistoryEventAction(items)
        action.run(self.user, None, None)

        self.user.history.add_event.assert_called_once()
        self.user.history.add_event.assert_called_once_with(expected)
    def run(self,
            text_preprocessing_result,
            user,
            params: Dict[str, Any] = None):
        main_form = self._get_form(user)
        user.last_scenarios.add(self.id, text_preprocessing_result)
        user.preprocessing_messages_for_scenarios.add(
            text_preprocessing_result)
        current_node = self.get_current_node(user)
        new_node = current_node
        self._add_loop_count(user, new_node.id)
        internal_form, question_form = None, None
        fill_other = True
        on_filled_actions = []

        while new_node:
            current_node = new_node
            log(
                "message id: {}, current scenario: {}, current node: {}".
                format(user.message.incremental_id, self.id,
                       current_node.id), user, self._log_params())
            internal_form = self._get_internal_form(main_form.forms,
                                                    current_node.form_key)
            data_extracted = {}

            validation_error_msg = None
            for field_key, field_descr in internal_form.description.fields.items(
            ):
                field = internal_form.fields[field_key]
                if field.available:
                    extracted = field_descr.filler.run(
                        user, text_preprocessing_result, params)
                    if extracted is not None:
                        event = Event(
                            type=HistoryConstants.types.FIELD_EVENT,
                            scenario=self.root_id,
                            node=current_node.id,
                            content={
                                HistoryConstants.content_fields.FIELD:
                                field_key
                            },
                            results=HistoryConstants.event_results.FILLED)
                        user.history.add_event(event)
                        log_params = self._log_params()
                        log_params["message_id"] = user.message.incremental_id
                        log_params["field_key"] = field_key
                        log_params["extracted"] = extracted
                        log(
                            "message id: %(message_id)s, extracted data for field %(field_key)s: "
                            "%(extracted)s", user, log_params)
                    if extracted is not None and fill_other:
                        fill_other = fill_other and field_descr.fill_other
                        field_data = {field_key: extracted}
                        _validation_error_msg = self._get_validation_error_msg(
                            user, text_preprocessing_result, internal_form,
                            field_data, params)
                        if _validation_error_msg:
                            # return only first validation message in form
                            validation_error_msg = validation_error_msg or _validation_error_msg
                        else:
                            data_extracted.update(field_data)
            on_filled_node_actions, is_break = self._fill_form(
                user, text_preprocessing_result, internal_form, data_extracted)
            if is_break:
                return on_filled_node_actions
            on_filled_actions.extend(on_filled_node_actions)

            if validation_error_msg is not None:
                return validation_error_msg

            if internal_form.is_valid():
                if not current_node.available_nodes and not question_form:
                    # end node found
                    main_form.set_valid()
                    self._remove_current_node_id(user)
                    event = Event(
                        type=HistoryConstants.types.END_SCENARIO,
                        scenario=self.root_id,
                        node=current_node.id,
                        results=HistoryConstants.event_results.SUCCESS)
                    user.history.add_event(event)
                    break

            elif not question_form:
                question_form = internal_form
                self._set_current_node_id(user, current_node.id)
            new_node = self.get_next_node(user, current_node,
                                          text_preprocessing_result, params)

        question_field = self._find_question_field(
            question_form, text_preprocessing_result, user,
            params) if question_form else None
        reply_commands = on_filled_actions
        if question_field:
            event = Event(type=HistoryConstants.types.FIELD_EVENT,
                          scenario=self.root_id,
                          node=current_node.id,
                          content={
                              HistoryConstants.content_fields.FIELD:
                              question_field.description.id
                          },
                          results=HistoryConstants.event_results.ASK_QUESTION)
            user.history.add_event(event)
        _command = self.get_reply(user, text_preprocessing_result,
                                  current_node.actions, question_field,
                                  main_form)
        reply_commands.extend(_command)

        if not reply_commands:
            reply_commands = self.get_no_commands_action(
                user, text_preprocessing_result)

        return reply_commands