Skip to content

Commit

Permalink
Fix issue where auto_paging_iter failed on nested list objects. (#855)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcr-stripe authored Aug 3, 2022
1 parent 37a564b commit c637f2d
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 25 deletions.
9 changes: 7 additions & 2 deletions stripe/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,13 @@ def convert_to_stripe_object(
last_response=stripe_response,
)

if hasattr(obj, "object") and (
(obj.object == "list") or (obj.object == "search_result")
# We only need to update _retrieve_params when special params were
# actually passed. Otherwise, leave it as is as the list / search result
# constructors will instantiate their own params.
if (
params is not None
and hasattr(obj, "object")
and ((obj.object == "list") or (obj.object == "search_result"))
):
obj._retrieve_params = params

Expand Down
8 changes: 8 additions & 0 deletions tests/api_resources/test_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,11 @@ def test_can_void_invoice_classmethod(self, request_mock):
"post", "/v1/invoices/%s/void" % TEST_RESOURCE_ID
)
assert isinstance(resource, stripe.Invoice)

def test_can_iterate_lines(self, request_mock):
resource = stripe.Invoice.retrieve(TEST_RESOURCE_ID)
assert isinstance(resource.lines.data, list)
assert isinstance(resource.lines.data[0], stripe.InvoiceLineItem)
seen = [item["id"] for item in resource.lines.auto_paging_iter()]

assert seen.__len__() > 0
100 changes: 77 additions & 23 deletions tests/test_stripe_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,60 @@
"subtotal": 10000,
"total": 10000,
"lines": {
"invoiceitems": [],
"prorations": [],
"subscriptions": [
"object": "list",
"data": [
{
"plan": {
"interval": "month",
"object": "plan",
"identifier": "expensive",
"id": "il_1LSiex2eZvKYlo2CZ5IspTNx",
"object": "line_item",
"amount": 2499,
"amount_excluding_tax": 2499,
"currency": "usd",
"description": "My First Invoice Item (created for API docs)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"invoice_item": "ii_1LSiex2eZvKYlo2C0X4adTLR",
"livemode": false,
"metadata": {},
"period": {
"end": 1659537295,
"start": 1659537295
},
"price": {
"id": "price_1LSicu2eZvKYlo2C4WSIaXEp",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1659537168,
"currency": "usd",
"custom_unit_amount": null,
"livemode": false,
"amount": 10000,
"name": "Expensive Plan",
"trial_period_days": null,
"id": "expensive"
"lookup_key": null,
"metadata": {},
"nickname": null,
"product": "prod_MB4mvosUV5tObf",
"recurring": null,
"tax_behavior": "unspecified",
"tiers_mode": null,
"transform_quantity": null,
"type": "one_time",
"unit_amount": 2499,
"unit_amount_decimal": "2499"
},
"period": {
"end": 1340917128,
"start": 1338238728
"proration": false,
"proration_details": {
"credited_items": null
},
"amount": 10000
"quantity": 1,
"subscription": null,
"tax_amounts": [],
"tax_rates": [],
"type": "invoiceitem",
"unit_amount_excluding_tax": "2499"
}
]
],
"has_more": false,
"url": "/v1/invoices/in_t9mHb2hpK7mml1/lines"
}
}
"""
Expand Down Expand Up @@ -157,11 +189,32 @@ def test_refresh_from_nested_object(self):
SAMPLE_INVOICE, "key"
)

assert len(obj.lines.subscriptions) == 1
assert len(obj.lines) == 1
assert isinstance(obj.lines, stripe.ListObject)
assert isinstance(obj.lines.data[0], stripe.InvoiceLineItem)
assert isinstance(
obj.lines.subscriptions[0], stripe.stripe_object.StripeObject
obj.lines.data[0].price, stripe.stripe_object.StripeObject
)
assert isinstance(obj.lines.data[0].price, stripe.Price)
assert obj.lines.data[0].price.billing_scheme == "per_unit"

def test_refresh_from_nested_object_can_be_paged(self):
obj = stripe.stripe_object.StripeObject.construct_from(
SAMPLE_INVOICE, "key"
)
assert obj.lines.subscriptions[0].plan.interval == "month"

assert len(obj.lines) == 1
assert isinstance(obj.lines, stripe.ListObject)
seen = [item["id"] for item in obj.lines.auto_paging_iter()]

assert seen == ["il_1LSiex2eZvKYlo2CZ5IspTNx"]

assert isinstance(obj.lines.data[0], stripe.InvoiceLineItem)
assert isinstance(
obj.lines.data[0].price, stripe.stripe_object.StripeObject
)
assert isinstance(obj.lines.data[0].price, stripe.Price)
assert obj.lines.data[0].price.billing_scheme == "per_unit"

def test_to_json(self):
obj = stripe.stripe_object.StripeObject.construct_from(
Expand All @@ -173,15 +226,16 @@ def test_to_json(self):
def check_invoice_data(self, data):
# Check rough structure
assert len(list(data.keys())) == 20
assert len(list(data["lines"].keys())) == 3
assert len(data["lines"]["invoiceitems"]) == 0
assert len(data["lines"]["subscriptions"]) == 1
assert len(list(data["lines"]["data"][0].keys())) == 22
assert len(data["lines"]["data"]) == 1

# Check various data types
assert data["date"] == 1338238728
assert data["next_payment_attempt"] is None
assert data["livemode"] is False
assert data["lines"]["subscriptions"][0]["plan"]["interval"] == "month"
assert (
data["lines"]["data"][0]["price"]["billing_scheme"] == "per_unit"
)

def test_repr(self):
obj = stripe.stripe_object.StripeObject("foo", "bar", myparam=5)
Expand Down

0 comments on commit c637f2d

Please sign in to comment.