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)
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)
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)
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'])
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
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)
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)
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