From cd413de27e7e1dc76e618d0bd887dc940ed34611 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Thu, 13 Sep 2018 18:59:33 +0200 Subject: [PATCH] Integer-index encode all arrays --- stripe/api_requestor.py | 6 +- stripe/api_resources/invoice.py | 3 - stripe/api_resources/order.py | 8 --- stripe/api_resources/subscription.py | 21 +------ stripe/util.py | 10 --- .../abstract/test_api_resource.py | 5 -- tests/api_resources/test_invoice.py | 22 ------- tests/api_resources/test_subscription.py | 61 ------------------- tests/test_api_requestor.py | 16 ++--- tests/test_http_client.py | 4 +- 10 files changed, 14 insertions(+), 142 deletions(-) diff --git a/stripe/api_requestor.py b/stripe/api_requestor.py index 7a9fe1d54..ce622dc3f 100644 --- a/stripe/api_requestor.py +++ b/stripe/api_requestor.py @@ -38,13 +38,13 @@ def _api_encode(data): elif hasattr(value, 'stripe_id'): yield (key, value.stripe_id) elif isinstance(value, list) or isinstance(value, tuple): - for sv in value: + for i, sv in enumerate(value): if isinstance(sv, dict): - subdict = _encode_nested_dict(key, sv, fmt='%s[][%s]') + subdict = _encode_nested_dict("%s[%d]" % (key, i), sv) for k, v in _api_encode(subdict): yield (k, v) else: - yield ("%s[]" % (key,), util.utf8(sv)) + yield ("%s[%d]" % (key, i), util.utf8(sv)) elif isinstance(value, dict): subdict = _encode_nested_dict(key, value) for subkey, subvalue in _api_encode(subdict): diff --git a/stripe/api_resources/invoice.py b/stripe/api_resources/invoice.py index d9ac83811..aa1e15af8 100644 --- a/stripe/api_resources/invoice.py +++ b/stripe/api_resources/invoice.py @@ -19,9 +19,6 @@ def pay(self, idempotency_key=None, **params): @classmethod def upcoming(cls, api_key=None, stripe_version=None, stripe_account=None, **params): - if "subscription_items" in params: - items = util.convert_array_to_dict(params["subscription_items"]) - params["subscription_items"] = items requestor = api_requestor.APIRequestor(api_key, api_version=stripe_version, account=stripe_account) diff --git a/stripe/api_resources/order.py b/stripe/api_resources/order.py index 3bfa8ea1e..f89dd50d1 100644 --- a/stripe/api_resources/order.py +++ b/stripe/api_resources/order.py @@ -10,12 +10,6 @@ class Order(CreateableAPIResource, UpdateableAPIResource, ListableAPIResource): OBJECT_NAME = 'order' - @classmethod - def create(cls, **params): - if "items" in params: - params["items"] = util.convert_array_to_dict(params["items"]) - return super(Order, cls).create(**params) - def pay(self, idempotency_key=None, **params): url = self.instance_url() + '/pay' headers = util.populate_headers(idempotency_key) @@ -23,8 +17,6 @@ def pay(self, idempotency_key=None, **params): return self def return_order(self, idempotency_key=None, **params): - if "items" in params: - params["items"] = util.convert_array_to_dict(params["items"]) headers = util.populate_headers(idempotency_key) return self.request( 'post', self.instance_url() + '/returns', params, headers) diff --git a/stripe/api_resources/subscription.py b/stripe/api_resources/subscription.py index 2a9ca8662..a7cac4dad 100644 --- a/stripe/api_resources/subscription.py +++ b/stripe/api_resources/subscription.py @@ -1,6 +1,6 @@ from __future__ import absolute_import, division, print_function -from stripe import api_requestor, util +from stripe import api_requestor from stripe.api_resources.abstract import CreateableAPIResource from stripe.api_resources.abstract import DeletableAPIResource from stripe.api_resources.abstract import UpdateableAPIResource @@ -18,22 +18,3 @@ def delete_discount(self, **params): url = self.instance_url() + '/discount' _, api_key = requestor.request('delete', url, params) self.refresh_from({'discount': None}, api_key, True) - - @classmethod - def modify(cls, sid, **params): - if "items" in params: - params["items"] = util.convert_array_to_dict(params["items"]) - return super(Subscription, cls).modify(sid, **params) - - @classmethod - def create(cls, **params): - if "items" in params: - params["items"] = util.convert_array_to_dict(params["items"]) - return super(Subscription, cls).create(**params) - - def serialize(self, previous): - updated_params = super(UpdateableAPIResource, self).serialize(previous) - if "items" in updated_params: - updated_params["items"] = util.convert_array_to_dict( - updated_params["items"]) - return updated_params diff --git a/stripe/util.py b/stripe/util.py index 28e98825a..6d9f3bd3f 100644 --- a/stripe/util.py +++ b/stripe/util.py @@ -253,16 +253,6 @@ def convert_to_stripe_object(resp, api_key=None, stripe_version=None, return resp -def convert_array_to_dict(arr): - if isinstance(arr, list): - d = {} - for i, value in enumerate(arr): - d[str(i)] = value - return d - else: - return arr - - def populate_headers(idempotency_key): if idempotency_key is not None: return {"Idempotency-Key": idempotency_key} diff --git a/tests/api_resources/abstract/test_api_resource.py b/tests/api_resources/abstract/test_api_resource.py index aaed8b2f0..b5bad4b74 100644 --- a/tests/api_resources/abstract/test_api_resource.py +++ b/tests/api_resources/abstract/test_api_resource.py @@ -95,11 +95,6 @@ def test_convert_to_stripe_object(self): # TODO: We should probably be stripping out this property # self.assertRaises(AttributeError, getattr, converted.adict, 'object') - def test_convert_array_to_dict(self): - out = stripe.util.convert_array_to_dict([{"foo": "bar"}]) - assert out == {"0": {"foo": "bar"}} - assert stripe.util.convert_array_to_dict({"f": "b"}) == {"f": "b"} - def test_raise_on_incorrect_id_type(self): for obj in [None, 1, 3.14, dict(), list(), set(), tuple(), object()]: with pytest.raises(stripe.error.InvalidRequestError): diff --git a/tests/api_resources/test_invoice.py b/tests/api_resources/test_invoice.py index 40df76f62..bff7c9756 100644 --- a/tests/api_resources/test_invoice.py +++ b/tests/api_resources/test_invoice.py @@ -72,25 +72,3 @@ def test_can_upcoming(self, request_mock): '/v1/invoices/upcoming' ) assert isinstance(resource, stripe.Invoice) - - def test_can_upcoming_and_subscription_items(self, request_mock): - resource = stripe.Invoice.upcoming( - customer="cus_123", - subscription_items=[ - {"plan": "foo", "quantity": 3} - ] - ) - request_mock.assert_requested( - 'get', - '/v1/invoices/upcoming', - { - 'customer': 'cus_123', - 'subscription_items': { - "0": { - "plan": "foo", - "quantity": 3, - }, - }, - }, - ) - assert isinstance(resource, stripe.Invoice) diff --git a/tests/api_resources/test_subscription.py b/tests/api_resources/test_subscription.py index d922393d4..78309dc31 100644 --- a/tests/api_resources/test_subscription.py +++ b/tests/api_resources/test_subscription.py @@ -70,64 +70,3 @@ def test_can_delete_discount(self, request_mock): 'delete', '/v1/subscriptions/%s/discount' % sub.id ) - - # Test create/modify methods with subscription items - - def test_is_creatable_with_items(self, request_mock): - resource = stripe.Subscription.create( - customer='cus_123', - items=[{"plan": "foo", "quantity": 3}] - ) - request_mock.assert_requested( - 'post', - '/v1/subscriptions', - { - 'customer': 'cus_123', - 'items': { - "0": { - "plan": "foo", - "quantity": 3 - }, - }, - }, - ) - assert isinstance(resource, stripe.Subscription) - - def test_is_modifiable_with_items(self, request_mock): - resource = stripe.Subscription.modify( - TEST_RESOURCE_ID, - items=[{"id": "si", "plan": "foo"}] - ) - request_mock.assert_requested( - 'post', - '/v1/subscriptions/%s' % TEST_RESOURCE_ID, - { - 'items': { - "0": { - "plan": "foo", - "id": "si" - }, - }, - }, - ) - assert isinstance(resource, stripe.Subscription) - - def test_is_saveable_with_items(self, request_mock): - resource = stripe.Subscription.retrieve(TEST_RESOURCE_ID) - resource.items = [{"id": "si", "plan": "foo"}] - resource.save() - request_mock.assert_requested( - 'post', - '/v1/subscriptions/%s' % TEST_RESOURCE_ID, - { - 'items': { - "0": { - "plan": "foo", - "id": "si" - }, - }, - }, - ) - assert isinstance(resource, stripe.Subscription) - - # TODO: Test serialize diff --git a/tests/test_api_requestor.py b/tests/test_api_requestor.py index ab1190004..c22090605 100644 --- a/tests/test_api_requestor.py +++ b/tests/test_api_requestor.py @@ -177,15 +177,15 @@ class TestAPIRequestor(object): ('%s[adatetime]', 1356994800), ('%s[adict][foo]', 'bar'), ('%s[adict][boz]', 5), - ('%s[alist][]', 'foo'), - ('%s[alist][]', 'bar'), - ('%s[atuple][]', 1), - ('%s[atuple][]', 2), + ('%s[alist][0]', 'foo'), + ('%s[alist][1]', 'bar'), + ('%s[atuple][0]', 1), + ('%s[atuple][1]', 2), ], 'list': [ - ('%s[]', 1), - ('%s[]', 'foo'), - ('%s[]', 'baz'), + ('%s[0]', 1), + ('%s[1]', 'foo'), + ('%s[2]', 'baz'), ], 'string': [('%s', 'boo')], 'unicode': [('%s', stripe.util.utf8(u'\u1234'))], @@ -347,7 +347,7 @@ def test_methods_with_params_and_response(self, requestor, mock_response, 'adatetime': datetime.datetime(2013, 1, 1, tzinfo=GMT1()) } encoded = ('adict%5Bfrobble%5D=bits&adatetime=1356994800&' - 'alist%5B%5D=1&alist%5B%5D=2&alist%5B%5D=3') + 'alist%5B0%5D=1&alist%5B1%5D=2&alist%5B2%5D=3') resp, key = requestor.request(method, self.valid_path, params) assert isinstance(resp, StripeResponse) diff --git a/tests/test_http_client.py b/tests/test_http_client.py index f58acd434..6bfb981e3 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -680,5 +680,5 @@ def test_encode_array(self): values = [t for t in stripe.api_requestor._api_encode(body)] - assert ('foo[][dob][month]', 1) in values - assert ('foo[][name]', 'bat') in values + assert ('foo[0][dob][month]', 1) in values + assert ('foo[0][name]', 'bat') in values