From 795be1b5f17012b43a3cab0db3ef965e2438442b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Thu, 26 Sep 2024 11:30:16 +0200 Subject: [PATCH] Knet Updates. Workflow updates --- checkout_sdk/payments/payment_apm.py | 6 +- checkout_sdk/payments/payments.py | 6 ++ .../payments/payments_apm_previous.py | 6 +- checkout_sdk/workflows/workflows.py | 6 ++ checkout_sdk/workflows/workflows_client.py | 8 ++- tests/exception_test.py | 56 +++++++++++++++++++ ..._apm_payments_previous_integration_test.py | 8 ++- .../request_apm_payments_integration_test.py | 8 ++- tests/workflows/workflow_integration_test.py | 35 +++++++++++- tests/workflows/workflows_client_test.py | 6 +- 10 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 tests/exception_test.py diff --git a/checkout_sdk/payments/payment_apm.py b/checkout_sdk/payments/payment_apm.py index 9a275370..783d8b56 100644 --- a/checkout_sdk/payments/payment_apm.py +++ b/checkout_sdk/payments/payment_apm.py @@ -4,7 +4,8 @@ from checkout_sdk.common.common import Address, AccountHolder from checkout_sdk.common.enums import PaymentSourceType, Country, Currency -from checkout_sdk.payments.payments import PaymentRequestSource, BillingPlan +from checkout_sdk.payments.payments import PaymentRequestSource, BillingPlan, PaymentMethodDetails +from checkout_sdk.tokens.tokens import ApplePayTokenData class RequestIdealSource(PaymentRequestSource): @@ -151,6 +152,9 @@ class RequestKnetSource(PaymentRequestSource): user_defined_field5: str card_token: str ptlf: str + token_type: str + token_data: ApplePayTokenData + payment_method_details: PaymentMethodDetails def __init__(self): super().__init__(PaymentSourceType.KNET) diff --git a/checkout_sdk/payments/payments.py b/checkout_sdk/payments/payments.py index a5e662ef..6c79ad03 100644 --- a/checkout_sdk/payments/payments.py +++ b/checkout_sdk/payments/payments.py @@ -598,3 +598,9 @@ class FawryProduct: quantity: int price: int description: str + + +class PaymentMethodDetails: + display_name: str + type: str + network: str diff --git a/checkout_sdk/payments/payments_apm_previous.py b/checkout_sdk/payments/payments_apm_previous.py index c92a3075..cacb90c3 100644 --- a/checkout_sdk/payments/payments_apm_previous.py +++ b/checkout_sdk/payments/payments_apm_previous.py @@ -4,8 +4,9 @@ from enum import Enum from checkout_sdk.common.enums import Country, PaymentSourceType -from checkout_sdk.payments.payments import Payer +from checkout_sdk.payments.payments import Payer, PaymentMethodDetails from checkout_sdk.payments.payments_previous import RequestSource +from checkout_sdk.tokens.tokens import ApplePayTokenData class IntegrationType(str, Enum): @@ -131,6 +132,9 @@ class RequestKnetSource(RequestSource): user_defined_field5: str card_token: str ptlf: str + token_type: str + token_data: ApplePayTokenData + payment_method_details: PaymentMethodDetails def __init__(self): super().__init__(PaymentSourceType.KNET) diff --git a/checkout_sdk/workflows/workflows.py b/checkout_sdk/workflows/workflows.py index 363c145b..7408b8a8 100644 --- a/checkout_sdk/workflows/workflows.py +++ b/checkout_sdk/workflows/workflows.py @@ -70,6 +70,8 @@ class CreateWorkflowRequest: class UpdateWorkflowRequest: name: str active: bool + conditions: list # WorkflowConditionRequest + actions: list # WorkflowActionRequest class ReflowRequest: @@ -82,3 +84,7 @@ class ReflowByEventsRequest(ReflowRequest): class ReflowBySubjectsRequest(ReflowRequest): subjects: list + + +class EventTypesRequest: + event_types: list diff --git a/checkout_sdk/workflows/workflows_client.py b/checkout_sdk/workflows/workflows_client.py index eaf605f5..1f50ff66 100644 --- a/checkout_sdk/workflows/workflows_client.py +++ b/checkout_sdk/workflows/workflows_client.py @@ -5,7 +5,7 @@ from checkout_sdk.checkout_configuration import CheckoutConfiguration from checkout_sdk.client import Client from checkout_sdk.workflows.workflows import CreateWorkflowRequest, UpdateWorkflowRequest, WorkflowActionRequest, \ - WorkflowConditionRequest, ReflowRequest + WorkflowConditionRequest, ReflowRequest, EventTypesRequest class WorkflowsClient(Client): @@ -17,6 +17,7 @@ class WorkflowsClient(Client): __SUBJECT_PATH = 'subject' __REFLOW_PATH = 'reflow' __WORKFLOW_PATH = 'workflow' + __TEST_PATH = 'test' def __init__(self, api_client: ApiClient, configuration: CheckoutConfiguration): super().__init__(api_client=api_client, @@ -78,6 +79,11 @@ def remove_workflow_condition(self, workflow_id: str, condition_id: str): self.build_path(self.__WORKFLOWS_PATH, workflow_id, self.__CONDITIONS_PATH, condition_id), self._sdk_authorization()) + def test_workflow(self, workflow_id: str, event_types_request: EventTypesRequest): + return self._api_client.post(self.build_path(self.__WORKFLOWS_PATH, workflow_id, self.__TEST_PATH), + self._sdk_authorization(), + event_types_request) + def get_event_types(self): return self._api_client.get(self.build_path(self.__WORKFLOWS_PATH, self.__EVENT_TYPES_PATH), self._sdk_authorization()) diff --git a/tests/exception_test.py b/tests/exception_test.py new file mode 100644 index 00000000..41961541 --- /dev/null +++ b/tests/exception_test.py @@ -0,0 +1,56 @@ +import pytest +from unittest.mock import Mock +from checkout_sdk.exception import ( + CheckoutException, + CheckoutArgumentException, + CheckoutAuthorizationException, + CheckoutApiException +) +from checkout_sdk.authorization_type import AuthorizationType + + +def test_checkout_exception(): + with pytest.raises(CheckoutException): + raise CheckoutException("Test message") + + +def test_checkout_argument_exception(): + with pytest.raises(CheckoutArgumentException): + raise CheckoutArgumentException("Argument error occurred") + + +def test_checkout_authorization_exception(): + with pytest.raises(CheckoutAuthorizationException): + raise CheckoutAuthorizationException("Authorization error occurred") + + +def test_invalid_authorization(): + auth_type = Mock(spec=AuthorizationType) + auth_type.name = "SECRET_KEY" + with pytest.raises(CheckoutAuthorizationException, match="SECRET_KEY authorization type"): + CheckoutAuthorizationException.invalid_authorization(auth_type) + + +def test_invalid_key(): + key_type = Mock(spec=AuthorizationType) + key_type.name = "PUBLIC_KEY" + with pytest.raises(CheckoutAuthorizationException, match="PUBLIC_KEY is required for this operation"): + CheckoutAuthorizationException.invalid_key(key_type) + + +def test_checkout_api_exception(): + response = Mock() + response.status_code = 400 + response.text = '{"error_type": "request_invalid", "error_codes": ["invalid_field"]}' + response.json.return_value = { + "error_type": "request_invalid", + "error_codes": ["invalid_field"] + } + + with pytest.raises(CheckoutApiException) as exc_info: + raise CheckoutApiException(response) + + exception = exc_info.value + assert exception.http_metadata.status_code == 400 + assert exception.error_type == "request_invalid" + assert exception.error_details == ["invalid_field"] diff --git a/tests/payments/previous/request_apm_payments_previous_integration_test.py b/tests/payments/previous/request_apm_payments_previous_integration_test.py index e2a4803e..2a354df9 100644 --- a/tests/payments/previous/request_apm_payments_previous_integration_test.py +++ b/tests/payments/previous/request_apm_payments_previous_integration_test.py @@ -3,7 +3,7 @@ import pytest from checkout_sdk.common.enums import Country, Currency -from checkout_sdk.payments.payments import FawryProduct +from checkout_sdk.payments.payments import FawryProduct, PaymentMethodDetails from checkout_sdk.payments.payments_apm_previous import IntegrationType, \ RequestBoletoSource, RequestFawrySource, RequestGiropaySource, RequestIdealSource, RequestOxxoSource, \ RequestPagoFacilSource, RequestRapiPagoSource, RequestSofortSource, RequestAlipaySource, \ @@ -303,8 +303,14 @@ def test_should_request_sofort_payment(previous_api): def test_should_make_knet_payment(previous_api): + payment_method_details = PaymentMethodDetails() + payment_method_details.display_name = "name" + payment_method_details.type = "type" + payment_method_details.description = "description" + request_source = RequestKnetSource() request_source.language = "en" + request_source.payment_method_details = payment_method_details payment_request = PaymentRequest() payment_request.source = request_source diff --git a/tests/payments/request_apm_payments_integration_test.py b/tests/payments/request_apm_payments_integration_test.py index 63f42b78..bbdaa71d 100644 --- a/tests/payments/request_apm_payments_integration_test.py +++ b/tests/payments/request_apm_payments_integration_test.py @@ -14,7 +14,7 @@ RequestKlarnaSource, RequestFawrySource, RequestTrustlySource, RequestCvConnectSource, RequestIllicadoSource, \ RequestSepaSource, RequestGiropaySource from checkout_sdk.payments.payments import PaymentRequest, ProcessingSettings, FawryProduct, PaymentCustomerRequest, \ - ShippingDetails + ShippingDetails, PaymentMethodDetails from checkout_sdk.payments.payments_apm_previous import RequestSofortSource from tests.checkout_test_utils import assert_response, SUCCESS_URL, FAILURE_URL, retriable, address, FIRST_NAME, \ LAST_NAME, phone, check_error_item, PAYEE_NOT_ONBOARDED, APM_SERVICE_UNAVAILABLE, random_email, new_uuid, \ @@ -245,8 +245,14 @@ def test_should_make_przelewy24_payment(default_api): def test_should_make_knet_payment(default_api): + payment_method_details = PaymentMethodDetails() + payment_method_details.display_name = "name" + payment_method_details.type = "type" + payment_method_details.description = "description" + request_source = RequestKnetSource() request_source.language = "en" + request_source.payment_method_details = payment_method_details payment_request = PaymentRequest() payment_request.source = request_source diff --git a/tests/workflows/workflow_integration_test.py b/tests/workflows/workflow_integration_test.py index 1f884eb8..bcfd20a4 100644 --- a/tests/workflows/workflow_integration_test.py +++ b/tests/workflows/workflow_integration_test.py @@ -1,7 +1,7 @@ import pytest from checkout_sdk.workflows.workflows import UpdateWorkflowRequest, WebhookWorkflowActionRequest, WebhookSignature, \ - EventWorkflowConditionRequest + EventWorkflowConditionRequest, EventTypesRequest from tests.checkout_test_utils import assert_response from tests.workflows.workflows_test_utils import create_workflow, clean_workflows, add_action @@ -205,3 +205,36 @@ def test__should_update_workflow_condition(default_api): assert condition_event_updated is not None clean_workflows(default_api) + + +@pytest.mark.skip(reason='unstable') +def test__should_create_and_test_workflow(default_api): + workflow = create_workflow(default_api) + + event_types_request = EventTypesRequest() + event_types_request.event_types = [ + "payment_approved", + "payment_declined", + "card_verification_declined", + "card_verified", + "payment_authorization_incremented", + "payment_authorization_increment_declined", + "payment_capture_declined", + "payment_captured", + "payment_refund_declined", + "payment_refunded", + "payment_void_declined", + "payment_voided", + "dispute_canceled", + "dispute_evidence_required", + "dispute_expired", + "dispute_lost", + "dispute_resolved", + "dispute_won" + ] + + get_workflow_response = default_api.workflows.test_workflow(workflow.id, event_types_request) + + assert get_workflow_response is not None + + clean_workflows(default_api) diff --git a/tests/workflows/workflows_client_test.py b/tests/workflows/workflows_client_test.py index 435946fd..ced9acdb 100644 --- a/tests/workflows/workflows_client_test.py +++ b/tests/workflows/workflows_client_test.py @@ -1,7 +1,7 @@ import pytest from checkout_sdk.workflows.workflows import CreateWorkflowRequest, UpdateWorkflowRequest, \ - WebhookWorkflowActionRequest, EventWorkflowConditionRequest, ReflowRequest + WebhookWorkflowActionRequest, EventWorkflowConditionRequest, ReflowRequest, EventTypesRequest from checkout_sdk.workflows.workflows_client import WorkflowsClient @@ -57,6 +57,10 @@ def test_remove_workflow_condition(self, mocker, client: WorkflowsClient): mocker.patch('checkout_sdk.api_client.ApiClient.delete', return_value='response') assert client.remove_workflow_condition('workflow_id', 'condition_id') == 'response' + def test_test_workflow(self, mocker, client: WorkflowsClient): + mocker.patch('checkout_sdk.api_client.ApiClient.post', return_value='response') + assert client.test_workflow('workflow_id', EventTypesRequest()) == 'response' + def test_get_event_types(self, mocker, client: WorkflowsClient): mocker.patch('checkout_sdk.api_client.ApiClient.get', return_value='response') assert client.get_event_types() == 'response'