Skip to content

Commit

Permalink
Test deeply nested lists too
Browse files Browse the repository at this point in the history
https://docs.mollie.com/reference/v2/subscriptions-api/list-subscription-payments
shows what we would call customer subscription payments. These are nested 2 layers deep.
  • Loading branch information
Tom Hendrikx committed Jun 22, 2023
1 parent be0df84 commit f13f820
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 15 deletions.
9 changes: 7 additions & 2 deletions mollie/api/objects/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,10 @@ def payments(self):
# the explicit interface using .payments.list()
from ..resources import SubscriptionPayments

customer = Customer({"id": self.customer_id}, self.client)
return SubscriptionPayments(self.client, customer=customer, subscription=self)
url = self._get_link("payments")
return SubscriptionPayments(self.client, resource_path=url)

# Additional methods

def has_payments(self):
return self._get_link("payments") is not None
12 changes: 1 addition & 11 deletions mollie/api/resources/payments.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from ..objects.order import Order
from ..objects.payment import Payment
from ..objects.profile import Profile
from ..objects.subscription import Subscription
from .base import (
ResourceBase,
ResourceCreateMixin,
Expand Down Expand Up @@ -109,16 +108,7 @@ def get_resource_path(self) -> str:
class SubscriptionPayments(PaymentsBase, ResourceListMixin):
"""Resource handler for the `/customers/:customer_id:/subscriptions/:subscription_id:/payments` endpoint."""

_customer: Customer
_subscription: Subscription

def __init__(self, client: "Client", customer: Customer, subscription: Subscription) -> None:
self._customer = customer
self._subscription = subscription
super().__init__(client)

def get_resource_path(self) -> str:
return f"customers/{self._customer.id}/subscriptions/{self._subscription.id}/payments"
pass


class SettlementPayments(PaymentsBase, ResourceListMixin):
Expand Down
78 changes: 78 additions & 0 deletions tests/responses/customer_subscription_payments_multiple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"_embedded":{
"payments":[
{
"resource":"payment",
"id":"tr_DtKxVP2AgW",
"mode":"live",
"createdA":"2018-09-19T12:49:52+00:00",
"amount":{
"value":"10.00",
"currency":"EUR"
},
"description":"Some subscription 19 sep. 2018",
"method":"directdebit",
"metadata":null,
"status":"pending",
"isCancelable":true,
"expiresAt":"2019-09-19T12:49:52+00:00",
"locale":"nl_NL",
"profileId":"pfl_rH9rQtedgS",
"customerId":"cst_8wmqcHMN4x",
"mandateId":"mdt_aGQNkteF6w",
"subscriptionId":"sub_rVKGtNd6s3",
"sequenceType":"recurring",
"redirectUrl":null,
"webhookUrl":"https://example.org/webhook",
"settlementAmount":{
"value":"10.00",
"currency":"EUR"
},
"details":{
"transferReference":"SD67-6850-2204-6029",
"creditorIdentifier":"NL08ZZZ502057730000",
"consumerName":"Customer A",
"consumerAccount":"NL50INGB0006588912",
"consumerBic":"INGBNL2A",
"dueDate":"2018-09-21",
"signatureDate":"2018-09-19"
},
"_links":{
"self":{
"href":"https://api.mollie.com/v2/payments/tr_DtKxVP2AgW",
"type":"application/hal+json"
},
"checkout":null,
"customer":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x",
"type":"application/hal+json"
},
"mandate":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x/mandates/mdt_aGQNkteF6w",
"type":"application/hal+json"
},
"subscription":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x/subscriptions/sub_rVKGtNd6s3",
"type":"application/hal+json"
}
}
}
]
},
"count":1,
"_links":{
"documentation":{
"href":"https://docs.mollie.com/reference/v2/subscriptions-api/list-subscription-payments",
"type":"text/html"
},
"self":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments?limit=1",
"type":"application/hal+json"
},
"previous":null,
"next": {
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments?limit=1&from=tr_DtKxVP2AgX",
"type":"application/hal+json"
}
}
}
78 changes: 78 additions & 0 deletions tests/responses/customer_subscription_payments_multiple_p2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"_embedded":{
"payments":[
{
"resource":"payment",
"id":"tr_DtKxVP2AgW",
"mode":"live",
"createdA":"2018-09-19T12:49:52+00:00",
"amount":{
"value":"10.00",
"currency":"EUR"
},
"description":"Some subscription 19 sep. 2018",
"method":"directdebit",
"metadata":null,
"status":"pending",
"isCancelable":true,
"expiresAt":"2019-09-19T12:49:52+00:00",
"locale":"nl_NL",
"profileId":"pfl_rH9rQtedgS",
"customerId":"cst_8wmqcHMN4x",
"mandateId":"mdt_aGQNkteF6w",
"subscriptionId":"sub_rVKGtNd6s3",
"sequenceType":"recurring",
"redirectUrl":null,
"webhookUrl":"https://example.org/webhook",
"settlementAmount":{
"value":"10.00",
"currency":"EUR"
},
"details":{
"transferReference":"SD67-6850-2204-6029",
"creditorIdentifier":"NL08ZZZ502057730000",
"consumerName":"Customer A",
"consumerAccount":"NL50INGB0006588912",
"consumerBic":"INGBNL2A",
"dueDate":"2018-09-21",
"signatureDate":"2018-09-19"
},
"_links":{
"self":{
"href":"https://api.mollie.com/v2/payments/tr_DtKxVP2AgW",
"type":"application/hal+json"
},
"checkout":null,
"customer":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x",
"type":"application/hal+json"
},
"mandate":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x/mandates/mdt_aGQNkteF6w",
"type":"application/hal+json"
},
"subscription":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4x/subscriptions/sub_rVKGtNd6s3",
"type":"application/hal+json"
}
}
}
]
},
"count":1,
"_links":{
"documentation":{
"href":"https://docs.mollie.com/reference/v2/subscriptions-api/list-subscription-payments",
"type":"text/html"
},
"self":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments?limit=1",
"type":"application/hal+json"
},
"previous":{
"href":"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments?limit=&1from=tr_DtKxVP2AgX",
"type":"application/hal+json"
},
"next":null
}
}
4 changes: 4 additions & 0 deletions tests/responses/subscription_single.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
"href": "https://api.mollie.com/v2/profiles/pfl_v9hTwCvYqw",
"type": "application/hal+json"
},
"payments": {
"href": "https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments",
"type": "application/hal+json"
},
"documentation": {
"href": "https://docs.mollie.com/reference/v2/subscriptions-api/get-subscription",
"type": "text/html"
Expand Down
5 changes: 4 additions & 1 deletion tests/test_customer_subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def test_get_customer_subscription(client, response):
assert subscription.is_pending() is False
assert subscription.is_completed() is False
assert subscription.is_canceled() is False
assert subscription.has_payments() is True


def test_get_customer_subscription_invalid_id(client, response):
Expand Down Expand Up @@ -197,9 +198,11 @@ def test_customer_subscription_get_related_payments(client, response):
)
response.get(
f"https://api.mollie.com/v2/customers/{CUSTOMER_ID}/subscriptions/{SUBSCRIPTION_ID}/payments",
"payments_list",
"customer_subscription_payments_multiple",
)
customer = client.customers.get(CUSTOMER_ID)
subscription = customer.subscriptions.get(SUBSCRIPTION_ID)

assert subscription.has_payments() is True
payments = subscription.payments.list()
assert_list_object(payments, Payment)
37 changes: 37 additions & 0 deletions tests/test_list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pytest
from responses import matchers

from mollie.api.objects.list import ObjectList
from mollie.api.objects.method import Method
from mollie.api.objects.payment import Payment
from mollie.api.objects.subscription import Subscription

from .utils import assert_list_object
Expand Down Expand Up @@ -176,3 +178,38 @@ def test_list_nested_objects(client, response):
assert subscriptions.has_next() is True
next_subscriptions = subscriptions.get_next()
assert_list_object(next_subscriptions, Subscription, 2)


def test_list_deep_nested_objects(client, response):
"""
Resources like SubscriptionPayments manage data two levels deep.
The URL for a subscription payment has 2 parent parameters:
https://api.mollie.com/v2/customers/*customerId*/subscriptions/*subscriptionId*/payments
"""

response.get("https://api.mollie.com/v2/customers/cst_8wmqcHMN4U", "customer_single")
response.get(
"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3", "subscription_single"
)
response.get(
"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments",
"customer_subscription_payments_multiple",
)
response.get(
"https://api.mollie.com/v2/customers/cst_8wmqcHMN4U/subscriptions/sub_rVKGtNd6s3/payments",
"customer_subscription_payments_multiple_p2",
match=[matchers.query_param_matcher({"limit": 1, "from": "tr_DtKxVP2AgX"})],
)

customer = client.customers.get("cst_8wmqcHMN4U")
assert customer.id == "cst_8wmqcHMN4U"
subscription = customer.subscriptions.get("sub_rVKGtNd6s3")

assert subscription.has_payments() is True
payments = subscription.payments.list()
assert_list_object(payments, Payment)

assert payments.has_next() is True
more_payments = payments.get_next()
assert_list_object(more_payments, Payment)
2 changes: 1 addition & 1 deletion tests/test_subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .utils import assert_list_object


def test_list_customers(client, response):
def test_list_subscriptions(client, response):
"""Retrieve a list of existing subscriptions."""
response.get("https://api.mollie.com/v2/subscriptions", "subscriptions_list")

Expand Down

0 comments on commit f13f820

Please sign in to comment.