diff --git a/paddle_billing/Client.py b/paddle_billing/Client.py index e9a5c07..2ea0e18 100644 --- a/paddle_billing/Client.py +++ b/paddle_billing/Client.py @@ -33,6 +33,7 @@ from paddle_billing.Resources.Simulations.SimulationsClient import SimulationsClient from paddle_billing.Resources.SimulationRuns.SimulationRunsClient import SimulationRunsClient from paddle_billing.Resources.SimulationRunEvents.SimulationRunEventsClient import SimulationRunEventsClient +from paddle_billing.Resources.SimulationTypes.SimulationTypesClient import SimulationTypesClient from paddle_billing.Resources.Subscriptions.SubscriptionsClient import SubscriptionsClient from paddle_billing.Resources.Transactions.TransactionsClient import TransactionsClient @@ -82,6 +83,7 @@ def __init__( self.simulations = SimulationsClient(self) self.simulation_runs = SimulationRunsClient(self) self.simulation_run_events = SimulationRunEventsClient(self) + self.simulation_types = SimulationTypesClient(self) self.subscriptions = SubscriptionsClient(self) self.transactions = TransactionsClient(self) self.ip_addresses = IPAddressesClient(self) diff --git a/paddle_billing/Resources/SimulationTypes/SimulationTypesClient.py b/paddle_billing/Resources/SimulationTypes/SimulationTypesClient.py index 8d88ca0..65ada51 100644 --- a/paddle_billing/Resources/SimulationTypes/SimulationTypesClient.py +++ b/paddle_billing/Resources/SimulationTypes/SimulationTypesClient.py @@ -13,7 +13,7 @@ def __init__(self, client: "Client"): self.response = None def list(self) -> SimulationTypeCollection: - self.response = self.client.get_raw("/simulations-types") + self.response = self.client.get_raw("/simulation-types") parser = ResponseParser(self.response) return SimulationTypeCollection.from_list(parser.get_data()) diff --git a/tests/Functional/Resources/SimulationTypes/__init__.py b/tests/Functional/Resources/SimulationTypes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/Functional/Resources/SimulationTypes/_fixtures/response/list_default.json b/tests/Functional/Resources/SimulationTypes/_fixtures/response/list_default.json new file mode 100644 index 0000000..91bbdad --- /dev/null +++ b/tests/Functional/Resources/SimulationTypes/_fixtures/response/list_default.json @@ -0,0 +1,523 @@ +{ + "data": [ + { + "name": "subscription_creation", + "label": "Subscription created from a checkout", + "description": "Occurs when a subscription is created.", + "group": "Subscription", + "type": "scenario", + "events": [ + "transaction.created", + "customer.created", + "address.created", + "transaction.updated", + "transaction.ready", + "transaction.updated", + "transaction.paid", + "subscription.created", + "subscription.activated", + "transaction.updated", + "transaction.updated", + "transaction.completed" + ] + }, + { + "name": "subscription_renewal", + "label": "Subscription renewed successfully", + "description": "Occurs when a subscription is renewed.", + "group": "Subscription", + "type": "scenario", + "events": [ + "subscription.updated", + "transaction.created", + "transaction.billed", + "transaction.updated", + "transaction.paid", + "transaction.updated", + "transaction.completed" + ] + }, + { + "name": "subscription_pause", + "label": "Subscription paused by customer", + "description": "Occurs when a subscription is paused.", + "group": "Subscription", + "type": "scenario", + "events": [ + "subscription.updated", + "subscription.paused" + ] + }, + { + "name": "subscription_resume", + "label": "Subscription resumed after being paused", + "description": "Occurs when a subscription is resumed after being paused.", + "group": "Subscription", + "type": "scenario", + "events": [ + "subscription.updated", + "subscription.resumed", + "transaction.created", + "transaction.billed", + "transaction.updated", + "transaction.paid", + "transaction.updated", + "transaction.completed" + ] + }, + { + "name": "subscription_cancellation", + "label": "Subscription canceled by customer", + "description": "Occurs when a subscription is canceled.", + "group": "Subscription", + "type": "scenario", + "events": [ + "subscription.updated", + "subscription.canceled" + ] + }, + { + "name": "subscription.activated", + "label": "subscription.activated", + "description": "Occurs when a subscription becomes active. Its status field changes to active. This means any trial period has elapsed and Paddle has successfully billed the customer.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.activated" + ] + }, + { + "name": "subscription.canceled", + "label": "subscription.canceled", + "description": "Occurs when a subscription is canceled. Its status field changes to canceled.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.canceled" + ] + }, + { + "name": "subscription.created", + "label": "subscription.created", + "description": "Occurs when a subscription is created. subscription.trialing or subscription.activated typically follow.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.created" + ] + }, + { + "name": "subscription.past_due", + "label": "subscription.past_due", + "description": "Occurs when a subscription has an unpaid transaction. Its status changes to past_due.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.past_due" + ] + }, + { + "name": "subscription.paused", + "label": "subscription.paused", + "description": "Occurs when a subscription is paused. Its status field changes to paused.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.paused" + ] + }, + { + "name": "subscription.resumed", + "label": "subscription.resumed", + "description": "Occurs when a subscription is resumed after being paused. Its status field changes to active.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.resumed" + ] + }, + { + "name": "subscription.trialing", + "label": "subscription.trialing", + "description": "Occurs when a subscription enters trial period.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.trialing" + ] + }, + { + "name": "subscription.updated", + "label": "subscription.updated", + "description": "Occurs when a subscription is updated.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.updated" + ] + }, + { + "name": "subscription.imported", + "label": "subscription.imported", + "description": "Occurs when a subscription is imported.", + "group": "Subscription", + "type": "single_event", + "events": [ + "subscription.imported" + ] + }, + { + "name": "address.created", + "label": "address.created", + "description": "Occurs when an address is created.", + "group": "Address", + "type": "single_event", + "events": [ + "address.created" + ] + }, + { + "name": "address.updated", + "label": "address.updated", + "description": "Occurs when an address is updated.", + "group": "Address", + "type": "single_event", + "events": [ + "address.updated" + ] + }, + { + "name": "address.imported", + "label": "address.imported", + "description": "Occurs when a address is imported.", + "group": "Address", + "type": "single_event", + "events": [ + "address.imported" + ] + }, + { + "name": "adjustment.created", + "label": "adjustment.created", + "description": "Occurs when an adjustment is created.", + "group": "Adjustment", + "type": "single_event", + "events": [ + "adjustment.created" + ] + }, + { + "name": "adjustment.updated", + "label": "adjustment.updated", + "description": "Occurs when an adjustment is updated, the only time an adjustment will be updated is when the status changes from pending to approved or from pending to rejected.", + "group": "Adjustment", + "type": "single_event", + "events": [ + "adjustment.updated" + ] + }, + { + "name": "business.created", + "label": "business.created", + "description": "Occurs when a business is created.", + "group": "Business", + "type": "single_event", + "events": [ + "business.created" + ] + }, + { + "name": "business.updated", + "label": "business.updated", + "description": "Occurs when a business is updated.", + "group": "Business", + "type": "single_event", + "events": [ + "business.updated" + ] + }, + { + "name": "business.imported", + "label": "business.imported", + "description": "Occurs when a business is imported.", + "group": "Business", + "type": "single_event", + "events": [ + "business.imported" + ] + }, + { + "name": "customer.created", + "label": "customer.created", + "description": "Occurs when a customer is created.", + "group": "Customer", + "type": "single_event", + "events": [ + "customer.created" + ] + }, + { + "name": "customer.updated", + "label": "customer.updated", + "description": "Occurs when a customer is updated.", + "group": "Customer", + "type": "single_event", + "events": [ + "customer.updated" + ] + }, + { + "name": "customer.imported", + "label": "customer.imported", + "description": "Occurs when a customer is imported.", + "group": "Customer", + "type": "single_event", + "events": [ + "customer.imported" + ] + }, + { + "name": "payment_method.saved", + "label": "payment_method.saved", + "description": "Occurs when a customer saves a payment method to their account.", + "group": "Payment Method", + "type": "single_event", + "events": [ + "payment_method.saved" + ] + }, + { + "name": "payment_method.deleted", + "label": "payment_method.deleted", + "description": "Occurs when a customer removes a payment method from their account.", + "group": "Payment Method", + "type": "single_event", + "events": [ + "payment_method.deleted" + ] + }, + { + "name": "discount.created", + "label": "discount.created", + "description": "Occurs when a discount is created.", + "group": "Discount", + "type": "single_event", + "events": [ + "discount.created" + ] + }, + { + "name": "discount.updated", + "label": "discount.updated", + "description": "Occurs when a discount is updated.", + "group": "Discount", + "type": "single_event", + "events": [ + "discount.updated" + ] + }, + { + "name": "discount.imported", + "label": "discount.imported", + "description": "Occurs when a discount is imported.", + "group": "Discount", + "type": "single_event", + "events": [ + "discount.imported" + ] + }, + { + "name": "payout.created", + "label": "payout.created", + "description": "Occurs when a payout is created.", + "group": "Payout", + "type": "single_event", + "events": [ + "payout.created" + ] + }, + { + "name": "payout.paid", + "label": "payout.paid", + "description": "Occurs when a payout is paid.", + "group": "Payout", + "type": "single_event", + "events": [ + "payout.paid" + ] + }, + { + "name": "price.created", + "label": "price.created", + "description": "Occurs when a price is created.", + "group": "Price", + "type": "single_event", + "events": [ + "price.created" + ] + }, + { + "name": "price.updated", + "label": "price.updated", + "description": "Occurs when a price is updated.", + "group": "Price", + "type": "single_event", + "events": [ + "price.updated" + ] + }, + { + "name": "price.imported", + "label": "price.imported", + "description": "Occurs when a price is imported.", + "group": "Price", + "type": "single_event", + "events": [ + "price.imported" + ] + }, + { + "name": "product.created", + "label": "product.created", + "description": "Occurs when a product is created.", + "group": "Product", + "type": "single_event", + "events": [ + "product.created" + ] + }, + { + "name": "product.updated", + "label": "product.updated", + "description": "Occurs when a product is updated.", + "group": "Product", + "type": "single_event", + "events": [ + "product.updated" + ] + }, + { + "name": "product.imported", + "label": "product.imported", + "description": "Occurs when a product is imported.", + "group": "Product", + "type": "single_event", + "events": [ + "product.imported" + ] + }, + { + "name": "report.created", + "label": "report.created", + "description": "Occurs when a report is created.", + "group": "Report", + "type": "single_event", + "events": [ + "report.created" + ] + }, + { + "name": "report.updated", + "label": "report.updated", + "description": "Occurs when a report is updated.", + "group": "Report", + "type": "single_event", + "events": [ + "report.updated" + ] + }, + { + "name": "transaction.billed", + "label": "transaction.billed", + "description": "Occurs when a transaction is billed. Its status field changes to billed and billed_at is populated.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.billed" + ] + }, + { + "name": "transaction.canceled", + "label": "transaction.canceled", + "description": "Occurs when a transaction is canceled. Its status field changes to canceled.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.canceled" + ] + }, + { + "name": "transaction.completed", + "label": "transaction.completed", + "description": "Occurs when a transaction is completed. Its status field changes to completed.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.completed" + ] + }, + { + "name": "transaction.created", + "label": "transaction.created", + "description": "Occurs when a transaction is created.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.created" + ] + }, + { + "name": "transaction.paid", + "label": "transaction.paid", + "description": "Occurs when a transaction is paid. Its status field changes to paid.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.paid" + ] + }, + { + "name": "transaction.past_due", + "label": "transaction.past_due", + "description": "Occurs when a transaction becomes past due. Its status field changes to past_due.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.past_due" + ] + }, + { + "name": "transaction.payment_failed", + "label": "transaction.payment_failed", + "description": "Occurs when a payment fails for a transaction. The payments array is updated with details of the payment attempt.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.payment_failed" + ] + }, + { + "name": "transaction.ready", + "label": "transaction.ready", + "description": "Occurs when a transaction is ready to be billed. Its status field changes to ready.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.ready" + ] + }, + { + "name": "transaction.updated", + "label": "transaction.updated", + "description": "Occurs when a transaction is updated.", + "group": "Transaction", + "type": "single_event", + "events": [ + "transaction.updated" + ] + } + ], + "meta": { + "request_id": "76905a23-8206-44ca-8821-7237b26f59d1" + } +} \ No newline at end of file diff --git a/tests/Functional/Resources/SimulationTypes/test_SimulationTypesClient.py b/tests/Functional/Resources/SimulationTypes/test_SimulationTypesClient.py new file mode 100644 index 0000000..2a44024 --- /dev/null +++ b/tests/Functional/Resources/SimulationTypes/test_SimulationTypesClient.py @@ -0,0 +1,68 @@ +from json import loads +from urllib.parse import unquote + +from paddle_billing.Entities.Collections import SimulationTypeCollection +from paddle_billing.Entities.Simulations import SimulationKind +from paddle_billing.Entities.SimulationType import SimulationType + +from tests.Utils.ReadsFixture import ReadsFixtures + + +class TestSimulationTypesClient: + def test_list_simulation_types_returns_expected_response( + self, + test_client, + mock_requests, + ): + expected_path = "/simulation-types" + expected_response_body = ReadsFixtures.read_raw_json_fixture("response/list_default") + + expected_url = f"{test_client.base_url}{expected_path}" + mock_requests.get(expected_url, status_code=200, text=expected_response_body) + + response = test_client.client.simulation_types.list() + response_json = test_client.client.simulation_types.response.json() + last_request = mock_requests.last_request + + assert isinstance(response, SimulationTypeCollection) + assert last_request is not None + assert last_request.method == "GET" + assert test_client.client.status_code == 200 + assert ( + unquote(last_request.url) == expected_url + ), "The URL does not match the expected URL, verify the query string is correct" + assert response_json == loads( + str(expected_response_body) + ), "The response JSON generated by ResponseParser() doesn't match the expected fixture JSON" + + assert len(response.items) == 49 + + first_simulation_type = response.items[0] + assert isinstance(first_simulation_type, SimulationType) + assert first_simulation_type.type == SimulationKind.Scenario + assert first_simulation_type.name == "subscription_creation" + assert first_simulation_type.label == "Subscription created from a checkout" + assert first_simulation_type.group == "Subscription" + assert len(first_simulation_type.events) == 12 + assert first_simulation_type.events == [ + "transaction.created", + "customer.created", + "address.created", + "transaction.updated", + "transaction.ready", + "transaction.updated", + "transaction.paid", + "subscription.created", + "subscription.activated", + "transaction.updated", + "transaction.updated", + "transaction.completed", + ] + + for simulation_type in response.items: + assert isinstance(simulation_type, SimulationType) + assert isinstance(simulation_type.type, SimulationKind) + assert simulation_type.name, "Simulation Type has no name" + assert simulation_type.label, "Simulation Type has no label" + assert simulation_type.group, "Simulation Type has no group" + assert len(simulation_type.events) > 0