Skip to content

DPNLPF-1571: smart_geo action, handler #218

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/names/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
SYSTEM_NAME = "systemName"
USER_CHANNEL = "userChannel"
USER_ID = "userId"
MESSAGE = "message"

DEBUG_INFO = "debug_info"
DEBUG_INFO_APP_KEY = "debug_info_key"
Expand Down
14 changes: 14 additions & 0 deletions smart_kit/action/smart_geo_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import Dict, Any, Optional, Union, List

from core.basic_models.actions.command import Command
from core.basic_models.actions.string_actions import StringAction
from core.model.base_user import BaseUser
from core.text_preprocessing.base import BaseTextPreprocessingResult
from smart_kit.names.message_names import GET_PROFILE_DATA


class SmartGeoAction(StringAction):
def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult,
params: Optional[Dict[str, Union[str, float, int]]] = None) -> List[Command]:
commands = [Command(GET_PROFILE_DATA)]
return commands
22 changes: 22 additions & 0 deletions smart_kit/handlers/handler_take_profile_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from core.logging.logger_utils import log
from core.names.field import MESSAGE
from core.text_preprocessing.preprocessing_result import TextPreprocessingResult
from scenarios.user.user_model import User

from smart_kit.handlers.handler_base import HandlerBase
from smart_kit.names.field import PROFILE_DATA, STATUS_CODE, CODE, GEO


class HandlerTakeProfileData(HandlerBase):
SUCCESS_CODE = 1

def run(self, payload, user: User):
super().run(payload, user)
log(f"{self.__class__.__name__} started", user)

text_preprocessing_result = TextPreprocessingResult(payload.get(MESSAGE, {}))
action = user.descriptions["external_actions"]["smart_geo_fail"]
if payload.get(STATUS_CODE, {}).get(CODE) == self.SUCCESS_CODE:
action = user.descriptions["external_actions"]["smart_geo_success"]
user.variables.set("smart_geo", payload.get(PROFILE_DATA, {}).get(GEO))
return action.run(user, text_preprocessing_result)
7 changes: 5 additions & 2 deletions smart_kit/models/smartapp_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

import scenarios.logging.logger_constants as log_const
from smart_kit.handlers.handle_close_app import HandlerCloseApp
from smart_kit.names.message_names import MESSAGE_TO_SKILL, LOCAL_TIMEOUT, RUN_APP, SERVER_ACTION, CLOSE_APP
from smart_kit.handlers.handler_take_profile_data import HandlerTakeProfileData
from smart_kit.names.message_names import MESSAGE_TO_SKILL, LOCAL_TIMEOUT, RUN_APP, SERVER_ACTION, CLOSE_APP, \
TAKE_PROFILE_DATA
from smart_kit.handlers.handle_respond import HandlerRespond
from smart_kit.handlers.handler_text import HandlerText
from smart_kit.handlers.handler_timeout import HandlerTimeout
Expand Down Expand Up @@ -39,7 +41,8 @@ def __init__(self, resources: SmartAppResources, dialogue_manager_cls, custom_se
RUN_APP: handler_text,
LOCAL_TIMEOUT: HandlerTimeout(self.app_name),
SERVER_ACTION: HandlerServerAction(self.app_name),
CLOSE_APP: HandlerCloseApp(self.app_name)
CLOSE_APP: HandlerCloseApp(self.app_name),
TAKE_PROFILE_DATA: HandlerTakeProfileData(self.app_name)
}
self._handlers.update({
message_name: HandlerRespond(self.app_name, action_name=action_name)
Expand Down
4 changes: 4 additions & 0 deletions smart_kit/names/field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PROFILE_DATA = "profile_data"
STATUS_CODE = "status_code"
CODE = "code"
GEO = "geo"
2 changes: 2 additions & 0 deletions smart_kit/names/message_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
RUN_APP = "RUN_APP"
CLOSE_APP = "CLOSE_APP"
SERVER_ACTION = "SERVER_ACTION"
GET_PROFILE_DATA = "GET_PROFILE_DATA"
TAKE_PROFILE_DATA = "TAKE_PROFILE_DATA"
2 changes: 2 additions & 0 deletions smart_kit/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
from scenarios.user.preprocessing_messages.preprocessing_messages_description import \
PreprocessingMessagesDescription
from smart_kit.action.http import HTTPRequestAction
from smart_kit.action.smart_geo_action import SmartGeoAction
from smart_kit.message.get_to_message import to_messages
from smart_kit.message.smart_app_push_message import SmartAppPushToMessage
from smart_kit.request.kafka_request import SmartKitKafkaRequest
Expand Down Expand Up @@ -315,6 +316,7 @@ def init_actions(self):
actions["push"] = PushAction
actions["give_me_memory"] = GiveMeMemoryAction
actions["remember_this"] = RememberThisAction
actions["smart_geo"] = SmartGeoAction

def init_requirements(self):
requirements[None] = Requirement
Expand Down
28 changes: 28 additions & 0 deletions smart_kit/template/static/references/actions/actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,33 @@
"type": "template",
"template": "{{ payload.new_session and settings['template_settings'].get('reset_context_on_new_session', False)}}"
}
},
"smart_geo_success": {
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Геоданные пользователя",
"items": [
{
"bubble": {
"text": "Геоданные пользователя: {{ user.variables.smart_geo }}"
}
}
]
}
},
"smart_geo_fail": {
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Ошибка при получении геоданных пользователя",
"items": [
{
"bubble": {
"text": "Ошибка при получении геоданных пользователя"
}
}
]
}
}
}
37 changes: 36 additions & 1 deletion tests/scenarios_tests/actions_test/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from scenarios.actions.action import ClearFormAction, ClearInnerFormAction, BreakScenarioAction, AskAgainAction, \
RemoveFormFieldAction, RemoveCompositeFormFieldAction
from scenarios.scenario_models.history import Event
from smart_kit.action.smart_geo_action import SmartGeoAction
from smart_kit.message.smartapp_to_message import SmartAppToMessage
from smart_kit.utils.picklable_mock import PicklableMock, PicklableMagicMock


Expand Down Expand Up @@ -238,7 +240,8 @@ def test_action_3(self):
self.assertEqual(result[0].name, "cmd_id")
self.assertEqual(result[0].raw, {'messageName': 'cmd_id', 'payload': {}})
behavior.add.assert_called_once_with(
self.user.message.generate_new_callback_id(), "test", scenarios_names[-1], text_preprocessing_result_raw, ANY
self.user.message.generate_new_callback_id(), "test", scenarios_names[-1], text_preprocessing_result_raw,
ANY
)


Expand Down Expand Up @@ -711,3 +714,35 @@ def test_action_with_jinja(self):

self.user.history.add_event.assert_called_once()
self.user.history.add_event.assert_called_once_with(expected)


class SmartGeoActionTest(unittest.TestCase):

def setUp(self):
items = {"type": "smart_geo"}
self.smart_geo_action = SmartGeoAction(items)

def test_action_send_request(self):
incoming_message = Mock(incremental_id="1605196199186625000",
session_id="0062530b-5521-42cc-90b0-a9d65dea4e98",
uuid={"userChannel": "B2C", "userId": "ec8a9097-1508-4bec-8d97-67f2329c03e0",
"sub": "385342565001000018390f1f"},
payload={})
user = Mock()
text_preprocessing_result = Mock()
params = Mock()
command = self.smart_geo_action.run(user, text_preprocessing_result, params)[0]
answer = SmartAppToMessage(command, incoming_message, None)
expected = {
"messageId": "1605196199186625000",
"sessionId": "0062530b-5521-42cc-90b0-a9d65dea4e98",
"messageName": "GET_PROFILE_DATA",
"uuid": {
"userId": "ec8a9097-1508-4bec-8d97-67f2329c03e0",
"userChannel": "B2C",
"sub": "385342565001000018390f1f"
},
"payload": {
}
}
self.assertEqual(answer.as_dict, expected)
48 changes: 48 additions & 0 deletions tests/smart_kit_tests/handlers/test_handle_take_profile_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# coding: utf-8
import unittest
from unittest.mock import Mock, MagicMock

from smart_kit.handlers import handler_take_profile_data


class MockVariables(Mock):
_storage = {}

def set(self, x, y):
self._storage[x] = y

def __getitem__(self, item):
return self._storage[item]

def get(self, item, default=None):
if item in self._storage:
return self._storage[item]
return default


class HandleTakeProfileDataTest(unittest.TestCase):
def setUp(self):
self.app_name = "TestAppName"
self.test_payload_1 = {"server_action": {}}
self.test_payload_2 = {"server_action": {"action_id": 1, "parameters": 1}}
self.test_user = MagicMock('user', message=MagicMock(message_name="some_name"), variables=MockVariables())
self.test_user.descriptions = {"external_actions": {"smart_geo_fail": MagicMock(run=lambda x, y: "fail"),
"smart_geo_success": MagicMock(run=lambda x, y: "success")}}

def test_handle_take_profile_data_init(self):
obj = handler_take_profile_data.HandlerTakeProfileData(self.app_name)
self.assertIsNotNone(obj.SUCCESS_CODE)
self.assertIsNotNone(handler_take_profile_data.GEO)

def test_handle_take_profile_data_run_fail(self):
obj = handler_take_profile_data.HandlerTakeProfileData(self.app_name)
payload = {"status_code": {"code": 102}}
self.assertEqual(obj.run(payload, self.test_user), "fail")

def test_handle_take_profile_data_run_success(self):
obj = handler_take_profile_data.HandlerTakeProfileData(self.app_name)
payload = {"profile_data": {"geo": {"reverseGeocoding": {"country": "Российская Федерация"},
"location": {"lat": 10.125, "lon": 10.0124}}},
"status_code": {"code": 1}}
self.assertEqual(obj.run(payload, self.test_user), "success")
self.assertEqual(self.test_user.variables.get("smart_geo"), payload["profile_data"]["geo"])