From 49b470a44e6825d94e43d4d65260004873b90d1b Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Fri, 11 Mar 2022 01:07:11 +0300 Subject: [PATCH 1/8] add SmartPayAction --- core/basic_models/actions/smartpay.py | 70 ++++++++++ smart_kit/resources/__init__.py | 8 ++ .../action_test/test_smartpay.py | 122 ++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 core/basic_models/actions/smartpay.py create mode 100644 tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py new file mode 100644 index 00000000..de6d72e6 --- /dev/null +++ b/core/basic_models/actions/smartpay.py @@ -0,0 +1,70 @@ +from smart_kit.action.http import HTTPRequestAction + + +POST = "POST" +GET = "GET" +PUT = "PUT" +DELETE = "DELETE" +PATCH = "PATCH" + + +class SmartPayAction(HTTPRequestAction): + url = None + method = None + store = None + + def __init__(self, items, id=None): + items = { + "params": {"json": items, "method": self.method, "url": self.url}, + "store": self.store, + "behavior": items.get("behavior") + } + super().__init__(items, id) + + +class SmartPayCreateAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = "/invoices" + self.method = POST + self.store = "SmartPay_create_answer" + super().__init__(items, id) + + +class SmartPayPerformAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = f"/invoices/{items['invoice_id']}" + self.method = POST + self.store = "SmartPay_perform_answer" + super().__init__(items, id) + + +class SmartPayGetStatusAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = f"/invoices/{items['invoice_id']}" + self.method = GET + self.store = "SmartPay_get_status_answer" + super().__init__(items, id) + + +class SmartPayConfirmAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = f"/invoices/{items['invoice_id']}" + self.method = PUT + self.store = "SmartPay_confirm_answer" + super().__init__(items, id) + + +class SmartPayDeleteAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = f"/invoices/{items['invoice_id']}" + self.method = DELETE + self.store = "SmartPay_delete_answer" + super().__init__(items, id) + + +class SmartPayRefundAction(SmartPayAction): + def __init__(self, items, id=None): + self.url = f"/invoices/{items['invoice_id']}" + self.method = PATCH + self.store = "SmartPay_refund_answer" + super().__init__(items, id) diff --git a/smart_kit/resources/__init__.py b/smart_kit/resources/__init__.py index ba834ec8..0d050842 100644 --- a/smart_kit/resources/__init__.py +++ b/smart_kit/resources/__init__.py @@ -14,6 +14,8 @@ from core.basic_models.actions.external_actions import ExternalAction from core.basic_models.actions.external_actions import ExternalActions from core.basic_models.actions.push_action import PushAction, PUSH_NOTIFY +from core.basic_models.actions.smartpay import SmartPayCreateAction, SmartPayPerformAction, SmartPayGetStatusAction, \ + SmartPayConfirmAction, SmartPayDeleteAction, SmartPayRefundAction from core.basic_models.actions.string_actions import StringAction, AfinaAnswerAction, SDKAnswer, \ SDKAnswerToUser from core.basic_models.answer_items.answer_items import items_factory, SdkAnswerItem, answer_items, BubbleText, \ @@ -315,6 +317,12 @@ def init_actions(self): actions["push"] = PushAction actions["give_me_memory"] = GiveMeMemoryAction actions["remember_this"] = RememberThisAction + actions["smartpay_create"] = SmartPayCreateAction + actions["smartpay_perform"] = SmartPayPerformAction + actions["smartpay_get_status"] = SmartPayGetStatusAction + actions["smartpay_confirm"] = SmartPayConfirmAction + actions["smartpay_delete"] = SmartPayDeleteAction + actions["smartpay_refund"] = SmartPayRefundAction def init_requirements(self): requirements[None] = Requirement diff --git a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py new file mode 100644 index 00000000..b2395691 --- /dev/null +++ b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py @@ -0,0 +1,122 @@ +import unittest + +from core.basic_models.actions.smartpay import SmartPayCreateAction +from smart_kit.utils.picklable_mock import PicklableMagicMock + + +class SmartPayCreateActionTest(unittest.TestCase): + def test_run(self): + items = { + "ptype": 1, + "invoice": { + "purchaser": { + "email": "test@test.ru", + "phone": "71111111111", + "contact": "phone" + }, + "delivery_info": { + "address": { + "country": "RU", + "city": "Москва", + "address": "Кутузовский проспект, 32" + }, + "delivery_type": "courier", + "description": "Спросить '\''Где тут Сбердевайсы?'\''" + }, + "invoice_params": [ + { + "key": "packageName", + "value": "SbERdeVICEs" + }, + { + "key": "packageKey", + "value": "ru.sberdevices.test" + } + ], + "order": { + "order_id": "a952b7ee-c928-4586-bd05-d932c21f749", + "order_number": "1952", + "order_date": "2021-04-07T08:24:37.729Z", + "service_id": "13", + "amount": 79900, + "currency": "RUB", + "purpose": "Покупка продуктов", + "description": "Заказ № 22-1952. Покупка продуктов", + "language": "ru-RU", + "tax_system": 0, + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "item_params": [ + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Ромашка" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "5009053292" + }, + { + "key": "_itemAttributes_nomenclature", + "value": "Å\u001e13622200005881" + }, + { + "key": "_itemAttributes_agent_info.type", + "value": "7" + } + + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 79801, + "currency": "RUB", + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", + "item_price": 79801, + "discount_type": "amount", + "discount_value": 17687, + "tax_type": 6 + }, + { + "position_id": 2, + "name": "Тиристор", + "item_params": [ + { + "key": "code", + "value": "123значение321" + }, + { + "key": "pack", + "value": "100" + }, + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Платежи" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "7730253720" + } + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 99, + "currency": "RUB", + "item_code": "21ff407c-fa98-11e8-80c5-0cc47a817926", + "item_price": 99, + "discount_type": "amount", + "discount_value": 21, + "tax_type": 6, + } + ] + } + } + } + user = PicklableMagicMock() + action = SmartPayCreateAction(items) + result = action.run(user, None) + print(result) From a012c6538f9552e91cb74dfab4f5aabf4acdbc54 Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Mon, 21 Mar 2022 10:51:14 +0300 Subject: [PATCH 2/8] add actions for SmartPay --- .../action_test/test_smartpay.py | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py diff --git a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py deleted file mode 100644 index b2395691..00000000 --- a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py +++ /dev/null @@ -1,122 +0,0 @@ -import unittest - -from core.basic_models.actions.smartpay import SmartPayCreateAction -from smart_kit.utils.picklable_mock import PicklableMagicMock - - -class SmartPayCreateActionTest(unittest.TestCase): - def test_run(self): - items = { - "ptype": 1, - "invoice": { - "purchaser": { - "email": "test@test.ru", - "phone": "71111111111", - "contact": "phone" - }, - "delivery_info": { - "address": { - "country": "RU", - "city": "Москва", - "address": "Кутузовский проспект, 32" - }, - "delivery_type": "courier", - "description": "Спросить '\''Где тут Сбердевайсы?'\''" - }, - "invoice_params": [ - { - "key": "packageName", - "value": "SbERdeVICEs" - }, - { - "key": "packageKey", - "value": "ru.sberdevices.test" - } - ], - "order": { - "order_id": "a952b7ee-c928-4586-bd05-d932c21f749", - "order_number": "1952", - "order_date": "2021-04-07T08:24:37.729Z", - "service_id": "13", - "amount": 79900, - "currency": "RUB", - "purpose": "Покупка продуктов", - "description": "Заказ № 22-1952. Покупка продуктов", - "language": "ru-RU", - "tax_system": 0, - "order_bundle": [ - { - "position_id": 1, - "name": "Транзистор", - "item_params": [ - { - "key": "_itemAttributes_supplier_info.name", - "value": "ООО Ромашка" - }, - { - "key": "_itemAttributes_supplier_info.inn", - "value": "5009053292" - }, - { - "key": "_itemAttributes_nomenclature", - "value": "Å\u001e13622200005881" - }, - { - "key": "_itemAttributes_agent_info.type", - "value": "7" - } - - ], - "quantity": { - "value": 1, - "measure": "шт." - }, - "item_amount": 79801, - "currency": "RUB", - "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", - "item_price": 79801, - "discount_type": "amount", - "discount_value": 17687, - "tax_type": 6 - }, - { - "position_id": 2, - "name": "Тиристор", - "item_params": [ - { - "key": "code", - "value": "123значение321" - }, - { - "key": "pack", - "value": "100" - }, - { - "key": "_itemAttributes_supplier_info.name", - "value": "ООО Платежи" - }, - { - "key": "_itemAttributes_supplier_info.inn", - "value": "7730253720" - } - ], - "quantity": { - "value": 1, - "measure": "шт." - }, - "item_amount": 99, - "currency": "RUB", - "item_code": "21ff407c-fa98-11e8-80c5-0cc47a817926", - "item_price": 99, - "discount_type": "amount", - "discount_value": 21, - "tax_type": 6, - } - ] - } - } - } - user = PicklableMagicMock() - action = SmartPayCreateAction(items) - result = action.run(user, None) - print(result) From 6427a2e05af9df4d4aec45debbba6affc3fe7e73 Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Thu, 31 Mar 2022 00:12:49 +0300 Subject: [PATCH 3/8] smartpay refactoring --- core/basic_models/actions/smartpay.py | 19 ++++++------------- smart_kit/action/http.py | 5 +++++ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py index de6d72e6..713a7e28 100644 --- a/core/basic_models/actions/smartpay.py +++ b/core/basic_models/actions/smartpay.py @@ -1,13 +1,6 @@ from smart_kit.action.http import HTTPRequestAction -POST = "POST" -GET = "GET" -PUT = "PUT" -DELETE = "DELETE" -PATCH = "PATCH" - - class SmartPayAction(HTTPRequestAction): url = None method = None @@ -25,7 +18,7 @@ def __init__(self, items, id=None): class SmartPayCreateAction(SmartPayAction): def __init__(self, items, id=None): self.url = "/invoices" - self.method = POST + self.method = self.POST self.store = "SmartPay_create_answer" super().__init__(items, id) @@ -33,7 +26,7 @@ def __init__(self, items, id=None): class SmartPayPerformAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" - self.method = POST + self.method = self.POST self.store = "SmartPay_perform_answer" super().__init__(items, id) @@ -41,7 +34,7 @@ def __init__(self, items, id=None): class SmartPayGetStatusAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" - self.method = GET + self.method = self.GET self.store = "SmartPay_get_status_answer" super().__init__(items, id) @@ -49,7 +42,7 @@ def __init__(self, items, id=None): class SmartPayConfirmAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" - self.method = PUT + self.method = self.PUT self.store = "SmartPay_confirm_answer" super().__init__(items, id) @@ -57,7 +50,7 @@ def __init__(self, items, id=None): class SmartPayDeleteAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" - self.method = DELETE + self.method = self.DELETE self.store = "SmartPay_delete_answer" super().__init__(items, id) @@ -65,6 +58,6 @@ def __init__(self, items, id=None): class SmartPayRefundAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" - self.method = PATCH + self.method = self.PATCH self.store = "SmartPay_refund_answer" super().__init__(items, id) diff --git a/smart_kit/action/http.py b/smart_kit/action/http.py index 7437270c..0e3eb066 100644 --- a/smart_kit/action/http.py +++ b/smart_kit/action/http.py @@ -22,6 +22,11 @@ class HTTPRequestAction(Action): """ HTTP_ACTION = BaseHttpRequestAction + POST = "POST" + GET = "GET" + PUT = "PUT" + DELETE = "DELETE" + PATCH = "PATCH" def __init__(self, items, id=None): self.http_action = self.HTTP_ACTION(items["params"], id) From 6cd52a441df0a2ad3a13074d5ce7c337626e8d96 Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Fri, 1 Apr 2022 11:01:37 +0300 Subject: [PATCH 4/8] smartpay refactoring --- core/basic_models/actions/smartpay.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py index 713a7e28..b095ec1b 100644 --- a/core/basic_models/actions/smartpay.py +++ b/core/basic_models/actions/smartpay.py @@ -1,3 +1,8 @@ +from typing import Optional, Dict, Union, List + +from core.basic_models.actions.command import Command +from core.model.base_user import BaseUser +from core.text_preprocessing.base import BaseTextPreprocessingResult from smart_kit.action.http import HTTPRequestAction @@ -14,6 +19,12 @@ def __init__(self, items, id=None): } super().__init__(items, id) + def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, + params: Optional[Dict[str, Union[str, float, int]]] = None) -> Optional[List[Command]]: + self.http_action.method_params["url"] = \ + user.settings["template_settings"]["smart_pay_url"] + self.http_action.method_params["url"] + return super().run(user, text_preprocessing_result, params) + class SmartPayCreateAction(SmartPayAction): def __init__(self, items, id=None): From b224cb1c2b183d8422cded5499a215f69d54926f Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Mon, 4 Apr 2022 15:04:50 +0300 Subject: [PATCH 5/8] smartpay refactoring and unittests --- core/basic_models/actions/smartpay.py | 34 +- smart_kit/action/base_http.py | 6 +- .../action_test/test_smartpay.py | 325 ++++++++++++++++++ .../action/test_base_http_action.py | 9 +- 4 files changed, 359 insertions(+), 15 deletions(-) create mode 100644 tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py index b095ec1b..de771459 100644 --- a/core/basic_models/actions/smartpay.py +++ b/core/basic_models/actions/smartpay.py @@ -12,11 +12,19 @@ class SmartPayAction(HTTPRequestAction): store = None def __init__(self, items, id=None): + request_params = items.get("request_params") + smartpay_params = items.get("smartpay_params") + items = { - "params": {"json": items, "method": self.method, "url": self.url}, + "params": {"method": self.method, "url": self.url}, "store": self.store, - "behavior": items.get("behavior") + "behavior": items["behavior"] } + if request_params: + items["params"]["params"] = request_params + if smartpay_params: + items["params"]["json"] = smartpay_params + super().__init__(items, id) def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, @@ -30,7 +38,7 @@ class SmartPayCreateAction(SmartPayAction): def __init__(self, items, id=None): self.url = "/invoices" self.method = self.POST - self.store = "SmartPay_create_answer" + self.store = "smartpay_create_answer" super().__init__(items, id) @@ -38,15 +46,25 @@ class SmartPayPerformAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.POST - self.store = "SmartPay_perform_answer" + self.store = "smartpay_perform_answer" super().__init__(items, id) class SmartPayGetStatusAction(SmartPayAction): def __init__(self, items, id=None): + items["request_params"] = {} + inv_status = items.get("inv_status") + wait = items.get("wait") + if inv_status: + del items["inv_status"] + items["request_params"]["inv_status"] = inv_status + if wait: + del items["wait"] + items["request_params"]["wait"] = wait + self.url = f"/invoices/{items['invoice_id']}" self.method = self.GET - self.store = "SmartPay_get_status_answer" + self.store = "smartpay_get_status_answer" super().__init__(items, id) @@ -54,7 +72,7 @@ class SmartPayConfirmAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.PUT - self.store = "SmartPay_confirm_answer" + self.store = "smartpay_confirm_answer" super().__init__(items, id) @@ -62,7 +80,7 @@ class SmartPayDeleteAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.DELETE - self.store = "SmartPay_delete_answer" + self.store = "smartpay_delete_answer" super().__init__(items, id) @@ -70,5 +88,5 @@ class SmartPayRefundAction(SmartPayAction): def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.PATCH - self.store = "SmartPay_refund_answer" + self.store = "smartpay_refund_answer" super().__init__(items, id) diff --git a/smart_kit/action/base_http.py b/smart_kit/action/base_http.py index b2904309..5fcffdc0 100644 --- a/smart_kit/action/base_http.py +++ b/smart_kit/action/base_http.py @@ -64,8 +64,8 @@ def _make_response(self, request_parameters, user): except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError): self.error = self.CONNECTION - def _get_requst_params(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, - params: Optional[Dict[str, Union[str, float, int]]] = None): + def _get_request_params(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, + params: Optional[Dict[str, Union[str, float, int]]] = None): collected = user.parametrizer.collect(text_preprocessing_result) params.update(collected) @@ -97,6 +97,6 @@ def _log_response(self, user, response, data): def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, params: Optional[Dict[str, Union[str, float, int]]] = None) -> Optional[List[Command]]: params = params or {} - request_parameters = self._get_requst_params(user, text_preprocessing_result, params) + request_parameters = self._get_request_params(user, text_preprocessing_result, params) self._log_request(user, request_parameters) return self._make_response(request_parameters, user) diff --git a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py new file mode 100644 index 00000000..d04e5f2a --- /dev/null +++ b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py @@ -0,0 +1,325 @@ +import unittest +from unittest.mock import patch + +from core.basic_models.actions.smartpay import SmartPayCreateAction, SmartPayPerformAction, SmartPayGetStatusAction, \ + SmartPayConfirmAction, SmartPayDeleteAction, SmartPayRefundAction +from smart_kit.utils.picklable_mock import PicklableMock +from tests.smart_kit_tests.action.test_base_http_action import BaseHttpRequestActionTest + + +class SmartPayActionTest(unittest.TestCase): + def setUp(self): + self.user = PicklableMock( + parametrizer=PicklableMock(collect=lambda *args, **kwargs: {}), + descriptions={ + "behaviors": { + "my_behavior": PicklableMock(timeout=PicklableMock(return_value=3)) + } + }, + settings={ + "template_settings": { + "smart_pay_url": "0.0.0.0" + } + } + ) + + @patch('requests.request') + def test_create(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "smartpay_params": { + "ptype": 1, + "invoice": { + "purchaser": { + "email": "test@test.ru", + "phone": "71111111111", + "contact": "phone" + }, + "delivery_info": { + "address": { + "country": "RU", + "city": "Москва", + "address": "Кутузовский проспект, 32" + }, + "delivery_type": "courier", + "description": "Спросить '\''Где тут Сбердевайсы?'\''" + }, + "invoice_params": [ + { + "key": "packageName", + "value": "SbERdeVICEs" + }, + { + "key": "packageKey", + "value": "ru.sberdevices.test" + } + ], + "order": { + "order_id": "a952b7ee-c928-4586-bd05-d932c21f749", + "order_number": "1952", + "order_date": "2021-04-07T08:24:37.729Z", + "service_id": "13", + "amount": 79900, + "currency": "RUB", + "purpose": "Покупка продуктов", + "description": "Заказ № 22-1952. Покупка продуктов", + "language": "ru-RU", + "tax_system": 0, + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "item_params": [ + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Ромашка" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "5009053292" + }, + { + "key": "_itemAttributes_nomenclature", + "value": "Å\u001e13622200005881" + }, + { + "key": "_itemAttributes_agent_info.type", + "value": "7" + } + + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 79801, + "currency": "RUB", + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", + "item_price": 79801, + "discount_type": "amount", + "discount_value": 17687, + "tax_type": 6 + }, + { + "position_id": 2, + "name": "Тиристор", + "item_params": [ + { + "key": "code", + "value": "123значение321" + }, + { + "key": "pack", + "value": "100" + }, + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Платежи" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "7730253720" + } + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 99, + "currency": "RUB", + "item_code": "21ff407c-fa98-11e8-80c5-0cc47a817926", + "item_price": 99, + "discount_type": "amount", + "discount_value": 21, + "tax_type": 6, + } + ] + } + } + } + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayCreateAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices", method="POST", + timeout=3, json=items.get("smartpay_params")) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_create_answer", {'data': 'value'}) + + @patch('requests.request') + def test_perform(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + "smartpay_params": { + "user_id": { + "partner_client_id": "2223" + }, + "operations": [ + { + "operation": "payment", + "code": "invoice", + "value": "167900" + } + ], + "device_info": { + "device_platform_type": "iOS", + "device_platform_version": "13.6.1", + "device_model": "iPhone 7", + "device_manufacturer": "Apple", + "device_id": "83c3f257-46d8-41fe-951b-f79d04e288c2", + "surface": "SBOL", + "surface_version": "11.5.0" + }, + "return_url": "https://ok", + "fail_url": "https://fail" + } + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayPerformAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="POST", + timeout=3, json=items.get("smartpay_params")) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_perform_answer", {'data': 'value'}) + + @patch('requests.request') + def test_get_status(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + "inv_status": "executed", + "wait": 50 + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayGetStatusAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="GET", + timeout=3, params={"inv_status": "executed", "wait": 50}) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_get_status_answer", {'data': 'value'}) + + @patch('requests.request') + def test_partial_confirm(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + "smartpay_params": { + "invoice": { + "order": { + "amount": 79801, + "currency": "RUB", + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 79801, + "currency": "RUB", + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", + "item_price": 79801 + } + ] + } + } + } + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayConfirmAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="PUT", + timeout=3, json=items["smartpay_params"]) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_confirm_answer", {'data': 'value'}) + + @patch('requests.request') + def test_full_confirm(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayConfirmAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="PUT", timeout=3) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_confirm_answer", {'data': 'value'}) + + @patch('requests.request') + def test_delete(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayDeleteAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="DELETE", timeout=3) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_delete_answer", {'data': 'value'}) + + @patch('requests.request') + def test_partial_refund(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + "smartpay_params": { + "invoice": { + "order": { + "current_amount": 79900, + "refund_amount": 79801, + "currency": "RUB", + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "quantity": { + "value": 1 + }, + "item_amount": 79801, + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926" + } + ] + } + } + } + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayRefundAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="PATCH", + timeout=3, json=items["smartpay_params"]) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_refund_answer", {'data': 'value'}) + + @patch('requests.request') + def test_full_refund(self, request_mock: PicklableMock): + items = { + "behavior": "my_behavior", + "invoice_id": "0", + } + + BaseHttpRequestActionTest.set_request_mock_attribute(request_mock, return_value={'data': 'value'}) + action = SmartPayRefundAction(items) + action.run(self.user, None, {}) + request_mock.assert_called_with(url="0.0.0.0/invoices/0", method="PATCH", timeout=3) + self.assertTrue(self.user.descriptions["behaviors"]["my_behavior"].success_action.run.called) + self.assertTrue(self.user.variables.set.called) + self.user.variables.set.assert_called_with("smartpay_refund_answer", {'data': 'value'}) diff --git a/tests/smart_kit_tests/action/test_base_http_action.py b/tests/smart_kit_tests/action/test_base_http_action.py index 581b0a70..cb6977a3 100644 --- a/tests/smart_kit_tests/action/test_base_http_action.py +++ b/tests/smart_kit_tests/action/test_base_http_action.py @@ -2,6 +2,7 @@ from unittest.mock import Mock, patch from smart_kit.action.base_http import BaseHttpRequestAction +from smart_kit.utils.picklable_mock import PicklableMock class BaseHttpRequestActionTest(unittest.TestCase): @@ -11,13 +12,13 @@ def setUp(self): @staticmethod def set_request_mock_attribute(request_mock, return_value=None): return_value = return_value or {} - request_mock.return_value = Mock( - __enter__=Mock(return_value=Mock( - json=Mock(return_value=return_value), + request_mock.return_value = PicklableMock( + __enter__=PicklableMock(return_value=PicklableMock( + json=PicklableMock(return_value=return_value), cookies={}, headers={}, ),), - __exit__=Mock() + __exit__=PicklableMock() ) @patch('requests.request') From 2a34f516929c8cd97b1f6c0f6dd5a12644b4ca63 Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Fri, 8 Apr 2022 11:07:49 +0300 Subject: [PATCH 6/8] add examples for smartpay --- core/basic_models/actions/smartpay.py | 235 ++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py index de771459..9c8d5940 100644 --- a/core/basic_models/actions/smartpay.py +++ b/core/basic_models/actions/smartpay.py @@ -35,6 +35,125 @@ def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingRe class SmartPayCreateAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_create", + "behavior": "some_behavior", // обязательный параметр + "smartpay_params": { // обязательноый параметр + "ptype": 1, + "invoice": { + "purchaser": { + "email": "test@test.ru", + "phone": "71111111111", + "contact": "phone" + }, + "delivery_info": { + "address": { + "country": "RU", + "city": "Москва", + "address": "Кутузовский проспект, 32" + }, + "delivery_type": "courier", + "description": "Спросить '\''Где тут Сбердевайсы?'\''" + }, + "invoice_params": [ + { + "key": "packageName", + "value": "SbERdeVICEs" + }, + { + "key": "packageKey", + "value": "ru.sberdevices.test" + } + ], + "order": { + "order_id": "a952b7ee-c928-4586-bd05-d932c21f749", + "order_number": "1952", + "order_date": "2021-04-07T08:24:37.729Z", + "service_id": "13", + "amount": 79900, + "currency": "RUB", + "purpose": "Покупка продуктов", + "description": "Заказ № 22-1952. Покупка продуктов", + "language": "ru-RU", + "tax_system": 0, + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "item_params": [ + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Ромашка" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "5009053292" + }, + { + "key": "_itemAttributes_nomenclature", + "value": "Å\u001e13622200005881" + }, + { + "key": "_itemAttributes_agent_info.type", + "value": "7" + } + + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 79801, + "currency": "RUB", + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", + "item_price": 79801, + "discount_type": "amount", + "discount_value": 17687, + "tax_type": 6 + }, + { + "position_id": 2, + "name": "Тиристор", + "item_params": [ + { + "key": "code", + "value": "123значение321" + }, + { + "key": "pack", + "value": "100" + }, + { + "key": "_itemAttributes_supplier_info.name", + "value": "ООО Платежи" + }, + { + "key": "_itemAttributes_supplier_info.inn", + "value": "7730253720" + } + ], + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 99, + "currency": "RUB", + "item_code": "21ff407c-fa98-11e8-80c5-0cc47a817926", + "item_price": 99, + "discount_type": "amount", + "discount_value": 21, + "tax_type": 6, + } + ] + } + } + } + } + """ + def __init__(self, items, id=None): self.url = "/invoices" self.method = self.POST @@ -43,6 +162,39 @@ def __init__(self, items, id=None): class SmartPayPerformAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_perform", + "behavior": "some_behavior", // обязательный параметр + "invoice_id": "0", // обязательный параметр + "smartpay_params": { // обязательынй параметр + "user_id": { + "partner_client_id": "2223" + }, + "operations": [ + { + "operation": "payment", + "code": "invoice", + "value": "167900" + } + ], + "device_info": { + "device_platform_type": "iOS", + "device_platform_version": "13.6.1", + "device_model": "iPhone 7", + "device_manufacturer": "Apple", + "device_id": "83c3f257-46d8-41fe-951b-f79d04e288c2", + "surface": "SBOL", + "surface_version": "11.5.0" + }, + "return_url": "https://ok", + "fail_url": "https://fail" + } + } + """ + def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.POST @@ -51,6 +203,18 @@ def __init__(self, items, id=None): class SmartPayGetStatusAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_get_status", + "behavior": "some_behavior", // обязательный параметр + "invoice_id": "0", // обязательный параметр + "inv_status": "executed", // опциональный параметр + "wait": 50 // опциональный параметр + } + """ + def __init__(self, items, id=None): items["request_params"] = {} inv_status = items.get("inv_status") @@ -69,6 +233,37 @@ def __init__(self, items, id=None): class SmartPayConfirmAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_confirm", + "invoice_id": "0", // обязательный параметр + "smartpay_params": { // опциональный параметр, задаётся для неполной суммы (см. доку SmartPay API) + "invoice": { + "order": { + "amount": 79801, + "currency": "RUB", + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "quantity": { + "value": 1, + "measure": "шт." + }, + "item_amount": 79801, + "currency": "RUB", + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926", + "item_price": 79801 + } + ] + } + } + } + } + """ + def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.PUT @@ -77,6 +272,16 @@ def __init__(self, items, id=None): class SmartPayDeleteAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_delete", + "behavior": "my_behavior", // обязательынй параметр + "invoice_id": "0" // обязательынй параметр + } + """ + def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.DELETE @@ -85,6 +290,36 @@ def __init__(self, items, id=None): class SmartPayRefundAction(SmartPayAction): + + """ + Example:: + { + "type": "smartpay_refund", + "behavior": "some_behavior", // обязательный параметр + "invoice_id": "0", // обязательный параметр + "smartpay_params": { // опциональный параметр, задаётся при частичном возврате (см. доку SmartPay API) + "invoice": { + "order": { + "current_amount": 79900, + "refund_amount": 79801, + "currency": "RUB", + "order_bundle": [ + { + "position_id": 1, + "name": "Транзистор", + "quantity": { + "value": 1 + }, + "item_amount": 79801, + "item_code": "21ff407a-fa98-11e8-80c5-0cc47a817926" + } + ] + } + } + } + } + """ + def __init__(self, items, id=None): self.url = f"/invoices/{items['invoice_id']}" self.method = self.PATCH From c5e680b6e180341a8b0e6ebd943d7b45ba486c2e Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Fri, 8 Apr 2022 11:19:40 +0300 Subject: [PATCH 7/8] add examples for smartpay --- core/basic_models/actions/smartpay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/basic_models/actions/smartpay.py b/core/basic_models/actions/smartpay.py index 9c8d5940..cbe383b1 100644 --- a/core/basic_models/actions/smartpay.py +++ b/core/basic_models/actions/smartpay.py @@ -30,7 +30,7 @@ def __init__(self, items, id=None): def run(self, user: BaseUser, text_preprocessing_result: BaseTextPreprocessingResult, params: Optional[Dict[str, Union[str, float, int]]] = None) -> Optional[List[Command]]: self.http_action.method_params["url"] = \ - user.settings["template_settings"]["smart_pay_url"] + self.http_action.method_params["url"] + user.settings["template_settings"]["smartpay_url"] + self.http_action.method_params["url"] return super().run(user, text_preprocessing_result, params) From a21fa4106ef3f415fe6ede824a5286306823b54c Mon Sep 17 00:00:00 2001 From: Dan1lD Date: Fri, 8 Apr 2022 11:49:57 +0300 Subject: [PATCH 8/8] refactoring --- .../basic_scenario_models_test/action_test/test_smartpay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py index d04e5f2a..edfb6103 100644 --- a/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py +++ b/tests/core_tests/basic_scenario_models_test/action_test/test_smartpay.py @@ -18,7 +18,7 @@ def setUp(self): }, settings={ "template_settings": { - "smart_pay_url": "0.0.0.0" + "smartpay_url": "0.0.0.0" } } )