From 15ba0455a985c49a5c84e0d5bb3acabe08fa192c Mon Sep 17 00:00:00 2001 From: David Grayston Date: Tue, 3 Dec 2024 17:33:29 +0000 Subject: [PATCH 1/3] fix: Subscription IDs can be omitted when creating customer portal sessions --- CHANGELOG.md | 6 ++++++ paddle_billing/Client.py | 2 +- .../Operations/CreateCustomerPortalSession.py | 3 ++- setup.py | 2 +- .../_fixtures/request/create_empty.json | 3 +++ .../_fixtures/response/full_entity_empty.json | 16 ++++++++++++++++ .../test_CustomerPortalSessionsClient.py | 16 ++++++++++++++++ 7 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tests/Functional/Resources/CustomerPortalSessions/_fixtures/request/create_empty.json create mode 100644 tests/Functional/Resources/CustomerPortalSessions/_fixtures/response/full_entity_empty.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 3371866..540a6af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx&utm_medium=paddle-python-sdk) for information about changes to the Paddle Billing platform, the Paddle API, and other developer tools. +## 1.2.1 - 2024-12-04 + +### Fixed + +- Subscription IDs can be omitted when creating customer portal sessions + ## 1.2.0 - 2024-12-03 ### Added diff --git a/paddle_billing/Client.py b/paddle_billing/Client.py index 0b7c9e4..b073d9c 100644 --- a/paddle_billing/Client.py +++ b/paddle_billing/Client.py @@ -204,7 +204,7 @@ def build_request_session(self) -> Session: "Authorization": f"Bearer {self.__api_key}", "Content-Type": "application/json", "Paddle-Version": str(self.use_api_version), - "User-Agent": "PaddleSDK/python 1.2.0", + "User-Agent": "PaddleSDK/python 1.2.1", } ) diff --git a/paddle_billing/Resources/CustomerPortalSessions/Operations/CreateCustomerPortalSession.py b/paddle_billing/Resources/CustomerPortalSessions/Operations/CreateCustomerPortalSession.py index 193a073..59de3a2 100644 --- a/paddle_billing/Resources/CustomerPortalSessions/Operations/CreateCustomerPortalSession.py +++ b/paddle_billing/Resources/CustomerPortalSessions/Operations/CreateCustomerPortalSession.py @@ -1,8 +1,9 @@ from dataclasses import dataclass from paddle_billing.Operation import Operation +from paddle_billing.Undefined import Undefined @dataclass class CreateCustomerPortalSession(Operation): - subscription_ids: list[str] = (None,) + subscription_ids: list[str] | Undefined = Undefined() diff --git a/setup.py b/setup.py index 2668c92..5a88d8c 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( - version="1.2.0", + version="1.2.1", author="Paddle and contributors", author_email="team-dx@paddle.com", description="Paddle's Python SDK for Paddle Billing", diff --git a/tests/Functional/Resources/CustomerPortalSessions/_fixtures/request/create_empty.json b/tests/Functional/Resources/CustomerPortalSessions/_fixtures/request/create_empty.json new file mode 100644 index 0000000..3884dfd --- /dev/null +++ b/tests/Functional/Resources/CustomerPortalSessions/_fixtures/request/create_empty.json @@ -0,0 +1,3 @@ +{ + "subscription_ids": [] +} diff --git a/tests/Functional/Resources/CustomerPortalSessions/_fixtures/response/full_entity_empty.json b/tests/Functional/Resources/CustomerPortalSessions/_fixtures/response/full_entity_empty.json new file mode 100644 index 0000000..6c8fe80 --- /dev/null +++ b/tests/Functional/Resources/CustomerPortalSessions/_fixtures/response/full_entity_empty.json @@ -0,0 +1,16 @@ +{ + "data": { + "id": "cpls_01h4ge9r64c22exjsx0fy8b48b", + "customer_id": "ctm_01gysfvfy7vqhpzkq8rjmrq7an", + "urls": { + "general": { + "overview": "https://customer-portal.paddle.com/cpl_01j7zbyqs3vah3aafp4jf62qaw?action=overview&token=pga_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjdG1fMDFncm5uNHp0YTVhMW1mMDJqanplN3kyeXMiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE3Mjc2NzkyMzh9._oO12IejzdKmyKTwb7BLjmiILkx4_cSyGjXraOBUI_g" + }, + "subscriptions": [] + }, + "created_at": "2024-10-25T06:53:58Z" + }, + "meta": { + "request_id": "fa176777-4bca-49ec-aa1e-f53885333cb7" + } +} diff --git a/tests/Functional/Resources/CustomerPortalSessions/test_CustomerPortalSessionsClient.py b/tests/Functional/Resources/CustomerPortalSessions/test_CustomerPortalSessionsClient.py index 064d688..7b8ea7b 100644 --- a/tests/Functional/Resources/CustomerPortalSessions/test_CustomerPortalSessionsClient.py +++ b/tests/Functional/Resources/CustomerPortalSessions/test_CustomerPortalSessionsClient.py @@ -32,10 +32,26 @@ class TestAddressesClient: ReadsFixtures.read_raw_json_fixture("response/full_entity_multiple"), "/customers/ctm_01gysfvfy7vqhpzkq8rjmrq7an/portal-sessions", ), + ( + "ctm_01gysfvfy7vqhpzkq8rjmrq7an", + CreateCustomerPortalSession([]), + ReadsFixtures.read_raw_json_fixture("request/create_empty"), + ReadsFixtures.read_raw_json_fixture("response/full_entity_empty"), + "/customers/ctm_01gysfvfy7vqhpzkq8rjmrq7an/portal-sessions", + ), + ( + "ctm_01gysfvfy7vqhpzkq8rjmrq7an", + CreateCustomerPortalSession(), + "{}", + ReadsFixtures.read_raw_json_fixture("response/full_entity_empty"), + "/customers/ctm_01gysfvfy7vqhpzkq8rjmrq7an/portal-sessions", + ), ], ids=[ "Create portal session with single subscription ID", "Create portal session with multiple subscription IDs", + "Create portal session with empty subscription IDs", + "Create portal session with omitted subscription IDs", ], ) def test_create_uses_expected_payload( From 87a279af4d0d2986d79c5b6590eaeb153a0b3173 Mon Sep 17 00:00:00 2001 From: David Grayston Date: Tue, 3 Dec 2024 20:17:05 +0000 Subject: [PATCH 2/3] fix: Customer portal session customer ID will always be returned as string --- CHANGELOG.md | 1 + paddle_billing/Entities/CustomerPortalSession.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 540a6af..bdc8dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx ### Fixed - Subscription IDs can be omitted when creating customer portal sessions +- Customer portal session customer ID will always be returned as string ## 1.2.0 - 2024-12-03 diff --git a/paddle_billing/Entities/CustomerPortalSession.py b/paddle_billing/Entities/CustomerPortalSession.py index ae9970e..26a6872 100644 --- a/paddle_billing/Entities/CustomerPortalSession.py +++ b/paddle_billing/Entities/CustomerPortalSession.py @@ -9,7 +9,7 @@ @dataclass class CustomerPortalSession(Entity): id: str - customer_id: str | None + customer_id: str urls: CustomerPortalSessionUrls created_at: datetime @@ -17,7 +17,7 @@ class CustomerPortalSession(Entity): def from_dict(data: dict) -> CustomerPortalSession: return CustomerPortalSession( id=data["id"], - customer_id=data.get("customer_id"), + customer_id=data["customer_id"], urls=CustomerPortalSessionUrls.from_dict(data["urls"]), created_at=datetime.fromisoformat(data["created_at"]), ) From d1786aa81a4ee1590908dd7774652bc8f7494255 Mon Sep 17 00:00:00 2001 From: David Grayston Date: Tue, 3 Dec 2024 21:03:26 +0000 Subject: [PATCH 3/3] fix: Notification replay now calls correct endpoint --- CHANGELOG.md | 1 + paddle_billing/Resources/Notifications/NotificationsClient.py | 2 +- .../Resources/Notifications/test_NotificationsClient.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdc8dd1..1a354f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx - Subscription IDs can be omitted when creating customer portal sessions - Customer portal session customer ID will always be returned as string +- `Client.notifications.replay` now calls correct endpoint ## 1.2.0 - 2024-12-03 diff --git a/paddle_billing/Resources/Notifications/NotificationsClient.py b/paddle_billing/Resources/Notifications/NotificationsClient.py index 20c3790..1c5d0a5 100644 --- a/paddle_billing/Resources/Notifications/NotificationsClient.py +++ b/paddle_billing/Resources/Notifications/NotificationsClient.py @@ -34,7 +34,7 @@ def get(self, notification_id: str) -> Notification: return Notification.from_dict(parser.get_data()) def replay(self, notification_id: str) -> str: - self.response = self.client.post_raw(f"/notifications/{notification_id}") + self.response = self.client.post_raw(f"/notifications/{notification_id}/replay") parser = ResponseParser(self.response) data = parser.get_data() diff --git a/tests/Functional/Resources/Notifications/test_NotificationsClient.py b/tests/Functional/Resources/Notifications/test_NotificationsClient.py index 1cec44d..4146a5f 100644 --- a/tests/Functional/Resources/Notifications/test_NotificationsClient.py +++ b/tests/Functional/Resources/Notifications/test_NotificationsClient.py @@ -259,12 +259,12 @@ def test_get_notification_returns_expected_response( 200, ReadsFixtures.read_raw_json_fixture("response/replay"), "ntf_01h46h1s2zabpkdks7yt4vkgkc", - "/notifications/nft_01h8441jn5pcwrfhwh78jqt8hk", + "/notifications/nft_01h8441jn5pcwrfhwh78jqt8hk/replay", ) ], ids=["Replay a notification by its id"], ) - def test_replacy_notification_returns_expected_response( + def test_replay_notification_returns_expected_response( self, test_client, mock_requests,