From 6b8f0d8e8b7440ba5f53b114c83185fab1c87273 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Fri, 5 Jan 2018 11:22:59 +0100 Subject: [PATCH 1/7] Drop support for Python 2.6 and 3.3 --- .travis.yml | 2 -- README.md | 2 +- setup.py | 4 ---- stripe/importer.py | 18 ------------------ stripe/util.py | 35 +++-------------------------------- tox.ini | 2 +- 6 files changed, 5 insertions(+), 58 deletions(-) delete mode 100644 stripe/importer.py diff --git a/.travis.yml b/.travis.yml index be93bf364..609a65005 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,7 @@ sudo: false language: python python: - - "2.6" - "2.7" - - "3.3" - "3.4" - "3.5" - "3.6" diff --git a/README.md b/README.md index 7e4bcbaef..fe89373c3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Install from source with: ### Requirements -* Python 2.6+ or Python 3.3+ (PyPy supported) +* Python 2.7+ or Python 3.4+ (PyPy supported) ## Usage diff --git a/setup.py b/setup.py index 62a08cc9c..ca4e2f1fc 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ import os import sys -import warnings try: from setuptools import setup @@ -11,7 +10,6 @@ path, script = os.path.split(sys.argv[0]) os.chdir(os.path.abspath(path)) - with open('LONG_DESCRIPTION.rst') as f: long_description = f.read() @@ -51,10 +49,8 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", diff --git a/stripe/importer.py b/stripe/importer.py deleted file mode 100644 index 79ebcc62a..000000000 --- a/stripe/importer.py +++ /dev/null @@ -1,18 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import warnings - -warnings.warn("The importers module is deprecated and will be removed in " - "version 2.0. Check the `util` module for json imports", - DeprecationWarning) - - -def import_json(): - warnings.warn( - "'import_json function is deprecated and will be removed in version " - "2.0 of the Stripe python bindings. Please use" - "`from importer import json` instead'", - DeprecationWarning) - - from stripe.util import json - return json diff --git a/stripe/util.py b/stripe/util.py index 493a1c17b..ee50a8899 100644 --- a/stripe/util.py +++ b/stripe/util.py @@ -2,6 +2,7 @@ import hmac import io +import json import logging import sys import os @@ -9,6 +10,8 @@ import stripe from stripe import six +from stripe.six.moves.urllib.parse import parse_qsl + STRIPE_LOG = os.environ.get('STRIPE_LOG') @@ -25,38 +28,6 @@ 'logfmt', ] -try: - from stripe.six.moves.urllib.parse import parse_qsl -except ImportError: - # Python < 2.6 - from cgi import parse_qsl - -try: - import json -except ImportError: - json = None - -if not (json and hasattr(json, 'loads')): - try: - import simplejson as json - except ImportError: - if not json: - raise ImportError( - "Stripe requires a JSON library, such as simplejson. " - "HINT: Try installing the " - "python simplejson library via 'pip install simplejson' or " - "'easy_install simplejson', or contact support@stripe.com " - "with questions.") - else: - raise ImportError( - "Stripe requires a JSON library with the same interface as " - "the Python 2.6 'json' library. You appear to have a 'json' " - "library with a different interface. Please install " - "the simplejson library. HINT: Try installing the " - "python simplejson library via 'pip install simplejson' " - "or 'easy_install simplejson', or contact support@stripe.com" - "with questions.") - def utf8(value): if six.PY2 and isinstance(value, six.text_type): diff --git a/tox.ini b/tox.ini index 697d21011..d3ad5269c 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, pypy, pypy3.3-5.2-alpha1, py33, py34, py35, py36 +envlist = py27, py34, py35, py36, pypy, pypy3 [testenv] deps = From 926fcc5dc0159d139e8d53d25a4b43d2bb2dd131 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Sat, 23 Dec 2017 17:14:50 +0100 Subject: [PATCH 2/7] Use pytest for tests --- .gitignore | 1 + .travis.yml | 4 +- README.md | 8 +- setup.cfg | 3 + setup.py | 11 +- stripe/http_client.py | 1 + .../abstract/test_api_resource.py | 62 +- .../abstract/test_createable_api_resource.py | 40 +- .../abstract/test_deletable_api_resource.py | 26 +- .../abstract/test_listable_api_resource.py | 30 +- .../test_nested_resource_class_methods.py | 43 +- .../abstract/test_singleton_api_resource.py | 24 +- .../abstract/test_updateable_api_resource.py | 210 +++---- tests/api_resources/test_account.py | 113 ++-- tests/api_resources/test_alipay_account.py | 29 +- tests/api_resources/test_apple_pay_domain.py | 29 +- tests/api_resources/test_application_fee.py | 49 +- .../test_application_fee_refund.py | 17 +- tests/api_resources/test_balance.py | 9 +- .../api_resources/test_balance_transaction.py | 11 +- tests/api_resources/test_bank_account.py | 35 +- tests/api_resources/test_bitcoin_receiver.py | 55 +- tests/api_resources/test_card.py | 35 +- tests/api_resources/test_charge.py | 71 ++- tests/api_resources/test_country_spec.py | 17 +- tests/api_resources/test_coupon.py | 39 +- tests/api_resources/test_customer.py | 193 ++++--- tests/api_resources/test_dispute.py | 31 +- tests/api_resources/test_ephemeral_key.py | 34 +- tests/api_resources/test_event.py | 17 +- tests/api_resources/test_exchange_rate.py | 17 +- tests/api_resources/test_file_upload.py | 47 +- tests/api_resources/test_invoice.py | 51 +- .../api_resources/test_issuer_fraud_record.py | 19 +- tests/api_resources/test_list_object.py | 93 ++- tests/api_resources/test_order.py | 47 +- tests/api_resources/test_order_return.py | 17 +- tests/api_resources/test_payment_intent.py | 57 +- tests/api_resources/test_payout.py | 39 +- tests/api_resources/test_plan.py | 39 +- tests/api_resources/test_product.py | 39 +- tests/api_resources/test_recipient.py | 47 +- tests/api_resources/test_refund.py | 33 +- tests/api_resources/test_reversal.py | 25 +- tests/api_resources/test_sku.py | 39 +- tests/api_resources/test_source.py | 47 +- .../api_resources/test_source_transaction.py | 13 +- tests/api_resources/test_subscription.py | 59 +- tests/api_resources/test_subscription_item.py | 37 +- tests/api_resources/test_three_d_secure.py | 15 +- tests/api_resources/test_topup.py | 35 +- tests/api_resources/test_transfer.py | 69 ++- tests/api_resources/test_usage_record.py | 13 +- tests/conftest.py | 62 ++ tests/helper.py | 78 --- tests/request_mock.py | 40 +- tests/test_api_requestor.py | 368 ++++++------ tests/test_error.py | 55 +- tests/test_http_client.py | 534 +++++++++--------- tests/test_multipart_data_generator.py | 26 +- tests/test_oauth.py | 41 +- tests/test_stripe_object.py | 161 +++--- tests/test_stripe_response.py | 37 +- tests/test_util.py | 129 ++--- tests/test_webhook.py | 98 ++-- tox.ini | 10 +- 66 files changed, 1854 insertions(+), 1929 deletions(-) create mode 100644 tests/conftest.py delete mode 100644 tests/helper.py diff --git a/.gitignore b/.gitignore index af2c7fe58..934eeb506 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ .tox/ .coverage .cache +.pytest_cache nosetests.xml coverage.xml htmlcov/ diff --git a/.travis.yml b/.travis.yml index 609a65005..1e06fda89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,13 +42,13 @@ before_install: install: - pip install -U setuptools pip - - pip install unittest2 mock pycurl flake8 tox-travis coveralls + - pip install pycurl flake8 coveralls - python setup.py clean --all - python setup.py install script: - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then flake8 stripe tests; fi - - python -W all -bb -W error::BytesWarning -m coverage.__main__ run setup.py test + - python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe" after_success: coveralls diff --git a/README.md b/README.md index fe89373c3..138937872 100644 --- a/README.md +++ b/README.md @@ -152,13 +152,17 @@ Run all tests (modify `-e` according to your Python target): tox -e py27 +Run all tests in a single file: + + tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py + Run a single test suite: - tox -e py27 -- --test-suite tests.api_resources.abstract.test_updateable_api_resource.UpdateableAPIResourceTests + tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource Run a single test: - tox -e py27 -- --test-suite tests.api_resources.abstract.test_updateable_api_resource.UpdateableAPIResourceTests.test_save + tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource::test_save Run the linter with: diff --git a/setup.cfg b/setup.cfg index ed8a958e0..3caebad48 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,6 @@ +[aliases] +test=pytest + [bdist_wheel] universal = 1 diff --git a/setup.py b/setup.py index ca4e2f1fc..2b604a620 100644 --- a/setup.py +++ b/setup.py @@ -37,11 +37,12 @@ install_requires=[ 'requests >= 0.8.8', ], - test_suite='tests', - tests_require=tests_require, - extras_require={ - 'testing': tests_require, - }, + setup_requires=['pytest-runner'], + tests_require=[ + 'pytest >= 3.4', + 'pytest-mock >= 1.7', + 'pytest-cov >= 2.5', + ], classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", diff --git a/stripe/http_client.py b/stripe/http_client.py index a5d6c2f6d..f0a590c53 100644 --- a/stripe/http_client.py +++ b/stripe/http_client.py @@ -166,6 +166,7 @@ def _handle_request_error(self, e): def close(self): if self._session is not None: + print("closing!") self._session.close() diff --git a/tests/api_resources/abstract/test_api_resource.py b/tests/api_resources/abstract/test_api_resource.py index 4af7e0fe4..779edf2f3 100644 --- a/tests/api_resources/abstract/test_api_resource.py +++ b/tests/api_resources/abstract/test_api_resource.py @@ -1,18 +1,17 @@ from __future__ import absolute_import, division, print_function -import stripe -from tests.helper import StripeTestCase - +import pytest -class MyResource(stripe.api_resources.abstract.APIResource): - pass +import stripe -class APIResourceTests(StripeTestCase): +class TestAPIResource(object): + class MyResource(stripe.api_resources.abstract.APIResource): + pass - def test_retrieve_and_refresh(self): + def test_retrieve_and_refresh(self, request_mock): url = '/v1/myresources/foo%2A' - self.stub_request( + request_mock.stub_request( 'get', url, { @@ -22,9 +21,9 @@ def test_retrieve_and_refresh(self): rheaders={'request-id': 'req_id'} ) - res = MyResource.retrieve('foo*', myparam=5) + res = self.MyResource.retrieve('foo*', myparam=5) - self.assert_requested( + request_mock.assert_requested( 'get', url, { @@ -32,15 +31,15 @@ def test_retrieve_and_refresh(self): }, None ) - self.assertEqual('scrobble', res.bobble) - self.assertEqual('foo2', res.id) - self.assertEqual('sk_test_123', res.api_key) + assert res.bobble == 'scrobble' + assert res.id == 'foo2' + assert res.api_key == 'sk_test_123' - self.assertTrue(res.last_response is not None) - self.assertEqual('req_id', res.last_response.request_id) + assert res.last_response is not None + assert res.last_response.request_id == 'req_id' url = '/v1/myresources/foo2' - self.stub_request( + request_mock.stub_request( 'get', url, { @@ -50,7 +49,7 @@ def test_retrieve_and_refresh(self): res = res.refresh() - self.assert_requested( + request_mock.assert_requested( 'get', url, { @@ -58,8 +57,9 @@ def test_retrieve_and_refresh(self): }, None ) - self.assertEqual(5, res.frobble) - self.assertRaises(KeyError, res.__getitem__, 'bobble') + assert res.frobble == 5 + with pytest.raises(KeyError): + res['bobble'] def test_convert_to_stripe_object(self): sample = { @@ -81,16 +81,15 @@ def test_convert_to_stripe_object(self): sample, 'akey', None, None) # Types - self.assertTrue(isinstance(converted, - stripe.stripe_object.StripeObject)) - self.assertTrue(isinstance(converted.adict, stripe.Charge)) - self.assertEqual(1, len(converted.alist)) - self.assertTrue(isinstance(converted.alist[0], stripe.Customer)) + assert isinstance(converted, stripe.stripe_object.StripeObject) + assert isinstance(converted.adict, stripe.Charge) + assert len(converted.alist) == 1 + assert isinstance(converted.alist[0], stripe.Customer) # Values - self.assertEqual('bar', converted.foo) - self.assertEqual(42, converted.adict.id) - self.assertEqual('chilango', converted.alist[0].name) + assert converted.foo == 'bar' + assert converted.adict.id == 42 + assert converted.alist[0].name == 'chilango' # Stripping # TODO: We should probably be stripping out this property @@ -98,11 +97,10 @@ def test_convert_to_stripe_object(self): def test_convert_array_to_dict(self): out = stripe.util.convert_array_to_dict([{"foo": "bar"}]) - self.assertEqual({"0": {"foo": "bar"}}, out) - self.assertEqual({"f": "b"}, - stripe.util.convert_array_to_dict({"f": "b"})) + 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()]: - self.assertRaises(stripe.error.InvalidRequestError, - MyResource.retrieve, obj) + with pytest.raises(stripe.error.InvalidRequestError): + self.MyResource.retrieve(obj) diff --git a/tests/api_resources/abstract/test_createable_api_resource.py b/tests/api_resources/abstract/test_createable_api_resource.py index 1da40be98..5b2c7c676 100644 --- a/tests/api_resources/abstract/test_createable_api_resource.py +++ b/tests/api_resources/abstract/test_createable_api_resource.py @@ -1,17 +1,14 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class MyCreatable(stripe.api_resources.abstract.CreateableAPIResource): - pass +class TestCreateableAPIResource(object): + class MyCreatable(stripe.api_resources.abstract.CreateableAPIResource): + pass - -class CreateableAPIResourceTests(StripeTestCase): - - def test_create(self): - self.stub_request( + def test_create(self, request_mock): + request_mock.stub_request( 'post', '/v1/mycreatables', { @@ -21,21 +18,21 @@ def test_create(self): rheaders={'request-id': 'req_id'} ) - res = MyCreatable.create() + res = self.MyCreatable.create() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/mycreatables', {} ) - self.assertTrue(isinstance(res, stripe.Charge)) - self.assertEqual('bar', res.foo) + assert isinstance(res, stripe.Charge) + assert res.foo == 'bar' - self.assertTrue(res.last_response is not None) - self.assertEqual('req_id', res.last_response.request_id) + assert res.last_response is not None + assert res.last_response.request_id == 'req_id' - def test_idempotent_create(self): - self.stub_request( + def test_idempotent_create(self, request_mock): + request_mock.stub_request( 'post', '/v1/mycreatables', { @@ -45,16 +42,13 @@ def test_idempotent_create(self): rheaders={'idempotency-key': 'foo'} ) - res = MyCreatable.create(idempotency_key='foo') + res = self.MyCreatable.create(idempotency_key='foo') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/mycreatables', {}, {'Idempotency-Key': 'foo'} ) - self.assertTrue(isinstance(res, stripe.Charge)) - self.assertEqual('bar', res.foo) - - self.assertTrue(res.last_response is not None) - self.assertEqual('foo', res.last_response.idempotency_key) + assert isinstance(res, stripe.Charge) + assert res.foo == 'bar' diff --git a/tests/api_resources/abstract/test_deletable_api_resource.py b/tests/api_resources/abstract/test_deletable_api_resource.py index 87568a541..155845d3c 100644 --- a/tests/api_resources/abstract/test_deletable_api_resource.py +++ b/tests/api_resources/abstract/test_deletable_api_resource.py @@ -1,16 +1,14 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class MyDeletable(stripe.api_resources.abstract.DeletableAPIResource): - pass +class TestDeletableAPIResource(object): + class MyDeletable(stripe.api_resources.abstract.DeletableAPIResource): + pass - -class DeletableAPIResourceTests(StripeTestCase): - def test_delete(self): - self.stub_request( + def test_delete(self, request_mock): + request_mock.stub_request( 'delete', '/v1/mydeletables/mid', { @@ -20,18 +18,18 @@ def test_delete(self): rheaders={'request-id': 'req_id'} ) - obj = MyDeletable.construct_from({ + obj = self.MyDeletable.construct_from({ 'id': 'mid' }, 'mykey') - self.assertTrue(obj is obj.delete()) - self.assert_requested( + assert obj is obj.delete() + request_mock.assert_requested( 'delete', '/v1/mydeletables/mid', {} ) - self.assertEqual(True, obj.deleted) - self.assertEqual('mid', obj.id) + assert obj.deleted is True + assert obj.id == 'mid' - self.assertTrue(obj.last_response is not None) - self.assertEqual('req_id', obj.last_response.request_id) + assert obj.last_response is not None + assert obj.last_response.request_id == 'req_id' diff --git a/tests/api_resources/abstract/test_listable_api_resource.py b/tests/api_resources/abstract/test_listable_api_resource.py index 585e15880..da618b097 100644 --- a/tests/api_resources/abstract/test_listable_api_resource.py +++ b/tests/api_resources/abstract/test_listable_api_resource.py @@ -1,17 +1,14 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class MyListable(stripe.api_resources.abstract.ListableAPIResource): - pass +class TestListableAPIResource(object): + class MyListable(stripe.api_resources.abstract.ListableAPIResource): + pass - -class ListableAPIResourceTests(StripeTestCase): - - def test_all(self): - self.stub_request( + def test_all(self, request_mock): + request_mock.stub_request( 'get', '/v1/mylistables', { @@ -32,17 +29,16 @@ def test_all(self): rheaders={'request-id': 'req_id'} ) - res = MyListable.list() - self.assert_requested( + res = self.MyListable.list() + request_mock.assert_requested( 'get', '/v1/mylistables', {} ) - self.assertEqual(2, len(res.data)) - self.assertTrue(all(isinstance(obj, stripe.Charge) - for obj in res.data)) - self.assertEqual('jose', res.data[0].name) - self.assertEqual('curly', res.data[1].name) + assert len(res.data) == 2 + assert all(isinstance(obj, stripe.Charge) for obj in res.data) + assert res.data[0].name == 'jose' + assert res.data[1].name == 'curly' - self.assertTrue(res.last_response is not None) - self.assertEqual('req_id', res.last_response.request_id) + assert res.last_response is not None + assert res.last_response.request_id == 'req_id' diff --git a/tests/api_resources/abstract/test_nested_resource_class_methods.py b/tests/api_resources/abstract/test_nested_resource_class_methods.py index b312e7a59..24f93691b 100644 --- a/tests/api_resources/abstract/test_nested_resource_class_methods.py +++ b/tests/api_resources/abstract/test_nested_resource_class_methods.py @@ -1,10 +1,9 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class NestedResourceClassMethodsTests(StripeTestCase): +class TestNestedResourceClassMethods(object): @stripe.api_resources.abstract.nested_resource_class_methods( 'nested', operations=['create', 'retrieve', 'update', 'delete', 'list'] @@ -12,8 +11,8 @@ class NestedResourceClassMethodsTests(StripeTestCase): class MainResource(stripe.api_resources.abstract.APIResource): pass - def test_create_nested(self): - self.stub_request( + def test_create_nested(self, request_mock): + request_mock.stub_request( 'post', '/v1/mainresources/id/nesteds', { @@ -23,7 +22,7 @@ def test_create_nested(self): } ) nested_resource = self.MainResource.create_nested('id', foo='bar') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/mainresources/id/nesteds', { @@ -31,10 +30,10 @@ def test_create_nested(self): }, None ) - self.assertEqual('bar', nested_resource.foo) + assert nested_resource.foo == 'bar' - def test_retrieve_nested(self): - self.stub_request( + def test_retrieve_nested(self, request_mock): + request_mock.stub_request( 'get', '/v1/mainresources/id/nesteds/nested_id', { @@ -44,16 +43,16 @@ def test_retrieve_nested(self): } ) nested_resource = self.MainResource.retrieve_nested('id', 'nested_id') - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/mainresources/id/nesteds/nested_id', {}, None ) - self.assertEqual('bar', nested_resource.foo) + assert nested_resource.foo == 'bar' - def test_modify_nested(self): - self.stub_request( + def test_modify_nested(self, request_mock): + request_mock.stub_request( 'post', '/v1/mainresources/id/nesteds/nested_id', { @@ -64,7 +63,7 @@ def test_modify_nested(self): ) nested_resource = self.MainResource.modify_nested('id', 'nested_id', foo='baz') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/mainresources/id/nesteds/nested_id', { @@ -72,10 +71,10 @@ def test_modify_nested(self): }, None ) - self.assertEqual('baz', nested_resource.foo) + assert nested_resource.foo == 'baz' - def test_delete_nested(self): - self.stub_request( + def test_delete_nested(self, request_mock): + request_mock.stub_request( 'delete', '/v1/mainresources/id/nesteds/nested_id', { @@ -85,16 +84,16 @@ def test_delete_nested(self): } ) nested_resource = self.MainResource.delete_nested('id', 'nested_id') - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/mainresources/id/nesteds/nested_id', {}, None ) - self.assertEqual(True, nested_resource.deleted) + assert nested_resource.deleted is True - def test_list_nesteds(self): - self.stub_request( + def test_list_nesteds(self, request_mock): + request_mock.stub_request( 'get', '/v1/mainresources/id/nesteds', { @@ -103,10 +102,10 @@ def test_list_nesteds(self): } ) nested_resource = self.MainResource.list_nesteds('id') - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/mainresources/id/nesteds', {}, None ) - self.assertTrue(isinstance(nested_resource.data, list)) + assert isinstance(nested_resource.data, list) diff --git a/tests/api_resources/abstract/test_singleton_api_resource.py b/tests/api_resources/abstract/test_singleton_api_resource.py index 25be650b8..a447843d5 100644 --- a/tests/api_resources/abstract/test_singleton_api_resource.py +++ b/tests/api_resources/abstract/test_singleton_api_resource.py @@ -1,17 +1,14 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class MySingleton(stripe.api_resources.abstract.SingletonAPIResource): - pass +class TestSingletonAPIResource(object): + class MySingleton(stripe.api_resources.abstract.SingletonAPIResource): + pass - -class SingletonAPIResourceTests(StripeTestCase): - - def test_retrieve(self): - self.stub_request( + def test_retrieve(self, request_mock): + request_mock.stub_request( 'get', '/v1/mysingleton', { @@ -20,13 +17,14 @@ def test_retrieve(self): rheaders={'request-id': 'req_id'} ) - res = MySingleton.retrieve() + res = self.MySingleton.retrieve() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/mysingleton', {} ) - self.assertEqual('ton', res.single) - self.assertTrue(res.last_response is not None) - self.assertEqual('req_id', res.last_response.request_id) + assert res.single == 'ton' + + assert res.last_response is not None + assert res.last_response.request_id == 'req_id' diff --git a/tests/api_resources/abstract/test_updateable_api_resource.py b/tests/api_resources/abstract/test_updateable_api_resource.py index 33e8d09a9..9924c29e6 100644 --- a/tests/api_resources/abstract/test_updateable_api_resource.py +++ b/tests/api_resources/abstract/test_updateable_api_resource.py @@ -1,18 +1,17 @@ from __future__ import absolute_import, division, print_function -import stripe -from tests.helper import StripeTestCase - +import pytest -class MyUpdateable(stripe.api_resources.abstract.UpdateableAPIResource): - pass +import stripe -class UpdateableAPIResourceTests(StripeTestCase): - def setUp(self): - super(UpdateableAPIResourceTests, self).setUp() +class TestUpdateableAPIResource(object): + class MyUpdateable(stripe.api_resources.abstract.UpdateableAPIResource): + pass - self.stub_request( + @pytest.fixture + def obj(self, request_mock): + request_mock.stub_request( 'post', '/v1/myupdateables/myid', { @@ -22,7 +21,7 @@ def setUp(self): rheaders={'request-id': 'req_id'} ) - self.obj = MyUpdateable.construct_from({ + return self.MyUpdateable.construct_from({ 'id': 'myid', 'foo': 'bar', 'baz': 'boz', @@ -33,19 +32,20 @@ def setUp(self): } }, 'mykey') - def checkSave(self): - self.assertTrue(self.obj is self.obj.save()) + def checkSave(self, obj): + assert obj is obj.save() - self.assertEqual('it', self.obj.thats) + assert obj.thats == 'it' # TODO: Should we force id to be retained? - # self.assertEqual('myid', obj.id) - self.assertRaises(AttributeError, getattr, self.obj, 'baz') + # assert obj.id == 'myid' + with pytest.raises(AttributeError): + obj.baz - def test_idempotent_save(self): - self.obj.baz = 'updated' - self.obj.save(idempotency_key='foo') + def test_idempotent_save(self, request_mock, obj): + obj.baz = 'updated' + obj.save(idempotency_key='foo') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -56,16 +56,16 @@ def test_idempotent_save(self): }, ) - def test_save(self): - self.obj.baz = 'updated' - self.obj.other = 'newval' - self.obj.metadata.size = 'm' - self.obj.metadata.info = 'a2' - self.obj.metadata.height = None + def test_save(self, request_mock, obj): + obj.baz = 'updated' + obj.other = 'newval' + obj.metadata.size = 'm' + obj.metadata.info = 'a2' + obj.metadata.height = None - self.checkSave() + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -80,16 +80,16 @@ def test_save(self): None ) - self.assertTrue(self.obj.last_response is not None) - self.assertEqual('req_id', self.obj.last_response.request_id) + assert obj.last_response is not None + assert obj.last_response.request_id == 'req_id' # Saving again should not cause any request. - self.request_mock.reset_mock() - self.checkSave() - self.assert_no_request() + request_mock.reset_mock() + self.checkSave(obj) + request_mock.assert_no_request() # Setting the same value should cause a request. - self.stub_request( + request_mock.stub_request( 'post', '/v1/myupdateables/myid', { @@ -98,10 +98,10 @@ def test_save(self): } ) - self.obj.thats = 'it' - self.checkSave() + obj.thats = 'it' + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -111,7 +111,7 @@ def test_save(self): ) # Changing the value should cause a request. - self.stub_request( + request_mock.stub_request( 'post', '/v1/myupdateables/myid', { @@ -120,11 +120,11 @@ def test_save(self): } ) - self.obj.id = 'myid' - self.obj.thats = 'updated' - self.checkSave() + obj.id = 'myid' + obj.thats = 'updated' + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -133,8 +133,8 @@ def test_save(self): None ) - def test_add_key_to_nested_object(self): - acct = MyUpdateable.construct_from({ + def test_add_key_to_nested_object(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'size': 'l', @@ -145,9 +145,9 @@ def test_add_key_to_nested_object(self): acct.legal_entity['first_name'] = 'bob' - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -158,20 +158,20 @@ def test_add_key_to_nested_object(self): None ) - def test_save_nothing(self): - acct = MyUpdateable.construct_from({ + def test_save_nothing(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'metadata': { 'key': 'value', } }, 'mykey') - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_no_request() + request_mock.assert_no_request() - def test_replace_nested_object(self): - acct = MyUpdateable.construct_from({ + def test_replace_nested_object(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'last_name': 'smith', @@ -182,9 +182,9 @@ def test_replace_nested_object(self): 'first_name': 'bob', } - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -196,17 +196,17 @@ def test_replace_nested_object(self): None ) - def test_array_setting(self): - acct = MyUpdateable.construct_from({ + def test_array_setting(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': {} }, 'mykey') acct.legal_entity.additional_owners = [{'first_name': 'Bob'}] - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -219,8 +219,8 @@ def test_array_setting(self): None ) - def test_array_none(self): - acct = MyUpdateable.construct_from({ + def test_array_none(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'additional_owners': None, @@ -229,9 +229,9 @@ def test_array_none(self): acct.foo = 'bar' - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -240,8 +240,8 @@ def test_array_none(self): None ) - def test_array_insertion(self): - acct = MyUpdateable.construct_from({ + def test_array_insertion(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'additional_owners': [] @@ -250,9 +250,9 @@ def test_array_insertion(self): acct.legal_entity.additional_owners.append({'first_name': 'Bob'}) - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -265,8 +265,8 @@ def test_array_insertion(self): None ) - def test_array_update(self): - acct = MyUpdateable.construct_from({ + def test_array_update(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'additional_owners': [ @@ -278,9 +278,9 @@ def test_array_update(self): acct.legal_entity.additional_owners[1].first_name = 'Janet' - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -294,8 +294,8 @@ def test_array_update(self): None ) - def test_array_noop(self): - acct = MyUpdateable.construct_from({ + def test_array_noop(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'additional_owners': [{'first_name': 'Bob'}] @@ -303,9 +303,9 @@ def test_array_noop(self): 'currencies_supported': ['usd', 'cad'] }, 'mykey') - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -314,26 +314,26 @@ def test_array_noop(self): None ) - def test_hash_noop(self): - acct = MyUpdateable.construct_from({ + def test_hash_noop(self, request_mock, obj): + acct = self.MyUpdateable.construct_from({ 'id': 'myid', 'legal_entity': { 'address': {'line1': '1 Two Three'} } }, 'mykey') - self.assertTrue(acct is acct.save()) + assert acct is acct.save() - self.assert_no_request() + request_mock.assert_no_request() - def test_save_replace_metadata_with_number(self): - self.obj.baz = 'updated' - self.obj.other = 'newval' - self.obj.metadata = 3 + def test_save_replace_metadata_with_number(self, request_mock, obj): + obj.baz = 'updated' + obj.other = 'newval' + obj.metadata = 3 - self.checkSave() + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -344,11 +344,11 @@ def test_save_replace_metadata_with_number(self): None ) - def test_save_overwrite_metadata(self): - self.obj.metadata = {} - self.checkSave() + def test_save_overwrite_metadata(self, request_mock, obj): + obj.metadata = {} + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -361,18 +361,18 @@ def test_save_overwrite_metadata(self): None ) - def test_save_replace_metadata(self): - self.obj.baz = 'updated' - self.obj.other = 'newval' - self.obj.metadata = { + def test_save_replace_metadata(self, request_mock, obj): + obj.baz = 'updated' + obj.other = 'newval' + obj.metadata = { 'size': 'm', 'info': 'a2', 'score': 4, } - self.checkSave() + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -388,18 +388,18 @@ def test_save_replace_metadata(self): None ) - def test_save_update_metadata(self): - self.obj.baz = 'updated' - self.obj.other = 'newval' - self.obj.metadata.update({ + def test_save_update_metadata(self, request_mock, obj): + obj.baz = 'updated' + obj.other = 'newval' + obj.metadata.update({ 'size': 'm', 'info': 'a2', 'score': 4, }) - self.checkSave() + self.checkSave(obj) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/myupdateables/myid', { @@ -414,8 +414,8 @@ def test_save_update_metadata(self): None ) - def test_retrieve_and_update_with_stripe_version(self): - self.stub_request( + def test_retrieve_and_update_with_stripe_version(self, request_mock, obj): + request_mock.stub_request( 'get', '/v1/myupdateables/foo', { @@ -424,11 +424,11 @@ def test_retrieve_and_update_with_stripe_version(self): } ) - res = MyUpdateable.retrieve('foo', stripe_version='2017-08-15') + res = self.MyUpdateable.retrieve('foo', stripe_version='2017-08-15') - self.request_mock.assert_api_version('2017-08-15') + request_mock.assert_api_version('2017-08-15') - self.stub_request( + request_mock.stub_request( 'post', '/v1/myupdateables/foo', { @@ -440,4 +440,4 @@ def test_retrieve_and_update_with_stripe_version(self): res.bobble = 'new_scrobble' res.save() - self.request_mock.assert_api_version('2017-08-15') + request_mock.assert_api_version('2017-08-15') diff --git a/tests/api_resources/test_account.py b/tests/api_resources/test_account.py index d7a4b2f9d..0bfb83c93 100644 --- a/tests/api_resources/test_account.py +++ b/tests/api_resources/test_account.py @@ -1,54 +1,53 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'acct_123' TEST_EXTERNALACCOUNT_ID = 'ba_123' -class AccountTest(StripeTestCase): - def test_is_listable(self): +class TestAccount(object): + def test_is_listable(self, request_mock): resources = stripe.Account.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/accounts' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Account) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Account) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Account.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/accounts/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Account) + assert isinstance(resource, stripe.Account) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Account.create( country='US', type='custom' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts' ) - self.assertIsInstance(resource, stripe.Account) + assert isinstance(resource, stripe.Account) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): account = stripe.Account.retrieve(TEST_RESOURCE_ID) account.metadata['key'] = 'value' resource = account.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s' % resource.id ) - self.assertIsInstance(resource, stripe.Account) - self.assertTrue(resource is account) + assert isinstance(resource, stripe.Account) + assert resource is account - def test_is_saveable_with_additional_owners(self): + def test_is_saveable_with_additional_owners(self, request_mock): # stripe-mock does not return additional owners so we construct account = stripe.Account.construct_from({ 'id': '%s' % TEST_RESOURCE_ID, @@ -62,7 +61,7 @@ def test_is_saveable_with_additional_owners(self): owner = account.legal_entity.additional_owners[0] owner.verification.document = 'file_foo' resource = account.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s' % TEST_RESOURCE_ID, { @@ -77,53 +76,53 @@ def test_is_saveable_with_additional_owners(self): }, } ) - self.assertIsInstance(resource, stripe.Account) - self.assertTrue(resource is account) + assert isinstance(resource, stripe.Account) + assert resource is account - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Account.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Account) + assert isinstance(resource, stripe.Account) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Account.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/accounts/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True - def test_can_retrieve_no_id(self): + def test_can_retrieve_no_id(self, request_mock): resource = stripe.Account.retrieve() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/account' ) - self.assertIsInstance(resource, stripe.Account) + assert isinstance(resource, stripe.Account) - def test_can_reject(self): + def test_can_reject(self, request_mock): account = stripe.Account.retrieve(TEST_RESOURCE_ID) resource = account.reject(reason='fraud') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s/reject' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Account) - self.assertTrue(resource is account) + assert isinstance(resource, stripe.Account) + assert resource is account - def test_is_deauthorizable(self): + def test_is_deauthorizable(self, request_mock): account = stripe.Account.retrieve(TEST_RESOURCE_ID) - self.stub_request( + request_mock.stub_request( 'post', '/oauth/deauthorize', { @@ -131,7 +130,7 @@ def test_is_deauthorizable(self): } ) account.deauthorize() - self.assert_requested( + request_mock.assert_requested( 'post', '/oauth/deauthorize', { @@ -141,70 +140,70 @@ def test_is_deauthorizable(self): ) -class AccountExternalAccountsTests(StripeTestCase): - def test_is_listable(self): +class TestAccountExternalAccounts(object): + def test_is_listable(self, request_mock): resources = stripe.Account.list_external_accounts(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/accounts/%s/external_accounts' % TEST_RESOURCE_ID ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Card) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Card) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Account.retrieve_external_account( TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID ) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/accounts/%s/external_accounts/%s' % (TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID) ) - self.assertIsInstance(resource, stripe.BankAccount) + assert isinstance(resource, stripe.BankAccount) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Account.create_external_account( TEST_RESOURCE_ID, external_account='btok_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s/external_accounts' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.BankAccount) + assert isinstance(resource, stripe.BankAccount) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Account.modify_external_account( TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID, metadata={'foo': 'bar'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s/external_accounts/%s' % (TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID) ) - self.assertIsInstance(resource, stripe.BankAccount) + assert isinstance(resource, stripe.BankAccount) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Account.delete_external_account( TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID ) - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/accounts/%s/external_accounts/%s' % (TEST_RESOURCE_ID, TEST_EXTERNALACCOUNT_ID) ) - self.assertTrue(resource.deleted) + assert resource.deleted is True -class AccountLoginLinksTests(StripeTestCase): - def test_is_creatable(self): +class TestAccountLoginLinks(object): + def test_is_creatable(self, request_mock): resource = stripe.Account.create_login_link(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/accounts/%s/login_links' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.LoginLink) + assert isinstance(resource, stripe.LoginLink) diff --git a/tests/api_resources/test_alipay_account.py b/tests/api_resources/test_alipay_account.py index e81973fcb..9437c5edb 100644 --- a/tests/api_resources/test_alipay_account.py +++ b/tests/api_resources/test_alipay_account.py @@ -1,13 +1,14 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import (StripeTestCase) TEST_RESOURCE_ID = 'aliacc_123' -class AlipayAccountTest(StripeTestCase): +class TestAlipayAccount(object): def construct_resource(self): alipay_dict = { 'id': TEST_RESOURCE_ID, @@ -17,44 +18,42 @@ def construct_resource(self): } return stripe.AlipayAccount.construct_from(alipay_dict, stripe.api_key) - def test_has_instance_url(self): + def test_has_instance_url(self, request_mock): resource = self.construct_resource() - self.assertEqual( - '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): stripe.AlipayAccount.modify( 'cus_123', TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) - def test_is_not_retrievable(self): - with self.assertRaises(NotImplementedError): + def test_is_not_retrievable(self, request_mock): + with pytest.raises(NotImplementedError): stripe.AlipayAccount.retrieve(TEST_RESOURCE_ID) # Below, we don't use stripe-mock as it always returns a Bank Account # object when you hit /v1/customers/%s/sources/%s - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = self.construct_resource() resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = self.construct_resource() resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) diff --git a/tests/api_resources/test_apple_pay_domain.py b/tests/api_resources/test_apple_pay_domain.py index 206a23292..c3764c63a 100644 --- a/tests/api_resources/test_apple_pay_domain.py +++ b/tests/api_resources/test_apple_pay_domain.py @@ -1,48 +1,47 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'apwc_123' -class ApplePayDomainTest(StripeTestCase): - def test_is_listable(self): +class TestApplePayDomain(object): + def test_is_listable(self, request_mock): resources = stripe.ApplePayDomain.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/apple_pay/domains' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.ApplePayDomain) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.ApplePayDomain) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.ApplePayDomain.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/apple_pay/domains/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.ApplePayDomain) + assert isinstance(resource, stripe.ApplePayDomain) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.ApplePayDomain.create( domain_name='test.com', ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/apple_pay/domains' ) - self.assertIsInstance(resource, stripe.ApplePayDomain) + assert isinstance(resource, stripe.ApplePayDomain) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.ApplePayDomain.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/apple_pay/domains/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_application_fee.py b/tests/api_resources/test_application_fee.py index 555cf3b17..f86a98b77 100644 --- a/tests/api_resources/test_application_fee.py +++ b/tests/api_resources/test_application_fee.py @@ -1,76 +1,75 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'fee_123' TEST_FEEREFUND_ID = 'fr_123' -class ApplicationFeeTest(StripeTestCase): - def test_is_listable(self): +class TestApplicationFee(object): + def test_is_listable(self, request_mock): resources = stripe.ApplicationFee.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/application_fees' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.ApplicationFee) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.ApplicationFee) - -class ApplicationFeeRefundsTests(StripeTestCase): - def test_can_call_refund(self): + def test_is_refundable(self, request_mock): appfee = stripe.ApplicationFee.retrieve(TEST_RESOURCE_ID) resource = appfee.refund() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/application_fees/%s/refund' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.ApplicationFee) - self.assertTrue(resource is appfee) + assert isinstance(resource, stripe.ApplicationFee) + assert resource is appfee + - def test_is_listable(self): +class TestApplicationFeeRefunds(object): + def test_is_listable(self, request_mock): resources = stripe.ApplicationFee.list_refunds(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/application_fees/%s/refunds' % TEST_RESOURCE_ID ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.ApplicationFeeRefund) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.ApplicationFeeRefund) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.ApplicationFee.retrieve_refund( TEST_RESOURCE_ID, TEST_FEEREFUND_ID ) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/application_fees/%s/refunds/%s' % (TEST_RESOURCE_ID, TEST_FEEREFUND_ID) ) - self.assertIsInstance(resource, stripe.ApplicationFeeRefund) + assert isinstance(resource, stripe.ApplicationFeeRefund) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.ApplicationFee.create_refund( TEST_RESOURCE_ID, amount=100 ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/application_fees/%s/refunds' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.ApplicationFeeRefund) + assert isinstance(resource, stripe.ApplicationFeeRefund) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.ApplicationFee.modify_refund( TEST_RESOURCE_ID, TEST_FEEREFUND_ID, metadata={'foo': 'bar'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/application_fees/%s/refunds/%s' % (TEST_RESOURCE_ID, TEST_FEEREFUND_ID) ) - self.assertIsInstance(resource, stripe.ApplicationFeeRefund) + assert isinstance(resource, stripe.ApplicationFeeRefund) diff --git a/tests/api_resources/test_application_fee_refund.py b/tests/api_resources/test_application_fee_refund.py index e4a2fbf0b..30d2df3f8 100644 --- a/tests/api_resources/test_application_fee_refund.py +++ b/tests/api_resources/test_application_fee_refund.py @@ -1,38 +1,39 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'fr_123' TEST_APPFEE_ID = 'fee_123' -class ApplicationFeeRefundTest(StripeTestCase): - def test_is_saveable(self): +class TestApplicationFeeRefund(object): + def test_is_saveable(self, request_mock): appfee = stripe.ApplicationFee.retrieve(TEST_APPFEE_ID) resource = appfee.refunds.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/application_fees/%s/refunds/%s' % (resource.fee, resource.id) ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.ApplicationFeeRefund.modify( TEST_APPFEE_ID, TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/application_fees/%s/refunds/%s' % (TEST_APPFEE_ID, TEST_RESOURCE_ID) ) - self.assertIsInstance(resource, stripe.ApplicationFeeRefund) + assert isinstance(resource, stripe.ApplicationFeeRefund) def test_is_not_retrievable(self): - with self.assertRaises(NotImplementedError): + with pytest.raises(NotImplementedError): stripe.ApplicationFeeRefund.retrieve(TEST_RESOURCE_ID) diff --git a/tests/api_resources/test_balance.py b/tests/api_resources/test_balance.py index 13bd24d38..237e6d9d1 100644 --- a/tests/api_resources/test_balance.py +++ b/tests/api_resources/test_balance.py @@ -1,14 +1,13 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class BalanceTest(StripeTestCase): - def test_is_retrievable(self): +class TestBalance(object): + def test_is_retrievable(self, request_mock): resource = stripe.Balance.retrieve() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/balance' ) - self.assertIsInstance(resource, stripe.Balance) + assert isinstance(resource, stripe.Balance) diff --git a/tests/api_resources/test_balance_transaction.py b/tests/api_resources/test_balance_transaction.py index c7344cc7c..8b0be9491 100644 --- a/tests/api_resources/test_balance_transaction.py +++ b/tests/api_resources/test_balance_transaction.py @@ -1,18 +1,17 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'txn_123' -class BalanceTransactionTest(StripeTestCase): - def test_is_listable(self): +class TestBalanceTransaction(object): + def test_is_listable(self, request_mock): resources = stripe.BalanceTransaction.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/balance/history', ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.BalanceTransaction) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.BalanceTransaction) diff --git a/tests/api_resources/test_bank_account.py b/tests/api_resources/test_bank_account.py index 94f3f81e3..7f5d234bd 100644 --- a/tests/api_resources/test_bank_account.py +++ b/tests/api_resources/test_bank_account.py @@ -1,13 +1,14 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import (StripeTestCase) TEST_RESOURCE_ID = 'ba_123' -class BankAccountTest(StripeTestCase): +class TestBankAccountTest(object): def construct_resource(self, **params): bank_dict = { 'id': TEST_RESOURCE_ID, @@ -19,55 +20,51 @@ def construct_resource(self, **params): def test_has_account_instance_url(self): resource = self.construct_resource(account='acct_123') - self.assertEqual( - '/v1/accounts/acct_123/external_accounts/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/accounts/acct_123/external_accounts/%s' % TEST_RESOURCE_ID def test_has_customer_instance_url(self): resource = self.construct_resource(customer='cus_123') - self.assertEqual( - '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID # The previous tests already ensure that the request will be routed to the # correct URL, so we only test the API operations once. def test_is_not_retrievable(self): - with self.assertRaises(NotImplementedError): + with pytest.raises(NotImplementedError): stripe.BankAccount.retrieve(TEST_RESOURCE_ID) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = self.construct_resource(customer='cus_123') resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) def test_is_not_modifiable(self): - with self.assertRaises(NotImplementedError): + with pytest.raises(NotImplementedError): stripe.BankAccount.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = self.construct_resource(customer='cus_123') resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) # stripe-mock does not yet correctly handle deleting customer sources - # self.assertTrue(resource.deleted) + # assert resource.deleted is True - def test_is_verifiable(self): + def test_is_verifiable(self, request_mock): resource = self.construct_resource(customer='cus_123') resource.verify() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/cus_123/sources/%s/verify' % TEST_RESOURCE_ID ) diff --git a/tests/api_resources/test_bitcoin_receiver.py b/tests/api_resources/test_bitcoin_receiver.py index 82992d104..702cdc585 100644 --- a/tests/api_resources/test_bitcoin_receiver.py +++ b/tests/api_resources/test_bitcoin_receiver.py @@ -1,13 +1,12 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'btcrcv_123' -class BitcoinReceiverTest(StripeTestCase): +class TestBitcoinReceiver(object): def construct_resource(self, **params): res_dict = { 'id': TEST_RESOURCE_ID, @@ -19,42 +18,38 @@ def construct_resource(self, **params): def test_has_customer_instance_url(self): resource = self.construct_resource(customer='cus_123') - self.assertEqual( - '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID def test_has_receiver_instance_url(self): resource = self.construct_resource() - self.assertEqual( - '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID - def test_is_listable(self): + def test_is_listable(self, request_mock): resources = stripe.BitcoinReceiver.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/bitcoin/receivers' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.BitcoinReceiver) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.BitcoinReceiver) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.BitcoinReceiver.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.BitcoinReceiver) + assert isinstance(resource, stripe.BitcoinReceiver) # stripe-mock does not handle most write operations anymore so we stub # each one instead. This endpoint/resource is mostly deprecated today. # The previous tests already ensure that the request will be routed to the # correct URL, so we also only test the API operations once. - def test_is_creatable(self): - self.stub_request( + def test_is_creatable(self, request_mock): + request_mock.stub_request( 'post', '/v1/bitcoin/receivers', { @@ -63,27 +58,27 @@ def test_is_creatable(self): } ) resource = stripe.BitcoinReceiver.create() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/bitcoin/receivers' ) - self.assertIsInstance(resource, stripe.BitcoinReceiver) + assert isinstance(resource, stripe.BitcoinReceiver) - def test_is_saveable(self): - self.stub_request( + def test_is_saveable(self, request_mock): + request_mock.stub_request( 'post', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) resource = self.construct_resource() resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) - def test_is_modifiable(self): - self.stub_request( + def test_is_modifiable(self, request_mock): + request_mock.stub_request( 'post', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) @@ -91,19 +86,19 @@ def test_is_modifiable(self): TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) - def test_is_deletable(self): - self.stub_request( + def test_is_deletable(self, request_mock): + request_mock.stub_request( 'delete', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) resource = self.construct_resource() resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/bitcoin/receivers/%s' % TEST_RESOURCE_ID ) diff --git a/tests/api_resources/test_card.py b/tests/api_resources/test_card.py index 78ab59c41..9aefb2182 100644 --- a/tests/api_resources/test_card.py +++ b/tests/api_resources/test_card.py @@ -1,13 +1,14 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import (StripeTestCase) TEST_RESOURCE_ID = 'card_123' -class CardTest(StripeTestCase): +class TestCard(object): def construct_resource(self, **params): card_dict = { 'id': TEST_RESOURCE_ID, @@ -19,52 +20,46 @@ def construct_resource(self, **params): def test_has_account_instance_url(self): resource = self.construct_resource(account='acct_123') - self.assertEqual( - '/v1/accounts/acct_123/external_accounts/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/accounts/acct_123/external_accounts/%s' % TEST_RESOURCE_ID def test_has_customer_instance_url(self): resource = self.construct_resource(customer='cus_123') - self.assertEqual( - '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID def test_has_recipient_instance_url(self): resource = self.construct_resource(recipient='rp_123') - self.assertEqual( - '/v1/recipients/rp_123/cards/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/recipients/rp_123/cards/%s' % TEST_RESOURCE_ID # The previous tests already ensure that the request will be routed to the # correct URL, so we only test the API operations once. def test_is_not_retrievable(self): - with self.assertRaises(NotImplementedError): + with pytest.raises(NotImplementedError): stripe.Card.retrieve(TEST_RESOURCE_ID) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = self.construct_resource(customer='cus_123') resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) def test_is_not_modifiable(self): - with self.assertRaises(NotImplementedError): + with pytest.raises(NotImplementedError): stripe.Card.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = self.construct_resource(customer='cus_123') resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) diff --git a/tests/api_resources/test_charge.py b/tests/api_resources/test_charge.py index 605a24829..cb43472d3 100644 --- a/tests/api_resources/test_charge.py +++ b/tests/api_resources/test_charge.py @@ -1,120 +1,117 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'ch_123' -class ChargeTest(StripeTestCase): - def test_is_listable(self): +class TestCharge(object): + def test_is_listable(self, request_mock): resources = stripe.Charge.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/charges' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Charge) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Charge) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Charge.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/charges/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Charge.create( amount=100, currency='usd', source='tok_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges' ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Charge.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - -class ChargeMethodsTest(StripeTestCase): - def test_can_refund(self): + def test_is_refundable(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.refund() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s/refund' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - def test_can_capture(self): + def test_is_capturable(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.capture() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s/capture' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - def test_can_update_dispute(self): + def test_can_update_dispute(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.update_dispute() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s/dispute' % charge.id ) - self.assertIsInstance(resource, stripe.Dispute) + assert isinstance(resource, stripe.Dispute) - def test_can_close_dispute(self): + def test_can_close_dispute(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.close_dispute() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s/dispute/close' % charge.id ) - self.assertIsInstance(resource, stripe.Dispute) + assert isinstance(resource, stripe.Dispute) - def test_can_mark_as_fraudulent(self): + def test_can_mark_as_fraudulent(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.mark_as_fraudulent() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s' % charge.id, { 'fraud_details': {'user_report': 'fraudulent'} } ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) - def test_can_mark_as_safe(self): + def test_can_mark_as_safe(self, request_mock): charge = stripe.Charge.retrieve(TEST_RESOURCE_ID) resource = charge.mark_as_safe() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/charges/%s' % charge.id, { 'fraud_details': {'user_report': 'safe'} } ) - self.assertIsInstance(resource, stripe.Charge) + assert isinstance(resource, stripe.Charge) diff --git a/tests/api_resources/test_country_spec.py b/tests/api_resources/test_country_spec.py index 3fb9dbe1c..904f19028 100644 --- a/tests/api_resources/test_country_spec.py +++ b/tests/api_resources/test_country_spec.py @@ -1,26 +1,25 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'US' -class CountrySpecTest(StripeTestCase): - def test_is_listable(self): +class TestCountrySpec(object): + def test_is_listable(self, request_mock): resources = stripe.CountrySpec.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/country_specs' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.CountrySpec) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.CountrySpec) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.CountrySpec.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/country_specs/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.CountrySpec) + assert isinstance(resource, stripe.CountrySpec) diff --git a/tests/api_resources/test_coupon.py b/tests/api_resources/test_coupon.py index b90c288b6..04822c226 100644 --- a/tests/api_resources/test_coupon.py +++ b/tests/api_resources/test_coupon.py @@ -1,71 +1,70 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = '250FF' -class CouponTest(StripeTestCase): - def test_is_listable(self): +class TestCoupon(object): + def test_is_listable(self, request_mock): resources = stripe.Coupon.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/coupons' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Coupon) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Coupon) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Coupon.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/coupons/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Coupon) + assert isinstance(resource, stripe.Coupon) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Coupon.create( percent_off=25, duration='repeating', duration_in_months=3, id='250FF' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/coupons' ) - self.assertIsInstance(resource, stripe.Coupon) + assert isinstance(resource, stripe.Coupon) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Coupon.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/coupons/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Coupon.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/coupons/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Coupon) + assert isinstance(resource, stripe.Coupon) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Coupon.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/coupons/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_customer.py b/tests/api_resources/test_customer.py index e51b5e045..6c6d0c61e 100644 --- a/tests/api_resources/test_customer.py +++ b/tests/api_resources/test_customer.py @@ -3,7 +3,6 @@ import warnings import stripe -from tests.helper import (StripeTestCase) TEST_RESOURCE_ID = 'cus_123' @@ -11,67 +10,124 @@ TEST_SOURCE_ID = 'ba_123' -class CustomerTest(StripeTestCase): - def test_is_listable(self): +class TestCustomer(object): + def test_is_listable(self, request_mock): resources = stripe.Customer.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/customers' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Customer) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Customer) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/customers/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Customer) + assert isinstance(resource, stripe.Customer) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Customer.create() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers' ) - self.assertIsInstance(resource, stripe.Customer) + assert isinstance(resource, stripe.Customer) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Customer.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Customer) + assert isinstance(resource, stripe.Customer) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True + + def test_can_add_invoice_item(self, request_mock): + resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) + resource.add_invoice_item( + amount=100, + currency='usd' + ) + request_mock.assert_requested( + 'post', + '/v1/invoiceitems', + { + 'amount': 100, + 'currency': 'usd', + 'customer': '%s' % resource.id + } + ) + + def test_can_invoices(self, request_mock): + resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) + resource.invoices() + request_mock.assert_requested( + 'get', + '/v1/invoices', + { + 'customer': '%s' % resource.id + } + ) + + def test_can_invoice_items(self, request_mock): + resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) + resource.invoice_items() + request_mock.assert_requested( + 'get', + '/v1/invoiceitems', + { + 'customer': '%s' % resource.id + } + ) + + def test_can_list_charges(self, request_mock): + resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) + resource.charges() + request_mock.assert_requested( + 'get', + '/v1/charges', + { + 'customer': '%s' % resource.id + } + ) + + def test_can_delete_discount(self, request_mock): + resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) + resource.delete_discount() + request_mock.assert_requested( + 'delete', + '/v1/customers/%s/discount' % resource.id + ) # stripe-mock does not handle the legacy subscription endpoint so we stub -class CustomerLegacySubscriptionTest(StripeTestCase): +class TestCustomerLegacySubscription(object): def construct_resource(self): res_dict = { 'id': TEST_RESOURCE_ID, @@ -80,8 +136,8 @@ def construct_resource(self): } return stripe.Customer.construct_from(res_dict, stripe.api_key) - def test_can_update_legacy_subscription(self): - self.stub_request( + def test_can_update_legacy_subscription(self, request_mock): + request_mock.stub_request( 'post', '/v1/customers/%s/subscription' % TEST_RESOURCE_ID, ) @@ -89,13 +145,13 @@ def test_can_update_legacy_subscription(self): with warnings.catch_warnings(): warnings.simplefilter('ignore') resource.update_subscription(plan='plan') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/%s/subscription' % TEST_RESOURCE_ID ) - def test_can_delete_legacy_subscription(self): - self.stub_request( + def test_can_delete_legacy_subscription(self, request_mock): + request_mock.stub_request( 'delete', '/v1/customers/%s/subscription' % TEST_RESOURCE_ID ) @@ -103,120 +159,61 @@ def test_can_delete_legacy_subscription(self): with warnings.catch_warnings(): warnings.simplefilter('ignore') resource.cancel_subscription() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/%s/subscription' % TEST_RESOURCE_ID ) -class CustomerSourcesTests(StripeTestCase): - def test_is_creatable(self): +class TestCustomerSources(object): + def test_is_creatable(self, request_mock): stripe.Customer.create_source( TEST_RESOURCE_ID, source='btok_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/%s/sources' % TEST_RESOURCE_ID ) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): stripe.Customer.retrieve_source( TEST_RESOURCE_ID, TEST_SOURCE_ID ) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/customers/%s/sources/%s' % (TEST_RESOURCE_ID, TEST_SOURCE_ID) ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): stripe.Customer.modify_source( TEST_RESOURCE_ID, TEST_SOURCE_ID, metadata={'foo': 'bar'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/customers/%s/sources/%s' % (TEST_RESOURCE_ID, TEST_SOURCE_ID) ) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): stripe.Customer.delete_source( TEST_RESOURCE_ID, TEST_SOURCE_ID ) - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/customers/%s/sources/%s' % (TEST_RESOURCE_ID, TEST_SOURCE_ID) ) - def test_is_listable(self): + def test_is_listable(self, request_mock): resources = stripe.Customer.list_sources(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/customers/%s/sources' % TEST_RESOURCE_ID ) - self.assertIsInstance(resources.data, list) - - -class CustomerMethodsTests(StripeTestCase): - def test_can_add_invoice_item(self): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.add_invoice_item( - amount=100, - currency='usd' - ) - self.assert_requested( - 'post', - '/v1/invoiceitems', - { - 'amount': 100, - 'currency': 'usd', - 'customer': '%s' % resource.id - } - ) - - def test_can_invoices(self): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.invoices() - self.assert_requested( - 'get', - '/v1/invoices', - { - 'customer': '%s' % resource.id - } - ) - - def test_can_invoice_items(self): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.invoice_items() - self.assert_requested( - 'get', - '/v1/invoiceitems', - { - 'customer': '%s' % resource.id - } - ) - - def test_can_charges(self): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.charges() - self.assert_requested( - 'get', - '/v1/charges', - { - 'customer': '%s' % resource.id - } - ) - - def test_can_delete_discount(self): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.delete_discount() - self.assert_requested( - 'delete', - '/v1/customers/%s/discount' % resource.id - ) + assert isinstance(resources.data, list) diff --git a/tests/api_resources/test_dispute.py b/tests/api_resources/test_dispute.py index 180a394a5..20e94e756 100644 --- a/tests/api_resources/test_dispute.py +++ b/tests/api_resources/test_dispute.py @@ -1,54 +1,53 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'dp_123' -class DisputeTest(StripeTestCase): - def test_is_listable(self): +class TestDispute(object): + def test_is_listable(self, request_mock): resources = stripe.Dispute.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/disputes' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Dispute) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Dispute) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Dispute.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/disputes/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Dispute) + assert isinstance(resource, stripe.Dispute) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Dispute.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/disputes/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Dispute.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/disputes/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Dispute) + assert isinstance(resource, stripe.Dispute) - def test_is_closeable(self): + def test_is_closeable(self, request_mock): resource = stripe.Dispute.retrieve(TEST_RESOURCE_ID) resource.close() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/disputes/%s/close' % resource.id ) diff --git a/tests/api_resources/test_ephemeral_key.py b/tests/api_resources/test_ephemeral_key.py index 3b87537df..2652dc673 100644 --- a/tests/api_resources/test_ephemeral_key.py +++ b/tests/api_resources/test_ephemeral_key.py @@ -2,26 +2,26 @@ import warnings -import stripe -from tests.helper import StripeTestCase +import pytest +import stripe -class EphemeralKeyTest(StripeTestCase): - def test_is_creatable(self): +class TestEphemeralKey(object): + def test_is_creatable(self, request_mock): resource = stripe.EphemeralKey.create( customer='cus_123', stripe_version='2017-05-25' ) - self.request_mock.assert_api_version('2017-05-25') - self.assert_requested( + request_mock.assert_api_version('2017-05-25') + request_mock.assert_requested( 'post', '/v1/ephemeral_keys', {'customer': 'cus_123'} ) - self.assertIsInstance(resource, stripe.EphemeralKey) + assert isinstance(resource, stripe.EphemeralKey) - def test_raises_a_warning_when_using_api_version_arg(self): + def test_raises_a_warning_when_using_api_version_arg(self, request_mock): with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') @@ -29,29 +29,29 @@ def test_raises_a_warning_when_using_api_version_arg(self): customer='cus_123', api_version='2017-05-25' ) - self.request_mock.assert_api_version('2017-05-25') - self.assert_requested( + request_mock.assert_api_version('2017-05-25') + request_mock.assert_requested( 'post', '/v1/ephemeral_keys', {'customer': 'cus_123'} ) - self.assertIsInstance(resource, stripe.EphemeralKey) + assert isinstance(resource, stripe.EphemeralKey) - self.assertEqual(1, len(w)) - self.assertEqual(w[0].category, DeprecationWarning) + assert len(w) == 1 + assert w[0].category == DeprecationWarning def test_is_not_creatable_without_an_explicit_api_version(self): - with self.assertRaisesRegex(ValueError, - 'stripe_version must be specified'): + with pytest.raises(ValueError, + message='stripe_version must be specified'): stripe.EphemeralKey.create(customer='cus_123') - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.EphemeralKey.create( customer='cus_123', stripe_version='2017-05-25' ) resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/ephemeral_keys/%s' % resource.id ) diff --git a/tests/api_resources/test_event.py b/tests/api_resources/test_event.py index 06a91f311..8a2b618ac 100644 --- a/tests/api_resources/test_event.py +++ b/tests/api_resources/test_event.py @@ -1,26 +1,25 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'evt_123' -class EventTest(StripeTestCase): - def test_is_listable(self): +class TestEvent(object): + def test_is_listable(self, request_mock): resources = stripe.Event.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/events' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Event) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Event) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Event.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/events/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Event) + assert isinstance(resource, stripe.Event) diff --git a/tests/api_resources/test_exchange_rate.py b/tests/api_resources/test_exchange_rate.py index b93c3911c..d12bbd84b 100644 --- a/tests/api_resources/test_exchange_rate.py +++ b/tests/api_resources/test_exchange_rate.py @@ -1,26 +1,25 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'usd' -class ExchangeRateTest(StripeTestCase): - def test_is_listable(self): +class TestExchangeRate(object): + def test_is_listable(self, request_mock): resources = stripe.ExchangeRate.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/exchange_rates' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.ExchangeRate) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.ExchangeRate) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.ExchangeRate.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/exchange_rates/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.ExchangeRate) + assert isinstance(resource, stripe.ExchangeRate) diff --git a/tests/api_resources/test_file_upload.py b/tests/api_resources/test_file_upload.py index 8ada91e69..d307be5c2 100644 --- a/tests/api_resources/test_file_upload.py +++ b/tests/api_resources/test_file_upload.py @@ -2,56 +2,59 @@ import tempfile +import pytest + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'file_123' -class FileUploadTest(StripeTestCase): - FIXTURE = { - 'id': TEST_RESOURCE_ID, - 'object': 'file_upload' - } +class TestFileUpload(object): + @pytest.fixture + def file_upload_dict(self): + return { + 'id': TEST_RESOURCE_ID, + 'object': 'file_upload' + } - def test_is_listable(self): - self.stub_request( + def test_is_listable(self, request_mock, file_upload_dict): + request_mock.stub_request( 'get', '/v1/files', { 'object': 'list', - 'data': [self.FIXTURE], + 'data': [file_upload_dict], } ) resources = stripe.FileUpload.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/files' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.FileUpload) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.FileUpload) - def test_is_retrievable(self): - self.stub_request( + def test_is_retrievable(self, request_mock, file_upload_dict): + request_mock.stub_request( 'get', '/v1/files/%s' % TEST_RESOURCE_ID, - self.FIXTURE + file_upload_dict ) resource = stripe.FileUpload.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/files/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.FileUpload) + assert isinstance(resource, stripe.FileUpload) - def test_is_creatable(self): - self.stub_request( + def test_is_creatable(self, request_mock, file_upload_dict): + request_mock.stub_request( 'post', '/v1/files', - self.FIXTURE + file_upload_dict ) test_file = tempfile.TemporaryFile() @@ -59,9 +62,9 @@ def test_is_creatable(self): purpose='dispute_evidence', file=test_file ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/files', headers={'Content-Type': 'multipart/form-data'} ) - self.assertIsInstance(resource, stripe.FileUpload) + assert isinstance(resource, stripe.FileUpload) diff --git a/tests/api_resources/test_invoice.py b/tests/api_resources/test_invoice.py index aebf317cb..2e66836ee 100644 --- a/tests/api_resources/test_invoice.py +++ b/tests/api_resources/test_invoice.py @@ -1,84 +1,83 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'in_123' -class InvoiceTest(StripeTestCase): - def test_is_listable(self): +class TestInvoice(object): + def test_is_listable(self, request_mock): resources = stripe.Invoice.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/invoices' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Invoice) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Invoice) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Invoice.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/invoices/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Invoice.create( customer='cus_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/invoices' ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Invoice.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/invoices/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Invoice.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/invoices/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) - def test_can_pay(self): + def test_can_pay(self, request_mock): resource = stripe.Invoice.retrieve(TEST_RESOURCE_ID) resource = resource.pay() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/invoices/%s/pay' % resource.id ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) - def test_can_upcoming(self): + def test_can_upcoming(self, request_mock): resource = stripe.Invoice.upcoming() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/invoices/upcoming' ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) - def test_can_upcoming_and_subscription_items(self): + def test_can_upcoming_and_subscription_items(self, request_mock): resource = stripe.Invoice.upcoming( subscription_items=[ {"plan": "foo", "quantity": 3} ] ) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/invoices/upcoming', { @@ -90,4 +89,4 @@ def test_can_upcoming_and_subscription_items(self): }, }, ) - self.assertIsInstance(resource, stripe.Invoice) + assert isinstance(resource, stripe.Invoice) diff --git a/tests/api_resources/test_issuer_fraud_record.py b/tests/api_resources/test_issuer_fraud_record.py index 3043702d9..f62bc8c16 100644 --- a/tests/api_resources/test_issuer_fraud_record.py +++ b/tests/api_resources/test_issuer_fraud_record.py @@ -1,24 +1,25 @@ +from __future__ import absolute_import, division, print_function + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'issfr_123' -class IssuerFraudRecordTest(StripeTestCase): - def test_is_listable(self): +class TestIssuerFraudRecord(object): + def test_is_listable(self, request_mock): resources = stripe.IssuerFraudRecord.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/issuer_fraud_records' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.IssuerFraudRecord) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.IssuerFraudRecord) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.IssuerFraudRecord.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/issuer_fraud_records/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.IssuerFraudRecord) + assert isinstance(resource, stripe.IssuerFraudRecord) diff --git a/tests/api_resources/test_list_object.py b/tests/api_resources/test_list_object.py index ee09891df..9c8025c76 100644 --- a/tests/api_resources/test_list_object.py +++ b/tests/api_resources/test_list_object.py @@ -2,35 +2,34 @@ import json -import stripe -from tests.helper import StripeTestCase - +import pytest -class ListObjectTests(StripeTestCase): +import stripe - def setUp(self): - super(ListObjectTests, self).setUp() - self.lo = stripe.ListObject.construct_from({ +class TestListObject(object): + @pytest.fixture + def list_object(self): + return stripe.ListObject.construct_from({ 'object': 'list', 'url': '/my/path', 'data': ['foo'], }, 'mykey') - def assertResponse(self, res): - self.assertTrue(isinstance(res[0], stripe.Charge)) - self.assertEqual('bar', res[0].foo) + def assert_response(self, res): + assert isinstance(res[0], stripe.Charge) + assert res[0].foo == 'bar' - def test_for_loop(self): + def test_for_loop(self, list_object): seen = [] - for item in self.lo: + for item in list_object: seen.append(item) - self.assertEqual(['foo'], seen) + assert seen == ['foo'] - def test_list(self): - self.stub_request( + def test_list(self, request_mock, list_object): + request_mock.stub_request( 'get', '/my/path', [ @@ -41,9 +40,9 @@ def test_list(self): ] ) - res = self.lo.list(myparam='you') + res = list_object.list(myparam='you') - self.assert_requested( + request_mock.assert_requested( 'get', '/my/path', { @@ -51,10 +50,10 @@ def test_list(self): }, None ) - self.assertResponse(res) + self.assert_response(res) - def test_create(self): - self.stub_request( + def test_create(self, request_mock, list_object): + request_mock.stub_request( 'post', '/my/path', [ @@ -65,9 +64,9 @@ def test_create(self): ] ) - res = self.lo.create(myparam='eter') + res = list_object.create(myparam='eter') - self.assert_requested( + request_mock.assert_requested( 'post', '/my/path', { @@ -75,10 +74,10 @@ def test_create(self): }, None ) - self.assertResponse(res) + self.assert_response(res) - def test_retrieve(self): - self.stub_request( + def test_retrieve(self, request_mock, list_object): + request_mock.stub_request( 'get', '/my/path/myid', [ @@ -89,9 +88,9 @@ def test_retrieve(self): ] ) - res = self.lo.retrieve('myid', myparam='cow') + res = list_object.retrieve('myid', myparam='cow') - self.assert_requested( + request_mock.assert_requested( 'get', '/my/path/myid', { @@ -100,20 +99,20 @@ def test_retrieve(self): None ) - self.assertResponse(res) + self.assert_response(res) - def test_len(self): - self.assertEqual(len(self.lo), 1) + def test_len(self, list_object): + assert len(list_object) == 1 - def test_bool(self): - self.assertTrue(self.lo) + def test_bool(self, list_object): + assert list_object empty = stripe.ListObject.construct_from({ 'object': 'list', 'url': '/my/path', 'data': [], }, 'mykey') - self.assertFalse(empty) + assert bool(empty) is False def test_serialize_empty_list(self): empty = stripe.ListObject.construct_from({ @@ -123,7 +122,7 @@ def test_serialize_empty_list(self): serialized = str(empty) deserialized = stripe.ListObject.construct_from( json.loads(serialized), 'mykey') - self.assertEqual(empty, deserialized) + assert deserialized == empty def test_serialize_nested_empty_list(self): empty = stripe.ListObject.construct_from({ @@ -136,10 +135,10 @@ def test_serialize_nested_empty_list(self): serialized = str(obj) deserialized = stripe.StripeObject.construct_from( json.loads(serialized), 'mykey') - self.assertEqual(empty, deserialized.nested) + assert deserialized.nested == empty -class AutoPagingTests(StripeTestCase): +class TestAutoPaging: @staticmethod def pageable_model_response(ids, has_more): @@ -150,26 +149,26 @@ def pageable_model_response(ids, has_more): 'has_more': has_more, } - def test_iter_one_page(self): + def test_iter_one_page(self, request_mock): lo = stripe.ListObject.construct_from( self.pageable_model_response(['pm_123', 'pm_124'], False), 'mykey' ) - self.assert_no_request() + request_mock.assert_no_request() seen = [item['id'] for item in lo.auto_paging_iter()] - self.assertEqual(['pm_123', 'pm_124'], seen) + assert seen == ['pm_123', 'pm_124'] - def test_iter_two_pages(self): + def test_iter_two_pages(self, request_mock): lo = stripe.ListObject.construct_from( self.pageable_model_response(['pm_123', 'pm_124'], True), 'mykey' ) lo._retrieve_params = {'foo': 'bar'} - self.stub_request( + request_mock.stub_request( 'get', '/v1/pageablemodels', self.pageable_model_response(['pm_125', 'pm_126'], False) @@ -177,7 +176,7 @@ def test_iter_two_pages(self): seen = [item['id'] for item in lo.auto_paging_iter()] - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/pageablemodels', { @@ -187,10 +186,10 @@ def test_iter_two_pages(self): None ) - self.assertEqual(['pm_123', 'pm_124', 'pm_125', 'pm_126'], seen) + assert seen == ['pm_123', 'pm_124', 'pm_125', 'pm_126'] - def test_class_method_two_pages(self): - self.stub_request( + def test_class_method_two_pages(self, request_mock): + request_mock.stub_request( 'get', '/v1/charges', { @@ -206,7 +205,7 @@ def test_class_method_two_pages(self): foo='bar' )] - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/charges', { @@ -214,4 +213,4 @@ def test_class_method_two_pages(self): 'foo': 'bar', } ) - self.assertEqual(['ch_001'], seen) + assert seen == ['ch_001'] diff --git a/tests/api_resources/test_order.py b/tests/api_resources/test_order.py index e82425a72..2055afe59 100644 --- a/tests/api_resources/test_order.py +++ b/tests/api_resources/test_order.py @@ -1,78 +1,77 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'or_123' -class OrderTest(StripeTestCase): - def test_is_listable(self): +class TestOrder(object): + def test_is_listable(self, request_mock): resources = stripe.Order.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/orders' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Order) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Order) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Order.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/orders/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Order) + assert isinstance(resource, stripe.Order) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Order.create( currency='usd' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/orders' ) - self.assertIsInstance(resource, stripe.Order) + assert isinstance(resource, stripe.Order) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Order.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/orders/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Order.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/orders/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Order) + assert isinstance(resource, stripe.Order) - def test_is_payable(self): + def test_is_payable(self, request_mock): order = stripe.Order.retrieve(TEST_RESOURCE_ID) resource = order.pay(source='src_123') - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/orders/%s/pay' % order.id, { 'source': 'src_123' } ) - self.assertTrue(resource, stripe.Order) - self.assertTrue(resource is order) + assert isinstance(resource, stripe.Order) + assert resource is order - def test_is_returnable(self): + def test_is_returnable(self, request_mock): order = stripe.Order.retrieve(TEST_RESOURCE_ID) resource = order.return_order() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/orders/%s/returns' % order.id ) - self.assertIsInstance(resource, stripe.OrderReturn) + assert isinstance(resource, stripe.OrderReturn) diff --git a/tests/api_resources/test_order_return.py b/tests/api_resources/test_order_return.py index 9e44f60fc..0fe4beccd 100644 --- a/tests/api_resources/test_order_return.py +++ b/tests/api_resources/test_order_return.py @@ -1,26 +1,25 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'orret_123' -class OrderReturnTest(StripeTestCase): - def test_is_listable(self): +class TestOrderReturn(object): + def test_is_listable(self, request_mock): resources = stripe.OrderReturn.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/order_returns' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.OrderReturn) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.OrderReturn) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.OrderReturn.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/order_returns/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.OrderReturn) + assert isinstance(resource, stripe.OrderReturn) diff --git a/tests/api_resources/test_payment_intent.py b/tests/api_resources/test_payment_intent.py index 054ec903e..dedc9c23a 100644 --- a/tests/api_resources/test_payment_intent.py +++ b/tests/api_resources/test_payment_intent.py @@ -1,88 +1,91 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'pi_123' -class PaymentIntentTest(StripeTestCase): - def test_is_listable(self): +class TestPaymentIntent(object): + def test_is_listable(self, request_mock): resources = stripe.PaymentIntent.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/payment_intents' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.PaymentIntent) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.PaymentIntent) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.PaymentIntent.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/payment_intents/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.PaymentIntent.create( allowed_source_types=['card'], amount='1234', currency='amount' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents', ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.PaymentIntent.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents/%s' % TEST_RESOURCE_ID, {'metadata': {'key': 'value'}} ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.PaymentIntent.retrieve(TEST_RESOURCE_ID) + resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents/%s' % resource.id, {'metadata': {'key': 'value'}} ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_can_cancel(self): + def test_can_cancel(self, request_mock): resource = stripe.PaymentIntent.retrieve(TEST_RESOURCE_ID) + resource.cancel() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents/%s/cancel' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_can_capture(self): + def test_can_capture(self, request_mock): resource = stripe.PaymentIntent.retrieve(TEST_RESOURCE_ID) + resource.capture() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents/%s/capture' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) - def test_can_confirm(self): + def test_can_confirm(self, request_mock): resource = stripe.PaymentIntent.retrieve(TEST_RESOURCE_ID) + resource.confirm() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payment_intents/%s/confirm' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.PaymentIntent) + assert isinstance(resource, stripe.PaymentIntent) diff --git a/tests/api_resources/test_payout.py b/tests/api_resources/test_payout.py index 846d09550..0f04528eb 100644 --- a/tests/api_resources/test_payout.py +++ b/tests/api_resources/test_payout.py @@ -1,66 +1,65 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'po_123' -class PayoutTest(StripeTestCase): - def test_is_listable(self): +class TestPayout(object): + def test_is_listable(self, request_mock): resources = stripe.Payout.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/payouts' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Payout) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Payout) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Payout.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/payouts/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Payout) + assert isinstance(resource, stripe.Payout) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Payout.create( amount=100, currency='usd' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payouts' ) - self.assertIsInstance(resource, stripe.Payout) + assert isinstance(resource, stripe.Payout) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Payout.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payouts/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Payout.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payouts/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Payout) + assert isinstance(resource, stripe.Payout) - def test_can_cancel(self): + def test_can_cancel(self, request_mock): payout = stripe.Payout.retrieve(TEST_RESOURCE_ID) resource = payout.cancel() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/payouts/%s/cancel' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Payout) + assert isinstance(resource, stripe.Payout) diff --git a/tests/api_resources/test_plan.py b/tests/api_resources/test_plan.py index 2b70c141b..82e08845d 100644 --- a/tests/api_resources/test_plan.py +++ b/tests/api_resources/test_plan.py @@ -1,31 +1,30 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = '250FF' -class PlanTest(StripeTestCase): - def test_is_listable(self): +class TestPlan(object): + def test_is_listable(self, request_mock): resources = stripe.Plan.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/plans' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Plan) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Plan) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Plan.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/plans/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Plan) + assert isinstance(resource, stripe.Plan) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Plan.create( amount=100, currency='usd', @@ -33,40 +32,40 @@ def test_is_creatable(self): interval='month', name='plan_name', ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/plans' ) - self.assertIsInstance(resource, stripe.Plan) + assert isinstance(resource, stripe.Plan) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Plan.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/plans/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Plan.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/plans/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Plan) + assert isinstance(resource, stripe.Plan) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Plan.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/plans/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_product.py b/tests/api_resources/test_product.py index 5f0c0d10e..503060fc8 100644 --- a/tests/api_resources/test_product.py +++ b/tests/api_resources/test_product.py @@ -1,69 +1,68 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'prod_123' -class ProductTest(StripeTestCase): - def test_is_listable(self): +class TestProduct(object): + def test_is_listable(self, request_mock): resources = stripe.Product.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/products' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Product) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Product) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Product.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/products/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Product) + assert isinstance(resource, stripe.Product) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Product.create( name='NAME', type='good' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/products' ) - self.assertIsInstance(resource, stripe.Product) + assert isinstance(resource, stripe.Product) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Product.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/products/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Product.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/products/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Product) + assert isinstance(resource, stripe.Product) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Product.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/products/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_recipient.py b/tests/api_resources/test_recipient.py index ca6a213bb..a0cf4df16 100644 --- a/tests/api_resources/test_recipient.py +++ b/tests/api_resources/test_recipient.py @@ -1,80 +1,79 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import (StripeTestCase) TEST_RESOURCE_ID = 'rp_123' -class RecipientTest(StripeTestCase): - def test_is_listable(self): +class TestRecipient(object): + def test_is_listable(self, request_mock): resources = stripe.Recipient.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/recipients' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Recipient) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Recipient) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Recipient.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/recipients/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Recipient) + assert isinstance(resource, stripe.Recipient) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Recipient.create( type='individual', name='NAME' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/recipients' ) - self.assertIsInstance(resource, stripe.Recipient) + assert isinstance(resource, stripe.Recipient) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Recipient.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/recipients/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Recipient.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/recipients/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Recipient) + assert isinstance(resource, stripe.Recipient) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Recipient.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/recipients/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True - def test_can_list_transfers(self): + def test_can_list_transfers(self, request_mock): recipient = stripe.Recipient.retrieve(TEST_RESOURCE_ID) resources = recipient.transfers() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/transfers', {'recipient': recipient.id} ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Transfer) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Transfer) diff --git a/tests/api_resources/test_refund.py b/tests/api_resources/test_refund.py index 0e4a700c8..914ee2a61 100644 --- a/tests/api_resources/test_refund.py +++ b/tests/api_resources/test_refund.py @@ -1,56 +1,55 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 're_123' -class RefundTest(StripeTestCase): - def test_is_listable(self): +class TestRefund(object): + def test_is_listable(self, request_mock): resources = stripe.Refund.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/refunds' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Refund) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Refund) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Refund.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/refunds/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Refund) + assert isinstance(resource, stripe.Refund) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Refund.create( charge='ch_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/refunds' ) - self.assertIsInstance(resource, stripe.Refund) + assert isinstance(resource, stripe.Refund) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Refund.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/refunds/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Refund.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/refunds/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Refund) + assert isinstance(resource, stripe.Refund) diff --git a/tests/api_resources/test_reversal.py b/tests/api_resources/test_reversal.py index 83d391165..8a44285e5 100644 --- a/tests/api_resources/test_reversal.py +++ b/tests/api_resources/test_reversal.py @@ -1,13 +1,14 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'trr_123' -class ReversalTest(StripeTestCase): +class TestReversal(object): def construct_resource(self): reversal_dict = { 'id': TEST_RESOURCE_ID, @@ -17,31 +18,29 @@ def construct_resource(self): } return stripe.Reversal.construct_from(reversal_dict, stripe.api_key) - def test_has_instance_url(self): + def test_has_instance_url(self, request_mock): resource = self.construct_resource() - self.assertEqual( - '/v1/transfers/tr_123/reversals/%s' % TEST_RESOURCE_ID, - resource.instance_url() - ) + assert resource.instance_url() == \ + '/v1/transfers/tr_123/reversals/%s' % TEST_RESOURCE_ID - def test_is_not_modifiable(self): - with self.assertRaises(NotImplementedError): + def test_is_not_modifiable(self, request_mock): + with pytest.raises(NotImplementedError): stripe.Reversal.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - def test_is_not_retrievable(self): - with self.assertRaises(NotImplementedError): + def test_is_not_retrievable(self, request_mock): + with pytest.raises(NotImplementedError): stripe.Reversal.retrieve(TEST_RESOURCE_ID) # We don't use stripe-mock as the reversal returned has a transfer id that # is different from the transfer used to access the reversal - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = self.construct_resource() resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/tr_123/reversals/%s' % TEST_RESOURCE_ID ) diff --git a/tests/api_resources/test_sku.py b/tests/api_resources/test_sku.py index eb7c48312..84fcde107 100644 --- a/tests/api_resources/test_sku.py +++ b/tests/api_resources/test_sku.py @@ -1,31 +1,30 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'sku_123' -class SKUTest(StripeTestCase): - def test_is_listable(self): +class TestSKU(object): + def test_is_listable(self, request_mock): resources = stripe.SKU.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/skus' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.SKU) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.SKU) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.SKU.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/skus/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.SKU) + assert isinstance(resource, stripe.SKU) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.SKU.create( currency='usd', inventory=dict( @@ -35,40 +34,40 @@ def test_is_creatable(self): price=100, product='prod_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/skus' ) - self.assertIsInstance(resource, stripe.SKU) + assert isinstance(resource, stripe.SKU) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.SKU.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/skus/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.SKU.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/skus/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.SKU) + assert isinstance(resource, stripe.SKU) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.SKU.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/skus/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_source.py b/tests/api_resources/test_source.py index 12358b175..014f86e0e 100644 --- a/tests/api_resources/test_source.py +++ b/tests/api_resources/test_source.py @@ -2,70 +2,71 @@ import warnings +import pytest + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'src_123' -class SourceTest(StripeTestCase): - - def test_is_retrievable(self): +class TestSource(object): + def test_is_retrievable(self, request_mock): resource = stripe.Source.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/sources/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Source) + assert isinstance(resource, stripe.Source) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Source.create( type='card', token='tok_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/sources' ) - self.assertIsInstance(resource, stripe.Source) + assert isinstance(resource, stripe.Source) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Source.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/sources/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Source.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/sources/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Source) + assert isinstance(resource, stripe.Source) - def test_is_detachable_when_attached(self): + def test_is_detachable_when_attached(self, request_mock): resource = stripe.Source.construct_from({ 'id': TEST_RESOURCE_ID, 'object': 'source', 'customer': 'cus_123' }, stripe.api_key) source = resource.detach() - self.assertTrue(source is resource) - self.assert_requested( + assert source is resource + request_mock.assert_requested( 'delete', '/v1/customers/cus_123/sources/%s' % TEST_RESOURCE_ID ) def test_is_not_detachable_when_unattached(self): resource = stripe.Source.retrieve(TEST_RESOURCE_ID) - self.assertRaises(NotImplementedError, resource.detach) + with pytest.raises(NotImplementedError): + resource.detach() def test_raises_a_warning_when_calling_delete(self): with warnings.catch_warnings(record=True) as w: @@ -78,14 +79,14 @@ def test_raises_a_warning_when_calling_delete(self): }, stripe.api_key) resource.delete() - self.assertEqual(1, len(w)) - self.assertEqual(w[0].category, DeprecationWarning) + assert len(w) == 1 + assert w[0].category == DeprecationWarning - def test_is_verifiable(self): + def test_is_verifiable(self, request_mock): resource = stripe.Source.retrieve(TEST_RESOURCE_ID) source = resource.verify(values=[1, 2]) - self.assertTrue(source is resource) - self.assert_requested( + assert source is resource + request_mock.assert_requested( 'post', '/v1/sources/%s/verify' % TEST_RESOURCE_ID, {'values': [1, 2]} diff --git a/tests/api_resources/test_source_transaction.py b/tests/api_resources/test_source_transaction.py index 15b162a4b..8df1d1732 100644 --- a/tests/api_resources/test_source_transaction.py +++ b/tests/api_resources/test_source_transaction.py @@ -1,20 +1,19 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase -class SourceTransactionTest(StripeTestCase): - def test_is_listable(self): +class TestSourceTransaction(object): + def test_is_listable(self, request_mock): source = stripe.Source.construct_from({ 'id': 'src_123', 'object': 'source' }, stripe.api_key) source_transactions = source.source_transactions() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/sources/src_123/source_transactions' ) - self.assertIsInstance(source_transactions.data, list) - self.assertIsInstance(source_transactions.data[0], - stripe.SourceTransaction) + assert isinstance(source_transactions.data, list) + assert isinstance(source_transactions.data[0], + stripe.SourceTransaction) diff --git a/tests/api_resources/test_subscription.py b/tests/api_resources/test_subscription.py index 8141f2586..66bc567a0 100644 --- a/tests/api_resources/test_subscription.py +++ b/tests/api_resources/test_subscription.py @@ -1,85 +1,84 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'sub_123' -class SubscriptionTest(StripeTestCase): - def test_is_listable(self): +class TestSubscription(object): + def test_is_listable(self, request_mock): resources = stripe.Subscription.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/subscriptions' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Subscription) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Subscription) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Subscription.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/subscriptions/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Subscription.create( customer='cus_123', ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscriptions' ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Subscription.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscriptions/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Subscription.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscriptions/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.Subscription.retrieve(TEST_RESOURCE_ID) resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/subscriptions/%s' % resource.id ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) - def test_can_delete_discount(self): + def test_can_delete_discount(self, request_mock): sub = stripe.Subscription.retrieve(TEST_RESOURCE_ID) sub.delete_discount() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/subscriptions/%s/discount' % sub.id ) # Test create/modify methods with subscription items - def test_is_creatable_with_items(self): + def test_is_creatable_with_items(self, request_mock): resource = stripe.Subscription.create( customer='cus_123', items=[{"plan": "foo", "quantity": 3}] ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscriptions', { @@ -92,14 +91,14 @@ def test_is_creatable_with_items(self): }, }, ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) - def test_is_modifiable_with_items(self): + def test_is_modifiable_with_items(self, request_mock): resource = stripe.Subscription.modify( TEST_RESOURCE_ID, items=[{"id": "si", "plan": "foo"}] ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscriptions/%s' % TEST_RESOURCE_ID, { @@ -111,14 +110,14 @@ def test_is_modifiable_with_items(self): }, }, ) - self.assertIsInstance(resource, stripe.Subscription) + assert isinstance(resource, stripe.Subscription) # TODO: Fix this test # def test_is_saveable_with_items(self): # resource = stripe.Subscription.retrieve(TEST_RESOURCE_ID) # resource.items = [{"id": "si", "plan": "foo"}] # resource.save() - # self.assert_requested( + # request_mock.assert_requested( # 'post', # '/v1/subscriptions/%s' % TEST_RESOURCE_ID, # { @@ -130,6 +129,6 @@ def test_is_modifiable_with_items(self): # }, # }, # ) - # self.assertIsInstance(resource, stripe.Subscription) + # assert isinstance(resource, stripe.Subscription) # TODO: Test serialize diff --git a/tests/api_resources/test_subscription_item.py b/tests/api_resources/test_subscription_item.py index c18302266..e42adf71d 100644 --- a/tests/api_resources/test_subscription_item.py +++ b/tests/api_resources/test_subscription_item.py @@ -1,47 +1,46 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'si_123' -class SubscriptionItemTest(StripeTestCase): - def test_is_listable(self): +class TestSubscriptionItem(object): + def test_is_listable(self, request_mock): resources = stripe.SubscriptionItem.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/subscription_items' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.SubscriptionItem) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.SubscriptionItem) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.SubscriptionItem.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/subscription_items/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.SubscriptionItem) + assert isinstance(resource, stripe.SubscriptionItem) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.SubscriptionItem.create( plan='plan', subscription='sub_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscription_items' ) - self.assertIsInstance(resource, stripe.SubscriptionItem) + assert isinstance(resource, stripe.SubscriptionItem) # TODO: Fix this test # def test_is_saveable(self): # resource = stripe.SubscriptionItem.retrieve(TEST_RESOURCE_ID) # resource.plan = 'plan' # resource.save() - # self.assert_requested( + # request_mock.assert_requested( # 'post', # '/v1/subscription_items/%s' % resource.id, # { @@ -49,28 +48,28 @@ def test_is_creatable(self): # }, # ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.SubscriptionItem.modify( TEST_RESOURCE_ID, plan='plan' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscription_items/%s' % TEST_RESOURCE_ID, { 'plan': 'plan', }, ) - self.assertIsInstance(resource, stripe.SubscriptionItem) + assert isinstance(resource, stripe.SubscriptionItem) - def test_is_deletable(self): + def test_is_deletable(self, request_mock): resource = stripe.SubscriptionItem.retrieve(TEST_RESOURCE_ID) # Unfortunately stripe-mock will return a resource with a different # ID, so we need to store the original ID for the request assertion resource_id = resource.id resource.delete() - self.assert_requested( + request_mock.assert_requested( 'delete', '/v1/subscription_items/%s' % resource_id ) - self.assertTrue(resource.deleted) + assert resource.deleted is True diff --git a/tests/api_resources/test_three_d_secure.py b/tests/api_resources/test_three_d_secure.py index e47d0bc4a..13a030c94 100644 --- a/tests/api_resources/test_three_d_secure.py +++ b/tests/api_resources/test_three_d_secure.py @@ -1,30 +1,29 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'tdsrc_123' -class ThreeDSecureTest(StripeTestCase): - def test_is_retrievable(self): +class TestThreeDSecure(object): + def test_is_retrievable(self, request_mock): resource = stripe.ThreeDSecure.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/3d_secure/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.ThreeDSecure) + assert isinstance(resource, stripe.ThreeDSecure) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.ThreeDSecure.create( card="tok_123", amount=100, currency="usd", return_url="url" ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/3d_secure' ) - self.assertIsInstance(resource, stripe.ThreeDSecure) + assert isinstance(resource, stripe.ThreeDSecure) diff --git a/tests/api_resources/test_topup.py b/tests/api_resources/test_topup.py index 229ca459d..df9c538d0 100644 --- a/tests/api_resources/test_topup.py +++ b/tests/api_resources/test_topup.py @@ -1,29 +1,30 @@ +from __future__ import absolute_import, division, print_function + import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'tu_123' -class TopupTest(StripeTestCase): - def test_is_listable(self): +class TestTopup(object): + def test_is_listable(self, request_mock): resources = stripe.Topup.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/topups' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Topup) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Topup) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Topup.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/topups/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Topup) + assert isinstance(resource, stripe.Topup) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Topup.create( amount=100, currency='usd', @@ -31,28 +32,28 @@ def test_is_creatable(self): description='description', statement_descriptor='statement descriptor' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/topups' ) - self.assertIsInstance(resource, stripe.Topup) + assert isinstance(resource, stripe.Topup) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Topup.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/topups/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Topup.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/topups/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Topup) + assert isinstance(resource, stripe.Topup) diff --git a/tests/api_resources/test_transfer.py b/tests/api_resources/test_transfer.py index 487d7d9be..258ada986 100644 --- a/tests/api_resources/test_transfer.py +++ b/tests/api_resources/test_transfer.py @@ -1,67 +1,66 @@ from __future__ import absolute_import, division, print_function import stripe -from tests.helper import StripeTestCase TEST_RESOURCE_ID = 'tr_123' TEST_REVERSAL_ID = 'trr_123' -class TransferTest(StripeTestCase): - def test_is_listable(self): +class TestTransfer(object): + def test_is_listable(self, request_mock): resources = stripe.Transfer.list() - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/transfers' ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Transfer) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Transfer) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Transfer.retrieve(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/transfers/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Transfer) + assert isinstance(resource, stripe.Transfer) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Transfer.create( amount=100, currency='usd', destination='acct_123' ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers' ) - self.assertIsInstance(resource, stripe.Transfer) + assert isinstance(resource, stripe.Transfer) - def test_is_saveable(self): + def test_is_saveable(self, request_mock): resource = stripe.Transfer.retrieve(TEST_RESOURCE_ID) resource.metadata['key'] = 'value' resource.save() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/%s' % resource.id ) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Transfer.modify( TEST_RESOURCE_ID, metadata={'key': 'value'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/%s' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Transfer) + assert isinstance(resource, stripe.Transfer) - def test_is_cancelable(self): + def test_is_cancelable(self, request_mock): # stripe-mock does not handle this anymore as it was on an old # API version so we stub instead. - self.stub_request( + request_mock.stub_request( 'post', '/v1/transfers/%s/cancel' % TEST_RESOURCE_ID, { @@ -75,55 +74,55 @@ def test_is_cancelable(self): 'object': 'transfer' }, stripe.api_key) transfer_canceled = transfer.cancel() - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/%s/cancel' % TEST_RESOURCE_ID ) - self.assertIsInstance(transfer_canceled, stripe.Transfer) + assert isinstance(transfer_canceled, stripe.Transfer) -class TransferReversalTest(StripeTestCase): - def test_is_listable(self): +class TestTransferReversals: + def test_is_listable(self, request_mock): resources = stripe.Transfer.list_reversals(TEST_RESOURCE_ID) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/transfers/%s/reversals' % TEST_RESOURCE_ID ) - self.assertIsInstance(resources.data, list) - self.assertIsInstance(resources.data[0], stripe.Reversal) + assert isinstance(resources.data, list) + assert isinstance(resources.data[0], stripe.Reversal) - def test_is_retrievable(self): + def test_is_retrievable(self, request_mock): resource = stripe.Transfer.retrieve_reversal( TEST_RESOURCE_ID, TEST_REVERSAL_ID ) - self.assert_requested( + request_mock.assert_requested( 'get', '/v1/transfers/%s/reversals/%s' % (TEST_RESOURCE_ID, TEST_REVERSAL_ID) ) - self.assertIsInstance(resource, stripe.Reversal) + assert isinstance(resource, stripe.Reversal) - def test_is_creatable(self): + def test_is_creatable(self, request_mock): resource = stripe.Transfer.create_reversal( TEST_RESOURCE_ID, amount=100 ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/%s/reversals' % TEST_RESOURCE_ID ) - self.assertIsInstance(resource, stripe.Reversal) + assert isinstance(resource, stripe.Reversal) - def test_is_modifiable(self): + def test_is_modifiable(self, request_mock): resource = stripe.Transfer.modify_reversal( TEST_RESOURCE_ID, TEST_REVERSAL_ID, metadata={'foo': 'bar'} ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/transfers/%s/reversals/%s' % (TEST_RESOURCE_ID, TEST_REVERSAL_ID) ) - self.assertIsInstance(resource, stripe.Reversal) + assert isinstance(resource, stripe.Reversal) diff --git a/tests/api_resources/test_usage_record.py b/tests/api_resources/test_usage_record.py index 4954e0aee..6a7293f1f 100644 --- a/tests/api_resources/test_usage_record.py +++ b/tests/api_resources/test_usage_record.py @@ -1,30 +1,31 @@ from __future__ import absolute_import, division, print_function +import pytest + import stripe -from tests.helper import StripeTestCase TEST_SUBSCRIPTION_ITEM_ID = 'si_123' -class UsageRecordTest(StripeTestCase): - def test_is_creatable(self): +class TestUsageRecord(object): + def test_is_creatable(self, request_mock): resource = stripe.UsageRecord.create( subscription_item=TEST_SUBSCRIPTION_ITEM_ID, quantity=5000, timestamp=1524182400, action='increment', ) - self.assert_requested( + request_mock.assert_requested( 'post', '/v1/subscription_items/%s/usage_records' % ( TEST_SUBSCRIPTION_ITEM_ID ) ) - self.assertIsInstance(resource, stripe.UsageRecord) + assert isinstance(resource, stripe.UsageRecord) def test_raises_when_creating_without_subscription_item(self): - with self.assertRaises(ValueError): + with pytest.raises(ValueError): stripe.UsageRecord.create( quantity=5000, timestamp=1524182400, diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..08c8c0ca5 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,62 @@ +from __future__ import absolute_import, division, print_function + +import os +import sys +from distutils.version import StrictVersion + +import pytest + +import stripe +from stripe.six.moves.urllib.request import urlopen +from stripe.six.moves.urllib.error import HTTPError + +from tests.request_mock import RequestMock + + +MOCK_MINIMUM_VERSION = '0.19.0' +MOCK_PORT = os.environ.get('STRIPE_MOCK_PORT', 12111) + + +try: + resp = urlopen('http://localhost:%s/' % MOCK_PORT) + info = resp.info() +except HTTPError as e: + info = e.info() +except Exception: + sys.exit("Couldn't reach stripe-mock at `localhost:%s`. Is " + "it running? Please see README for setup instructions." % + MOCK_PORT) + +version = info.get('Stripe-Mock-Version') +if version != 'master' \ + and StrictVersion(version) < StrictVersion(MOCK_MINIMUM_VERSION): + sys.exit("Your version of stripe-mock (%s) is too old. The minimum " + "version to run this test suite is %s. Please " + "see its repository for upgrade instructions." % + (version, MOCK_MINIMUM_VERSION)) + + +@pytest.fixture(autouse=True) +def setup_stripe(): + orig_attrs = { + 'api_base': stripe.api_base, + 'api_key': stripe.api_key, + 'client_id': stripe.client_id, + 'default_http_client': stripe.default_http_client, + } + http_client = stripe.http_client.new_default_http_client() + stripe.api_base = 'http://localhost:%s' % MOCK_PORT + stripe.api_key = 'sk_test_123' + stripe.client_id = 'ca_123' + stripe.default_http_client = http_client + yield + http_client.close() + stripe.api_base = orig_attrs['api_base'] + stripe.api_key = orig_attrs['api_key'] + stripe.client_id = orig_attrs['client_id'] + stripe.default_http_client = orig_attrs['default_http_client'] + + +@pytest.fixture +def request_mock(mocker): + return RequestMock(mocker) diff --git a/tests/helper.py b/tests/helper.py deleted file mode 100644 index 983647691..000000000 --- a/tests/helper.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import os -import sys -import unittest2 - -from distutils.version import StrictVersion - -import stripe -from stripe.six.moves.urllib.request import urlopen -from stripe.six.moves.urllib.error import HTTPError - -from tests.request_mock import RequestMock - - -MOCK_MINIMUM_VERSION = '0.16.1' -MOCK_PORT = os.environ.get('STRIPE_MOCK_PORT', 12111) - - -try: - resp = urlopen('http://localhost:%s/' % MOCK_PORT) - info = resp.info() -except HTTPError as e: - info = e.info() -except Exception: - sys.exit("Couldn't reach stripe-mock at `localhost:%s`. Is " - "it running? Please see README for setup instructions." % - MOCK_PORT) - -version = info.get('Stripe-Mock-Version') -if version != 'master' \ - and StrictVersion(version) < StrictVersion(MOCK_MINIMUM_VERSION): - sys.exit("Your version of stripe-mock (%s) is too old. The minimum " - "version to run this test suite is %s. Please " - "see its repository for upgrade instructions." % - (version, MOCK_MINIMUM_VERSION)) - - -class StripeTestCase(unittest2.TestCase): - def setUp(self): - super(StripeTestCase, self).setUp() - - stripe.orig_attrs = { - 'api_base': stripe.api_base, - 'api_key': stripe.api_key, - 'client_id': stripe.client_id, - 'default_http_client': stripe.default_http_client, - } - stripe.api_base = 'http://localhost:%s' % MOCK_PORT - stripe.api_key = 'sk_test_123' - stripe.client_id = 'ca_123' - - self.client = stripe.http_client.new_default_http_client() - stripe.default_http_client = self.client - - self.request_mock = RequestMock() - self.request_mock.start() - - def tearDown(self): - super(StripeTestCase, self).tearDown() - - self.request_mock.stop() - - self.client.close() - - stripe.api_base = stripe.orig_attrs['api_base'] - stripe.api_key = stripe.orig_attrs['api_key'] - stripe.client_id = stripe.orig_attrs['client_id'] - stripe.default_http_client = stripe.orig_attrs['default_http_client'] - - def stub_request(self, *args, **kwargs): - return self.request_mock.stub_request(*args, **kwargs) - - def assert_requested(self, *args, **kwargs): - return self.request_mock.assert_requested(*args, **kwargs) - - def assert_no_request(self): - return self.request_mock.assert_no_request() diff --git a/tests/request_mock.py b/tests/request_mock.py index 46c0d1713..968705dd6 100644 --- a/tests/request_mock.py +++ b/tests/request_mock.py @@ -1,33 +1,26 @@ from __future__ import absolute_import, division, print_function -from mock import patch, ANY - import stripe from stripe import six from stripe.stripe_response import StripeResponse class RequestMock(object): - def __init__(self): + def __init__(self, mocker): + self._mocker = mocker + self._real_request = stripe.api_requestor.APIRequestor.request self._stub_request_handler = StubRequestHandler() - def start(self): - self.constructor_patcher = patch( + self.constructor_patcher = self._mocker.patch( 'stripe.api_requestor.APIRequestor.__init__', side_effect=stripe.api_requestor.APIRequestor.__init__, autospec=True) - self.constructor_spy = self.constructor_patcher.start() - self.request_patcher = patch( + self.request_patcher = self._mocker.patch( 'stripe.api_requestor.APIRequestor.request', side_effect=self._patched_request, autospec=True) - self.request_spy = self.request_patcher.start() - - def stop(self): - self.request_patcher.stop() - self.constructor_patcher.stop() def _patched_request(self, requestor, method, url, *args, **kwargs): response = self._stub_request_handler.get_response(method, url) @@ -45,34 +38,37 @@ def assert_api_version(self, expected_api_version): # as a keyword argument in APIRequestor's constructor, not as a # positional argument. - if 'api_version' not in self.constructor_spy.call_args[1]: + if 'api_version' not in self.constructor_patcher.call_args[1]: msg = ("Expected APIRequestor to have been constructed with " "api_version='%s'. No API version was provided." % expected_api_version) raise AssertionError(msg) - actual_api_version = self.constructor_spy.call_args[1]['api_version'] + actual_api_version = \ + self.constructor_patcher.call_args[1]['api_version'] if actual_api_version != expected_api_version: msg = ("Expected APIRequestor to have been constructed with " "api_version='%s'. Constructed with api_version='%s' " "instead." % (expected_api_version, actual_api_version)) raise AssertionError(msg) - def assert_requested(self, method, url, params=ANY, headers=ANY): + def assert_requested(self, method, url, params=None, headers=None): + params = params or self._mocker.ANY + headers = headers or self._mocker.ANY called = False exception = None # Sadly, ANY does not match a missing optional argument, so we # check all the possible signatures of the request method possible_called_args = [ - (ANY, method, url), - (ANY, method, url, params), - (ANY, method, url, params, headers), + (self._mocker.ANY, method, url), + (self._mocker.ANY, method, url, params), + (self._mocker.ANY, method, url, params, headers), ] for args in possible_called_args: try: - self.request_spy.assert_called_with(*args) + self.request_patcher.assert_called_with(*args) except AssertionError as e: exception = e else: @@ -83,14 +79,14 @@ def assert_requested(self, method, url, params=ANY, headers=ANY): raise exception def assert_no_request(self): - if self.request_spy.call_count != 0: + if self.request_patcher.call_count != 0: msg = ("Expected 'request' to not have been called. " "Called %s times." % - (self.request_spy.call_count)) + (self.request_patcher.call_count)) raise AssertionError(msg) def reset_mock(self): - self.request_spy.reset_mock() + self.request_patcher.reset_mock() class StubRequestHandler(object): diff --git a/tests/test_api_requestor.py b/tests/test_api_requestor.py index b2d1f50b9..f18a1b565 100644 --- a/tests/test_api_requestor.py +++ b/tests/test_api_requestor.py @@ -1,19 +1,15 @@ from __future__ import absolute_import, division, print_function import datetime -import os -import unittest2 import tempfile -from mock import Mock, ANY +import pytest import stripe from stripe import six from stripe.stripe_response import StripeResponse from stripe import util -from tests.helper import StripeTestCase - from six.moves.urllib.parse import urlsplit @@ -67,7 +63,7 @@ def _keys_match(self, other): if self.request_method is not None and self.request_method in \ self.METHOD_EXTRA_KEYS: expected_keys.extend(self.METHOD_EXTRA_KEYS[self.request_method]) - return (sorted(other.keys()) == sorted(expected_keys)) + return sorted(other.keys()) == sorted(expected_keys) def _auth_match(self, other): return other['Authorization'] == "Bearer %s" % (self.api_key,) @@ -106,6 +102,9 @@ def __eq__(self, other): parsed = stripe.util.parse_qsl(query) return self.expected == sorted(parsed) + def __repr__(self): + return ("QueryMatcher(expected=%s)" % (repr(self.expected))) + class UrlMatcher(object): @@ -126,8 +125,11 @@ def __eq__(self, other): q_matcher = QueryMatcher(stripe.util.parse_qsl(self.exp_parts.query)) return q_matcher == other + def __repr__(self): + return ("UrlMatcher(exp_parts=%s)" % (repr(self.exp_parts))) -class APIRequestorRequestTests(StripeTestCase): + +class TestAPIRequestor(object): ENCODE_INPUTS = { 'dict': { 'astring': 'bar', @@ -168,42 +170,50 @@ class APIRequestorRequestTests(StripeTestCase): 'none': [], } - def setUp(self): - super(APIRequestorRequestTests, self).setUp() - - stripe.api_version = os.environ.get('STRIPE_API_VERSION', '2017-04-06') - - self.http_client = Mock(stripe.http_client.HTTPClient) - self.http_client._verify_ssl_certs = True - self.http_client.name = 'mockclient' - - self.requestor = stripe.api_requestor.APIRequestor( - client=self.http_client) - - def tearDown(self): - stripe.api_version = None - - super(APIRequestorRequestTests, self).tearDown() - - def mock_response(self, return_body, return_code, requestor=None, - headers=None): - if not requestor: - requestor = self.requestor - - self.http_client.request = Mock( - return_value=(return_body, return_code, headers or {})) - - def check_call(self, meth, abs_url=None, headers=None, - post_data=None, requestor=None): - if not abs_url: - abs_url = '%s%s' % (stripe.api_base, self.valid_path,) - if not requestor: - requestor = self.requestor - if not headers: - headers = APIHeaderMatcher(request_method=meth) - - self.http_client.request.assert_called_with( - meth, abs_url, headers, post_data) + @pytest.fixture(autouse=True) + def setup_stripe(self): + orig_attrs = { + 'api_key': stripe.api_key, + 'api_version': stripe.api_version, + } + stripe.api_key = 'sk_test_123' + stripe.api_version = '2017-12-14' + yield + stripe.api_key = orig_attrs['api_key'] + stripe.api_version = orig_attrs['api_version'] + + @pytest.fixture + def http_client(self, mocker): + http_client = mocker.Mock(stripe.http_client.HTTPClient) + http_client._verify_ssl_certs = True + http_client.name = 'mockclient' + return http_client + + @pytest.fixture + def requestor(self, http_client): + requestor = stripe.api_requestor.APIRequestor(client=http_client) + return requestor + + @pytest.fixture + def mock_response(self, mocker, http_client): + def mock_response(return_body, return_code, headers=None): + print(return_code) + http_client.request = mocker.Mock( + return_value=(return_body, return_code, headers or {})) + return mock_response + + @pytest.fixture + def check_call(self, http_client): + def check_call(method, abs_url=None, headers=None, + post_data=None): + if not abs_url: + abs_url = '%s%s' % (stripe.api_base, self.valid_path,) + if not headers: + headers = APIHeaderMatcher(request_method=method) + + http_client.request.assert_called_with( + method, abs_url, headers, post_data) + return check_call @property def valid_path(self): @@ -224,7 +234,7 @@ def encoder_check(self, key): expectation.sort() stk.sort() - self.assertEqual(expectation, stk) + assert stk == expectation, stk def _test_encode_naive_datetime(self): stk = [] @@ -235,18 +245,18 @@ def _test_encode_naive_datetime(self): # Naive datetimes will encode differently depending on your system # local time. Since we don't know the local time of your system, # we just check that naive encodings are within 24 hours of correct. - self.assertTrue(60 * 60 * 24 > abs(stk[0][1] - 1356994800)) + assert abs(stk[0][1] - 1356994800) <= 60 * 60 * 24 - def test_param_encoding(self): - self.mock_response('{}', 200) + def test_param_encoding(self, requestor, mock_response, check_call): + mock_response('{}', 200) - self.requestor.request('get', '', self.ENCODE_INPUTS) + requestor.request('get', '', self.ENCODE_INPUTS) expectation = [] for type_, values in six.iteritems(self.ENCODE_EXPECTATIONS): expectation.extend([(k % (type_,), str(v)) for k, v in values]) - self.check_call('get', QueryMatcher(expectation)) + check_call('get', QueryMatcher(expectation)) def test_dictionary_list_encoding(self): params = { @@ -259,10 +269,10 @@ def test_dictionary_list_encoding(self): encoded = list(stripe.api_requestor._api_encode(params)) key, value = encoded[0] - self.assertEqual('foo[0][bar]', key) - self.assertEqual('bat', value) + assert key == 'foo[0][bar]' + assert value == 'bat' - def test_url_construction(self): + def test_url_construction(self, requestor, mock_response, check_call): CASES = ( ('%s?foo=bar' % stripe.api_base, '', {'foo': 'bar'}), ('%s?foo=bar' % stripe.api_base, '?', {'foo': 'bar'}), @@ -280,32 +290,33 @@ def test_url_construction(self): ) for expected, url, params in CASES: - self.mock_response('{}', 200) + mock_response('{}', 200) - self.requestor.request('get', url, params) + requestor.request('get', url, params) - self.check_call('get', expected) + check_call('get', expected) - def test_empty_methods(self): + def test_empty_methods(self, requestor, mock_response, check_call): for meth in VALID_API_METHODS: - self.mock_response('{}', 200) + mock_response('{}', 200) - resp, key = self.requestor.request(meth, self.valid_path, {}) + resp, key = requestor.request(meth, self.valid_path, {}) if meth == 'post': post_data = '' else: post_data = None - self.check_call(meth, post_data=post_data) - self.assertTrue(isinstance(resp, StripeResponse)) + check_call(meth, post_data=post_data) + assert isinstance(resp, StripeResponse) - self.assertEqual({}, resp.data) - self.assertEqual(util.json.loads(resp.body), resp.data) + assert resp.data == {} + assert resp.data == util.json.loads(resp.body) - def test_methods_with_params_and_response(self): - for meth in VALID_API_METHODS: - self.mock_response('{"foo": "bar", "baz": 6}', 200) + def test_methods_with_params_and_response(self, requestor, mock_response, + check_call): + for method in VALID_API_METHODS: + mock_response('{"foo": "bar", "baz": 6}', 200) params = { 'alist': [1, 2, 3], @@ -315,72 +326,70 @@ def test_methods_with_params_and_response(self): encoded = ('adict%5Bfrobble%5D=bits&adatetime=1356994800&' 'alist%5B%5D=1&alist%5B%5D=2&alist%5B%5D=3') - resp, key = self.requestor.request(meth, self.valid_path, - params) - self.assertTrue(isinstance(resp, StripeResponse)) + resp, key = requestor.request(method, self.valid_path, params) + assert isinstance(resp, StripeResponse) - self.assertEqual({'foo': 'bar', 'baz': 6}, resp.data) - self.assertEqual(util.json.loads(resp.body), resp.data) + assert resp.data == {'foo': 'bar', 'baz': 6} + assert resp.data == util.json.loads(resp.body) - if meth == 'post': - self.check_call( - meth, + if method == 'post': + check_call( + method, post_data=QueryMatcher(stripe.util.parse_qsl(encoded))) else: abs_url = "%s%s?%s" % ( stripe.api_base, self.valid_path, encoded) - self.check_call(meth, abs_url=UrlMatcher(abs_url)) + check_call(method, abs_url=UrlMatcher(abs_url)) - def test_uses_headers(self): - self.mock_response('{}', 200) - self.requestor.request('get', self.valid_path, {}, {'foo': 'bar'}) - self.check_call('get', headers=APIHeaderMatcher(extra={'foo': 'bar'})) + def test_uses_headers(self, requestor, mock_response, check_call): + mock_response('{}', 200) + requestor.request('get', self.valid_path, {}, {'foo': 'bar'}) + check_call('get', headers=APIHeaderMatcher(extra={'foo': 'bar'})) - def test_uses_instance_key(self): + def test_uses_instance_key(self, http_client, mock_response, check_call): key = 'fookey' requestor = stripe.api_requestor.APIRequestor(key, - client=self.http_client) + client=http_client) - self.mock_response('{}', 200, requestor=requestor) + mock_response('{}', 200) resp, used_key = requestor.request('get', self.valid_path, {}) - self.check_call('get', headers=APIHeaderMatcher( - key, request_method='get'), requestor=requestor) - self.assertEqual(key, used_key) + check_call('get', headers=APIHeaderMatcher(key, request_method='get')) + assert used_key == key - def test_uses_instance_api_version(self): + def test_uses_instance_api_version(self, http_client, mock_response, + check_call): api_version = 'fooversion' requestor = stripe.api_requestor.APIRequestor(api_version=api_version, - client=self.http_client) + client=http_client) - self.mock_response('{}', 200, requestor=requestor) + mock_response('{}', 200) requestor.request('get', self.valid_path, {}) - self.check_call('get', headers=APIHeaderMatcher( - extra={'Stripe-Version': 'fooversion'}, request_method='get'), - requestor=requestor) + check_call('get', headers=APIHeaderMatcher( + extra={'Stripe-Version': 'fooversion'}, request_method='get')) - def test_uses_instance_account(self): + def test_uses_instance_account(self, http_client, mock_response, + check_call): account = 'acct_foo' requestor = stripe.api_requestor.APIRequestor(account=account, - client=self.http_client) + client=http_client) - self.mock_response('{}', 200, requestor=requestor) + mock_response('{}', 200) requestor.request('get', self.valid_path, {}) - self.check_call( + check_call( 'get', - requestor=requestor, headers=APIHeaderMatcher( extra={'Stripe-Account': account}, request_method='get' ), ) - def test_uses_app_info(self): + def test_uses_app_info(self, requestor, mock_response, check_call): try: old = stripe.app_info stripe.set_app_info( @@ -390,8 +399,8 @@ def test_uses_app_info(self): partner_id='partner_12345', ) - self.mock_response('{}', 200) - self.requestor.request('get', self.valid_path, {}) + mock_response('{}', 200) + requestor.request('get', self.valid_path, {}) ua = "Stripe/v1 PythonBindings/%s" % (stripe.version.VERSION,) ua += " MyAwesomePlugin/1.2.34 (https://myawesomeplugin.info)" @@ -404,135 +413,136 @@ def test_uses_app_info(self): 'partner_id': 'partner_12345', } ) - self.check_call('get', headers=header_matcher) + check_call('get', headers=header_matcher) finally: stripe.app_info = old - def test_fails_without_api_key(self): + def test_fails_without_api_key(self, requestor): stripe.api_key = None - self.assertRaises(stripe.error.AuthenticationError, - self.requestor.request, - 'get', self.valid_path, {}) + with pytest.raises(stripe.error.AuthenticationError): + requestor.request('get', self.valid_path, {}) - def test_invalid_request_error_404(self): - self.mock_response('{"error": {}}', 404) + def test_invalid_request_error_404(self, requestor, mock_response): + mock_response('{"error": {}}', 404) - with self.assertRaises(stripe.error.InvalidRequestError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.InvalidRequestError): + requestor.request('get', self.valid_path, {}) - def test_invalid_request_error_400(self): - self.mock_response('{"error": {}}', 400) + def test_invalid_request_error_400(self, requestor, mock_response): + mock_response('{"error": {}}', 400) - with self.assertRaises(stripe.error.InvalidRequestError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.InvalidRequestError): + requestor.request('get', self.valid_path, {}) - def test_idempotency_error(self): - self.mock_response('{"error": {"type": "idempotency_error"}}', 400) + def test_idempotency_error(self, requestor, mock_response): + mock_response('{"error": {"type": "idempotency_error"}}', 400) - with self.assertRaises(stripe.error.IdempotencyError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.IdempotencyError): + requestor.request('get', self.valid_path, {}) - def test_authentication_error(self): - self.mock_response('{"error": {}}', 401) + def test_authentication_error(self, requestor, mock_response): + mock_response('{"error": {}}', 401) - with self.assertRaises(stripe.error.AuthenticationError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.AuthenticationError): + requestor.request('get', self.valid_path, {}) - def test_permissions_error(self): - self.mock_response('{"error": {}}', 403) + def test_permissions_error(self, requestor, mock_response): + mock_response('{"error": {}}', 403) - with self.assertRaises(stripe.error.PermissionError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.PermissionError): + requestor.request('get', self.valid_path, {}) - def test_card_error(self): - self.mock_response('{"error": {"code": "invalid_expiry_year"}}', 402) + def test_card_error(self, requestor, mock_response): + mock_response('{"error": {"code": "invalid_expiry_year"}}', 402) - with self.assertRaises(stripe.error.CardError) as ctx: - self.requestor.request('get', self.valid_path, {}) - self.assertEqual('invalid_expiry_year', ctx.exception.code) + with pytest.raises(stripe.error.CardError) as excinfo: + requestor.request('get', self.valid_path, {}) + assert excinfo.value.code == 'invalid_expiry_year' - def test_rate_limit_error(self): - self.mock_response('{"error": {}}', 429) + def test_rate_limit_error(self, requestor, mock_response): + mock_response('{"error": {}}', 429) - with self.assertRaises(stripe.error.RateLimitError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.RateLimitError): + requestor.request('get', self.valid_path, {}) - def test_old_rate_limit_error(self): + def test_old_rate_limit_error(self, requestor, mock_response): """ Tests legacy rate limit error pre-2015-09-18 """ - self.mock_response('{"error": {"code":"rate_limit"}}', 400) + mock_response('{"error": {"code":"rate_limit"}}', 400) - with self.assertRaises(stripe.error.RateLimitError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.RateLimitError): + requestor.request('get', self.valid_path, {}) - def test_server_error(self): - self.mock_response('{"error": {}}', 500) + def test_server_error(self, requestor, mock_response): + mock_response('{"error": {}}', 500) - with self.assertRaises(stripe.error.APIError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.APIError): + requestor.request('get', self.valid_path, {}) - def test_invalid_json(self): - self.mock_response('{', 200) + def test_invalid_json(self, requestor, mock_response): + mock_response('{', 200) - with self.assertRaises(stripe.error.APIError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.error.APIError): + requestor.request('get', self.valid_path, {}) - def test_invalid_method(self): - with self.assertRaises(stripe.error.APIConnectionError): - self.requestor.request('foo', 'bar') + def test_invalid_method(self, requestor): + with pytest.raises(stripe.error.APIConnectionError): + requestor.request('foo', 'bar') - def test_oauth_invalid_requestor_error(self): - self.mock_response('{"error": "invalid_request"}', 400) + def test_oauth_invalid_requestor_error(self, requestor, mock_response): + mock_response('{"error": "invalid_request"}', 400) - with self.assertRaises(stripe.oauth_error.InvalidRequestError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.oauth_error.InvalidRequestError): + requestor.request('get', self.valid_path, {}) - def test_invalid_client_error(self): - self.mock_response('{"error": "invalid_client"}', 401) + def test_invalid_client_error(self, requestor, mock_response): + mock_response('{"error": "invalid_client"}', 401) - with self.assertRaises(stripe.oauth_error.InvalidClientError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.oauth_error.InvalidClientError): + requestor.request('get', self.valid_path, {}) - def test_invalid_grant_error(self): - self.mock_response('{"error": "invalid_grant"}', 400) + def test_invalid_grant_error(self, requestor, mock_response): + mock_response('{"error": "invalid_grant"}', 400) - with self.assertRaises(stripe.oauth_error.InvalidGrantError): - self.requestor.request('get', self.valid_path, {}) + with pytest.raises(stripe.oauth_error.InvalidGrantError): + requestor.request('get', self.valid_path, {}) - def test_raw_request_with_file_param(self): + def test_raw_request_with_file_param(self, requestor, mock_response): test_file = tempfile.NamedTemporaryFile() test_file.write('\u263A'.encode('utf-16')) test_file.seek(0) params = {'file': test_file, 'purpose': 'dispute_evidence'} supplied_headers = {'Content-Type': 'multipart/form-data'} - self.mock_response('{}', 200) - self.requestor.request('post', '/v1/files', params, supplied_headers) - + mock_response('{}', 200) + requestor.request('post', '/v1/files', params, supplied_headers) -class DefaultClientTests(unittest2.TestCase): - def setUp(self): - stripe.default_http_client = None - stripe.api_key = 'foo' +class TestDefaultClient(object): + @pytest.fixture(autouse=True) + def setup_stripe(self): + orig_attrs = { + 'api_key': stripe.api_key, + 'default_http_client': stripe.default_http_client, + } + stripe.api_key = 'sk_test_123' + yield + stripe.api_key = orig_attrs['api_key'] + stripe.default_http_client = orig_attrs['default_http_client'] - def test_default_http_client_called(self): - hc = Mock(stripe.http_client.HTTPClient) + def test_default_http_client_called(self, mocker): + hc = mocker.Mock(stripe.http_client.HTTPClient) hc._verify_ssl_certs = True hc.name = 'mockclient' - hc.request = Mock(return_value=("{}", 200, {})) + hc.request = mocker.Mock(return_value=("{}", 200, {})) stripe.default_http_client = hc stripe.Charge.list(limit=3) hc.request.assert_called_with( - 'get', 'https://api.stripe.com/v1/charges?limit=3', ANY, None) - - def tearDown(self): - stripe.api_key = None - stripe.default_http_client = None - - -if __name__ == '__main__': - unittest2.main() + 'get', + 'https://api.stripe.com/v1/charges?limit=3', + mocker.ANY, + None + ) diff --git a/tests/test_error.py b/tests/test_error.py index 91b74a3c8..652f9455d 100644 --- a/tests/test_error.py +++ b/tests/test_error.py @@ -3,65 +3,62 @@ from __future__ import absolute_import, division, print_function from stripe import CardError, StripeError, six -from tests.helper import StripeTestCase -class StripeErrorTests(StripeTestCase): - +class TestStripeError(object): def test_formatting(self): err = StripeError(u'öre') - self.assertEqual(u'öre', six.text_type(err)) + assert six.text_type(err) == u'öre' if six.PY2: - self.assertEqual('\xc3\xb6re', str(err)) + assert str(err) == '\xc3\xb6re' else: - self.assertEqual(u'öre', str(err)) + assert str(err) == u'öre' def test_formatting_with_request_id(self): err = StripeError(u'öre', headers={'request-id': '123'}) - self.assertEqual(u'Request 123: öre', six.text_type(err)) + assert six.text_type(err) == u'Request 123: öre' if six.PY2: - self.assertEqual('Request 123: \xc3\xb6re', str(err)) + assert str(err) == 'Request 123: \xc3\xb6re' else: - self.assertEqual(u'Request 123: öre', str(err)) + assert str(err) == u'Request 123: öre' def test_formatting_with_message_none_and_request_id(self): err = StripeError(None, headers={'request-id': '123'}) - self.assertEqual(u'Request 123: ', six.text_type(err)) + assert six.text_type(err) == u'Request 123: ' if six.PY2: - self.assertEqual('Request 123: ', str(err)) + assert str(err) == 'Request 123: ' else: - self.assertEqual('Request 123: ', str(err)) + assert str(err) == 'Request 123: ' def test_formatting_with_message_none_and_request_id_none(self): err = StripeError(None) - self.assertEqual(u'', six.text_type(err)) + assert six.text_type(err) == u'' if six.PY2: - self.assertEqual('', str(err)) + assert str(err) == '' else: - self.assertEqual('', str(err)) + assert str(err) == u'' def test_repr(self): err = StripeError(u'öre', headers={'request-id': '123'}) if six.PY2: - self.assertEquals(repr(err), ( - "StripeError(message=u'\\xf6re', http_status=None, " - "request_id='123')")) + assert repr(err) == \ + "StripeError(message=u'\\xf6re', http_status=None, " \ + "request_id='123')" else: - self.assertEquals(repr(err), ( - "StripeError(message='öre', http_status=None, " - "request_id='123')")) - + assert repr(err) == \ + "StripeError(message='öre', http_status=None, " \ + "request_id='123')" -class StripeErrorWithParamCodeTests(StripeTestCase): +class TestStripeErrorWithParamCode(object): def test_repr(self): err = CardError(u'öre', param='cparam', code='ccode', http_status=403, headers={'request-id': '123'}) if six.PY2: - self.assertEquals(repr(err), ( - "CardError(message=u'\\xf6re', param='cparam', code='ccode', " - "http_status=403, request_id='123')")) + assert repr(err) == \ + "CardError(message=u'\\xf6re', param='cparam', " \ + "code='ccode', http_status=403, request_id='123')" else: - self.assertEquals(repr(err), ( - "CardError(message='öre', param='cparam', code='ccode', " - "http_status=403, request_id='123')")) + assert repr(err) == \ + "CardError(message='öre', param='cparam', code='ccode', " \ + "http_status=403, request_id='123')" diff --git a/tests/test_http_client.py b/tests/test_http_client.py index 678dd6254..6271bef20 100644 --- a/tests/test_http_client.py +++ b/tests/test_http_client.py @@ -1,7 +1,6 @@ from __future__ import absolute_import, division, print_function -import unittest2 -from mock import MagicMock, Mock, patch +import pytest import stripe from stripe import six @@ -9,39 +8,24 @@ VALID_API_METHODS = ('get', 'post', 'delete') -class StripeClientTestCase(unittest2.TestCase): +class StripeClientTestCase(object): REQUEST_LIBRARIES = ['urlfetch', 'requests', 'pycurl', 'urllib.request'] - def setUp(self): - super(StripeClientTestCase, self).setUp() - - self.request_patchers = {} - self.request_mocks = {} + @pytest.fixture + def request_mocks(self, mocker): + request_mocks = {} for lib in self.REQUEST_LIBRARIES: - patcher = patch("stripe.http_client.%s" % (lib,)) - - self.request_mocks[lib] = patcher.start() - self.request_patchers[lib] = patcher - - def tearDown(self): - super(StripeClientTestCase, self).tearDown() - - for patcher in six.itervalues(self.request_patchers): - patcher.stop() - + request_mocks[lib] = mocker.patch("stripe.http_client.%s" % (lib,)) + return request_mocks -class HttpClientTests(StripeClientTestCase): - def setUp(self): - super(HttpClientTests, self).setUp() - - self.original_filters = stripe.http_client.warnings.filters[:] +class TestNewDefaultHttpClient(StripeClientTestCase): + @pytest.fixture(autouse=True) + def setup_warnings(self, request_mocks): + original_filters = stripe.http_client.warnings.filters[:] stripe.http_client.warnings.simplefilter('ignore') - - def tearDown(self): - stripe.http_client.warnings.filters = self.original_filters - - super(HttpClientTests, self).tearDown() + yield + stripe.http_client.warnings.filters = original_filters def check_default(self, none_libs, expected): for lib in none_libs: @@ -49,7 +33,7 @@ def check_default(self, none_libs, expected): inst = stripe.http_client.new_default_http_client() - self.assertTrue(isinstance(inst, expected)) + assert isinstance(inst, expected) def test_new_default_http_client_urlfetch(self): self.check_default((), @@ -68,316 +52,352 @@ def test_new_default_http_client_urllib2(self): stripe.http_client.Urllib2Client) -class ClientTestBase(): - - @property - def request_mock(self): - return self.request_mocks[self.request_client.name] +class ClientTestBase(object): + @pytest.fixture + def request_mock(self, request_mocks): + return request_mocks[self.REQUEST_CLIENT.name] @property def valid_url(self, path='/foo'): return 'https://api.stripe.com%s' % (path,) def make_request(self, method, url, headers, post_data): - client = self.request_client(verify_ssl_certs=True) + client = self.REQUEST_CLIENT(verify_ssl_certs=True) return client.request(method, url, headers, post_data) - def mock_response(self, body, code): - raise NotImplementedError( - 'You must implement this in your test subclass') - - def mock_error(self, error): - raise NotImplementedError( - 'You must implement this in your test subclass') - - def check_call(self, meth, abs_url, headers, params): - raise NotImplementedError( - 'You must implement this in your test subclass') - - def test_request(self): - self.mock_response(self.request_mock, '{"foo": "baz"}', 200) - - for meth in VALID_API_METHODS: + @pytest.fixture + def mock_response(self): + def mock_response(mock, body, code): + raise NotImplementedError( + 'You must implement this in your test subclass') + return mock_response + + @pytest.fixture + def mock_error(self): + def mock_error(mock, error): + raise NotImplementedError( + 'You must implement this in your test subclass') + return mock_error + + @pytest.fixture + def check_call(self): + def check_call(mock, method, abs_url, headers, params): + raise NotImplementedError( + 'You must implement this in your test subclass') + return check_call + + def test_request(self, request_mock, mock_response, check_call): + mock_response(request_mock, '{"foo": "baz"}', 200) + + for method in VALID_API_METHODS: abs_url = self.valid_url data = '' - if meth != 'post': + if method != 'post': abs_url = '%s?%s' % (abs_url, data) data = None headers = {'my-header': 'header val'} body, code, _ = self.make_request( - meth, abs_url, headers, data) + method, abs_url, headers, data) - self.assertEqual(200, code) - self.assertEqual('{"foo": "baz"}', body) + assert code == 200 + assert body == '{"foo": "baz"}' - self.check_call(self.request_mock, meth, abs_url, - data, headers) + check_call(request_mock, method, abs_url, data, headers) - def test_exception(self): - self.mock_error(self.request_mock) - self.assertRaises(stripe.error.APIConnectionError, - self.make_request, - 'get', self.valid_url, {}, None) + def test_exception(self, request_mock, mock_error): + mock_error(request_mock) + with pytest.raises(stripe.error.APIConnectionError): + self.make_request('get', self.valid_url, {}, None) class RequestsVerify(object): - def __eq__(self, other): return other and other.endswith('stripe/data/ca-certificates.crt') -class RequestsClientTests(StripeClientTestCase, ClientTestBase): - request_client = stripe.http_client.RequestsClient +class TestRequestsClient(StripeClientTestCase, ClientTestBase): + REQUEST_CLIENT = stripe.http_client.RequestsClient - def setUp(self): - super(RequestsClientTests, self).setUp() - self.session = MagicMock() + @pytest.fixture + def session(self, mocker, request_mocks): + return mocker.MagicMock() - def test_timeout(self): - headers = {'my-header': 'header val'} - data = '' - self.mock_response(self.request_mock, '{"foo": "baz"}', 200) - self.make_request('POST', self.valid_url, - headers, data, timeout=5) + @pytest.fixture + def mock_response(self, mocker, session): + def mock_response(mock, body, code): + result = mocker.Mock() + result.content = body + result.status_code = code + + session.request = mocker.MagicMock(return_value=result) + mock.Session = mocker.MagicMock(return_value=session) + return mock_response + + @pytest.fixture + def mock_error(self, mocker, session): + def mock_error(mock): + mock.exceptions.RequestException = Exception + session.request.side_effect = mock.exceptions.RequestException() + mock.Session = mocker.MagicMock(return_value=session) + return mock_error - self.check_call(None, 'POST', self.valid_url, - data, headers, timeout=5) + # Note that unlike other modules, we don't use the "mock" argument here + # because we need to run the request call against the internal mock + # session. + @pytest.fixture + def check_call(self, session): + def check_call(mock, method, url, post_data, headers, timeout=80): + session.request. \ + assert_called_with(method, url, + headers=headers, + data=post_data, + verify=RequestsVerify(), + proxies={"http": "http://slap/", + "https": "http://slap/"}, + timeout=timeout) + return check_call def make_request(self, method, url, headers, post_data, timeout=80): - client = self.request_client(verify_ssl_certs=True, + client = self.REQUEST_CLIENT(verify_ssl_certs=True, timeout=timeout, proxy='http://slap/') - return client.request(method, url, headers, post_data) - def mock_response(self, mock, body, code): - result = Mock() - result.content = body - result.status_code = code - - self.session.request = MagicMock(return_value=result) - mock.Session = MagicMock(return_value=self.session) + def test_timeout(self, request_mock, mock_response, check_call): + headers = {'my-header': 'header val'} + data = '' + mock_response(request_mock, '{"foo": "baz"}', 200) + self.make_request('POST', self.valid_url, + headers, data, timeout=5) - def mock_error(self, mock): - mock.exceptions.RequestException = Exception - self.session.request.side_effect = mock.exceptions.RequestException() - mock.Session = MagicMock(return_value=self.session) + check_call(None, 'POST', self.valid_url, data, headers, timeout=5) - # Note that unlike other modules, we don't use the "mock" argument here - # because we need to run the request call against the internal mock - # session. - def check_call(self, mock, meth, url, post_data, headers, timeout=80): - self.session.request. \ - assert_called_with(meth, url, - headers=headers, - data=post_data, - verify=RequestsVerify(), - proxies={"http": "http://slap/", - "https": "http://slap/"}, - timeout=timeout) +class TestUrlFetchClient(StripeClientTestCase, ClientTestBase): + REQUEST_CLIENT = stripe.http_client.UrlFetchClient -class UrlFetchClientTests(StripeClientTestCase, ClientTestBase): - request_client = stripe.http_client.UrlFetchClient + @pytest.fixture + def mock_response(self, mocker): + def mock_response(mock, body, code): + result = mocker.Mock() + result.content = body + result.status_code = code - def mock_response(self, mock, body, code): - result = Mock() - result.content = body - result.status_code = code + mock.fetch = mocker.Mock(return_value=result) + return mock_response - mock.fetch = Mock(return_value=result) + @pytest.fixture + def mock_error(self): + def mock_error(mock): + mock.Error = mock.InvalidURLError = Exception + mock.fetch.side_effect = mock.InvalidURLError() + return mock_error - def mock_error(self, mock): - mock.Error = mock.InvalidURLError = Exception - mock.fetch.side_effect = mock.InvalidURLError() + @pytest.fixture + def check_call(self): + def check_call(mock, method, url, post_data, headers): + mock.fetch.assert_called_with( + url=url, + method=method, + headers=headers, + validate_certificate=True, + deadline=55, + payload=post_data + ) + return check_call - def check_call(self, mock, meth, url, post_data, headers): - mock.fetch.assert_called_with( - url=url, - method=meth, - headers=headers, - validate_certificate=True, - deadline=55, - payload=post_data - ) - -class Urllib2ClientTests(StripeClientTestCase, ClientTestBase): - request_client = stripe.http_client.Urllib2Client +class TestUrllib2Client(StripeClientTestCase, ClientTestBase): + REQUEST_CLIENT = stripe.http_client.Urllib2Client def make_request(self, method, url, headers, post_data, proxy=None): - self.client = self.request_client(verify_ssl_certs=True, + self.client = self.REQUEST_CLIENT(verify_ssl_certs=True, proxy=proxy) self.proxy = proxy return self.client.request(method, url, headers, post_data) - def mock_response(self, mock, body, code): - response = Mock - response.read = Mock(return_value=body) - response.code = code - response.info = Mock(return_value={}) - - self.request_object = Mock() - mock.Request = Mock(return_value=self.request_object) - - mock.urlopen = Mock(return_value=response) - - opener = Mock - opener.open = Mock(return_value=response) - mock.build_opener = Mock(return_value=opener) - mock.build_opener.open = opener.open - mock.ProxyHandler = Mock(return_value=opener) - - mock.urlopen = Mock(return_value=response) - - def mock_error(self, mock): - mock.urlopen.side_effect = ValueError - mock.build_opener().open.side_effect = ValueError - mock.build_opener.reset_mock() - - def check_call(self, mock, meth, url, post_data, headers): - if six.PY3 and isinstance(post_data, six.string_types): - post_data = post_data.encode('utf-8') - - mock.Request.assert_called_with(url, post_data, headers) - - if (self.client._proxy): - self.assertTrue(type(self.client._proxy) is dict) - mock.ProxyHandler.assert_called_with(self.client._proxy) - mock.build_opener.open.assert_called_with(self.request_object) - self.assertTrue(not mock.urlopen.called) - - if (not self.client._proxy): - mock.urlopen.assert_called_with(self.request_object) - self.assertTrue(not mock.build_opener.called) - self.assertTrue(not mock.build_opener.open.called) - - -class Urllib2ClientHttpsProxyTests(Urllib2ClientTests): + @pytest.fixture + def mock_response(self, mocker): + def mock_response(mock, body, code): + response = mocker.Mock() + response.read = mocker.Mock(return_value=body) + response.code = code + response.info = mocker.Mock(return_value={}) + + self.request_object = mocker.Mock() + mock.Request = mocker.Mock(return_value=self.request_object) + + mock.urlopen = mocker.Mock(return_value=response) + + opener = mocker.Mock() + opener.open = mocker.Mock(return_value=response) + mock.build_opener = mocker.Mock(return_value=opener) + mock.build_opener.open = opener.open + mock.ProxyHandler = mocker.Mock(return_value=opener) + + mock.urlopen = mocker.Mock(return_value=response) + return mock_response + + @pytest.fixture + def mock_error(self): + def mock_error(mock): + mock.urlopen.side_effect = ValueError + mock.build_opener().open.side_effect = ValueError + mock.build_opener.reset_mock() + return mock_error + + @pytest.fixture + def check_call(self): + def check_call(mock, method, url, post_data, headers): + if six.PY3 and isinstance(post_data, six.string_types): + post_data = post_data.encode('utf-8') + + mock.Request.assert_called_with(url, post_data, headers) + + if self.client._proxy: + assert type(self.client._proxy) is dict + mock.ProxyHandler.assert_called_with(self.client._proxy) + mock.build_opener.open.assert_called_with(self.request_object) + assert not mock.urlopen.called + + if not self.client._proxy: + mock.urlopen.assert_called_with(self.request_object) + assert not mock.build_opener.called + assert not mock.build_opener.open.called + return check_call + + +class TestUrllib2ClientHttpsProxy(TestUrllib2Client): def make_request(self, method, url, headers, post_data, proxy=None): - return super(Urllib2ClientHttpsProxyTests, self).make_request( + return super(TestUrllib2ClientHttpsProxy, self).make_request( method, url, headers, post_data, {"http": "http://slap/", "https": "http://slap/"}) -class Urllib2ClientHttpProxyTests(Urllib2ClientTests): +class TestUrllib2ClientHttpProxy(TestUrllib2Client): def make_request(self, method, url, headers, post_data, proxy=None): - return super(Urllib2ClientHttpProxyTests, self).make_request( + return super(TestUrllib2ClientHttpProxy, self).make_request( method, url, headers, post_data, "http://slap/") -class PycurlClientTests(StripeClientTestCase, ClientTestBase): - request_client = stripe.http_client.PycurlClient +class TestPycurlClient(StripeClientTestCase, ClientTestBase): + REQUEST_CLIENT = stripe.http_client.PycurlClient def make_request(self, method, url, headers, post_data, proxy=None): - self.client = self.request_client(verify_ssl_certs=True, + self.client = self.REQUEST_CLIENT(verify_ssl_certs=True, proxy=proxy) self.proxy = proxy return self.client.request(method, url, headers, post_data) - @property - def request_mock(self): - if not hasattr(self, 'curl_mock'): - lib_mock = self.request_mocks[self.request_client.name] - - self.curl_mock = Mock() - - lib_mock.Curl = Mock(return_value=self.curl_mock) - - return self.curl_mock - - def setUp(self): - super(PycurlClientTests, self).setUp() - - self.bio_patcher = patch('stripe.util.io.BytesIO') - - bio_mock = Mock() - self.bio_patcher.start().return_value = bio_mock - self.bio_getvalue = bio_mock.getvalue - - def tearDown(self): - super(PycurlClientTests, self).tearDown() - - self.bio_patcher.stop() - - def mock_response(self, mock, body, code): - self.bio_getvalue.return_value = body.encode('utf-8') - - mock.getinfo.return_value = code - - def mock_error(self, mock): - class FakeException(BaseException): - @property - def args(self): - return ('foo', 'bar') - - stripe.http_client.pycurl.error = FakeException - mock.perform.side_effect = stripe.http_client.pycurl.error - - def check_call(self, mock, meth, url, post_data, headers): - lib_mock = self.request_mocks[self.request_client.name] - - # A note on methodology here: we don't necessarily need to verify - # _every_ call to setopt, but check a few of them to make sure the - # right thing is happening. Keep an eye specifically on conditional - # statements where things are more likely to go wrong. - - self.curl_mock.setopt.assert_any_call(lib_mock.NOSIGNAL, 1) - self.curl_mock.setopt.assert_any_call(lib_mock.URL, - stripe.util.utf8(url)) - - if meth == 'get': - self.curl_mock.setopt.assert_any_call(lib_mock.HTTPGET, 1) - elif meth == 'post': - self.curl_mock.setopt.assert_any_call(lib_mock.POST, 1) - else: - self.curl_mock.setopt.assert_any_call(lib_mock.CUSTOMREQUEST, - meth.upper()) - - self.curl_mock.perform.assert_any_call() - - -class PycurlClientHttpProxyTests(PycurlClientTests): + @pytest.fixture + def curl_mock(self, mocker): + return mocker.Mock() + + @pytest.fixture + def request_mock(self, mocker, request_mocks, curl_mock): + lib_mock = request_mocks[self.REQUEST_CLIENT.name] + lib_mock.Curl = mocker.Mock(return_value=curl_mock) + return curl_mock + + @pytest.fixture + def bio_getvalue(self, mocker): + bio_patcher = mocker.patch('stripe.util.io.BytesIO') + bio_mock = mocker.Mock() + bio_patcher.return_value = bio_mock + bio_getvalue = bio_mock.getvalue + return bio_getvalue + + @pytest.fixture + def mock_response(self, bio_getvalue): + def mock_response(mock, body, code): + bio_getvalue.return_value = body.encode('utf-8') + mock.getinfo.return_value = code + return mock_response + + @pytest.fixture + def mock_error(self): + def mock_error(mock): + class FakeException(BaseException): + @property + def args(self): + return ('foo', 'bar') + + stripe.http_client.pycurl.error = FakeException + mock.perform.side_effect = stripe.http_client.pycurl.error + return mock_error + + @pytest.fixture + def check_call(self, request_mocks): + def check_call(mock, method, url, post_data, headers): + lib_mock = request_mocks[self.REQUEST_CLIENT.name] + + # A note on methodology here: we don't necessarily need to verify + # _every_ call to setopt, but check a few of them to make sure the + # right thing is happening. Keep an eye specifically on conditional + # statements where things are more likely to go wrong. + + mock.setopt.assert_any_call(lib_mock.NOSIGNAL, 1) + mock.setopt.assert_any_call(lib_mock.URL, stripe.util.utf8(url)) + + if method == 'get': + mock.setopt.assert_any_call(lib_mock.HTTPGET, 1) + elif method == 'post': + mock.setopt.assert_any_call(lib_mock.POST, 1) + else: + mock.setopt.assert_any_call(lib_mock.CUSTOMREQUEST, + method.upper()) + + mock.perform.assert_any_call() + return check_call + + +class TestPycurlClientHttpProxy(TestPycurlClient): def make_request(self, method, url, headers, post_data, proxy=None): - return super(PycurlClientHttpProxyTests, self).make_request( + return super(TestPycurlClientHttpProxy, self).make_request( method, url, headers, post_data, "http://user:withPwd@slap:8888/") - def check_call(self, mock, meth, url, post_data, headers): - lib_mock = self.request_mocks[self.request_client.name] + @pytest.fixture + def check_call(self, request_mocks, curl_mock): + def check_call(mock, meth, url, post_data, headers): + lib_mock = request_mocks[self.REQUEST_CLIENT.name] - self.curl_mock.setopt.assert_any_call(lib_mock.PROXY, "slap") - self.curl_mock.setopt.assert_any_call(lib_mock.PROXYPORT, 8888) - self.curl_mock.setopt.assert_any_call(lib_mock.PROXYUSERPWD, - "user:withPwd") + curl_mock.setopt.assert_any_call(lib_mock.PROXY, "slap") + curl_mock.setopt.assert_any_call(lib_mock.PROXYPORT, 8888) + curl_mock.setopt.assert_any_call(lib_mock.PROXYUSERPWD, + "user:withPwd") - super(PycurlClientHttpProxyTests, self).check_call( + super(TestPycurlClientHttpProxy, self).check_call(request_mocks)( mock, meth, url, post_data, headers) + return check_call -class PycurlClientHttpsProxyTests(PycurlClientTests): +class TestPycurlClientHttpsProxy(TestPycurlClient): def make_request(self, method, url, headers, post_data, proxy=None): - return super(PycurlClientHttpsProxyTests, self).make_request( + return super(TestPycurlClientHttpsProxy, self).make_request( method, url, headers, post_data, {"http": "http://slap:8888/", "https": "http://slap2:444/"}) - def check_call(self, mock, meth, url, post_data, headers): - lib_mock = self.request_mocks[self.request_client.name] + @pytest.fixture + def check_call(self, request_mocks, curl_mock): + def check_call(mock, meth, url, post_data, headers): + lib_mock = request_mocks[self.REQUEST_CLIENT.name] - self.curl_mock.setopt.assert_any_call(lib_mock.PROXY, "slap2") - self.curl_mock.setopt.assert_any_call(lib_mock.PROXYPORT, 444) + curl_mock.setopt.assert_any_call(lib_mock.PROXY, "slap2") + curl_mock.setopt.assert_any_call(lib_mock.PROXYPORT, 444) - super(PycurlClientHttpsProxyTests, self).check_call( + super(TestPycurlClientHttpsProxy, self).check_call(request_mocks)( mock, meth, url, post_data, headers) + return check_call -class APIEncodeTest(StripeClientTestCase): +class TestAPIEncode(StripeClientTestCase): def test_encode_dict(self): body = { @@ -391,8 +411,8 @@ def test_encode_dict(self): values = [t for t in stripe.api_requestor._api_encode(body)] - self.assertTrue(('foo[dob][month]', 1) in values) - self.assertTrue(('foo[name]', 'bat') in values) + assert ('foo[dob][month]', 1) in values + assert ('foo[name]', 'bat') in values def test_encode_array(self): body = { @@ -406,5 +426,5 @@ def test_encode_array(self): values = [t for t in stripe.api_requestor._api_encode(body)] - self.assertTrue(('foo[][dob][month]', 1) in values) - self.assertTrue(('foo[][name]', 'bat') in values) + assert ('foo[][dob][month]', 1) in values + assert ('foo[][name]', 'bat') in values diff --git a/tests/test_multipart_data_generator.py b/tests/test_multipart_data_generator.py index 300effd7f..18064435b 100644 --- a/tests/test_multipart_data_generator.py +++ b/tests/test_multipart_data_generator.py @@ -6,11 +6,9 @@ from stripe import six from stripe.multipart_data_generator import MultipartDataGenerator -from tests.helper import StripeTestCase -class MultipartDataGeneratorTests(StripeTestCase): - +class TestMultipartDataGenerator(object): def run_test_multipart_data_with_file(self, test_file): params = { "key1": b"ASCII value", @@ -24,18 +22,18 @@ def run_test_multipart_data_with_file(self, test_file): if six.PY3: http_body = http_body.decode('utf-8') - self.assertTrue(re.search( - r"Content-Disposition: form-data; name=\"key1\"", http_body)) - self.assertTrue(re.search(r"ASCII value", http_body)) - self.assertTrue(re.search( - r"Content-Disposition: form-data; name=\"key2\"", http_body)) - self.assertTrue(re.search(r"Üñìçôdé value", http_body)) - self.assertTrue(re.search( + assert re.search( + r"Content-Disposition: form-data; name=\"key1\"", http_body) + assert re.search(r"ASCII value", http_body) + assert re.search( + r"Content-Disposition: form-data; name=\"key2\"", http_body) + assert re.search(r"Üñìçôdé value", http_body) + assert re.search( r"Content-Disposition: form-data; name=\"key3\"; " r"filename=\".+\"", - http_body)) - self.assertTrue(re.search( - r"Content-Type: application/octet-stream", http_body)) + http_body) + assert re.search( + r"Content-Type: application/octet-stream", http_body) test_file.seek(0) file_contents = test_file.read() @@ -43,7 +41,7 @@ def run_test_multipart_data_with_file(self, test_file): if six.PY3 and isinstance(file_contents, bytes): file_contents = file_contents.decode('utf-8') - self.assertNotEqual(-1, http_body.find(file_contents)) + assert http_body.find(file_contents) != -1 def test_multipart_data_file_text(self): with open(__file__, mode='r') as test_file: diff --git a/tests/test_oauth.py b/tests/test_oauth.py index 080c10487..671b87003 100644 --- a/tests/test_oauth.py +++ b/tests/test_oauth.py @@ -3,11 +3,10 @@ from six.moves.urllib.parse import parse_qs, urlparse import stripe -from tests.helper import StripeTestCase -class OAuthTests(StripeTestCase): - def test_authorize_url(self): +class TestOAuth(object): + def test_authorize_url(self, request_mock): url = stripe.OAuth.authorize_url( scope='read_write', state='csrf_token', @@ -20,21 +19,19 @@ def test_authorize_url(self): o = urlparse(url) params = parse_qs(o.query) - self.assertEqual('https', o.scheme) - self.assertEqual('connect.stripe.com', o.netloc) - self.assertEqual('/oauth/authorize', o.path) + assert o.scheme == 'https' + assert o.netloc == 'connect.stripe.com' + assert o.path == '/oauth/authorize' - self.assertEqual(['ca_123'], params['client_id']) - self.assertEqual(['read_write'], params['scope']) - self.assertEqual(['test@example.com'], params['stripe_user[email]']) - self.assertEqual( - ['https://example.com/profile/test'], - params['stripe_user[url]'] - ) - self.assertEqual(['US'], params['stripe_user[country]']) + assert params['client_id'] == ['ca_123'] + assert params['scope'] == ['read_write'] + assert params['stripe_user[email]'] == ['test@example.com'] + assert params['stripe_user[url]'] == \ + ['https://example.com/profile/test'] + assert params['stripe_user[country]'] == ['US'] - def test_token(self): - self.stub_request( + def test_token(self, request_mock): + request_mock.stub_request( 'post', '/oauth/token', { @@ -52,7 +49,7 @@ def test_token(self): grant_type='authorization_code', code='this_is_an_authorization_code', ) - self.assert_requested( + request_mock.assert_requested( 'post', '/oauth/token', { @@ -60,10 +57,10 @@ def test_token(self): 'code': 'this_is_an_authorization_code', } ) - self.assertEqual('sk_access_token', resp['access_token']) + assert resp['access_token'] == 'sk_access_token' - def test_deauthorize(self): - self.stub_request( + def test_deauthorize(self, request_mock): + request_mock.stub_request( 'post', '/oauth/deauthorize', { @@ -72,7 +69,7 @@ def test_deauthorize(self): ) resp = stripe.OAuth.deauthorize(stripe_user_id='acct_test_deauth') - self.assert_requested( + request_mock.assert_requested( 'post', '/oauth/deauthorize', { @@ -80,4 +77,4 @@ def test_deauthorize(self): 'stripe_user_id': 'acct_test_deauth', } ) - self.assertEqual('acct_test_deauth', resp['stripe_user_id']) + assert resp['stripe_user_id'] == 'acct_test_deauth' diff --git a/tests/test_stripe_object.py b/tests/test_stripe_object.py index d2320fc4b..a6a5d566d 100644 --- a/tests/test_stripe_object.py +++ b/tests/test_stripe_object.py @@ -3,11 +3,11 @@ import datetime import pickle from copy import copy, deepcopy -from mock import Mock + +import pytest import stripe from stripe import util, six -from tests.helper import StripeTestCase SAMPLE_INVOICE = stripe.util.json.loads(""" @@ -59,57 +59,58 @@ """) -class StripeObjectTests(StripeTestCase): - +class TestStripeObject(object): def test_initializes_with_parameters(self): obj = stripe.stripe_object.StripeObject( 'foo', 'bar', myparam=5, yourparam='boo') - self.assertEqual('foo', obj.id) - self.assertEqual('bar', obj.api_key) + assert obj.id == 'foo' + assert obj.api_key == 'bar' def test_access(self): obj = stripe.stripe_object.StripeObject('myid', 'mykey', myparam=5) # Empty - self.assertRaises(AttributeError, getattr, obj, 'myattr') - self.assertRaises(KeyError, obj.__getitem__, 'myattr') - self.assertEqual('def', obj.get('myattr', 'def')) - self.assertEqual(None, obj.get('myattr')) + with pytest.raises(AttributeError): + obj.myattr + with pytest.raises(KeyError): + obj['myattr'] + assert obj.get('myattr', 'def') == 'def' + assert obj.get('myattr') is None # Setters obj.myattr = 'myval' obj['myitem'] = 'itval' - self.assertEqual('sdef', obj.setdefault('mydef', 'sdef')) + assert obj.setdefault('mydef', 'sdef') == 'sdef' # Getters - self.assertEqual('myval', obj.setdefault('myattr', 'sdef')) - self.assertEqual('myval', obj.myattr) - self.assertEqual('myval', obj['myattr']) - self.assertEqual('myval', obj.get('myattr')) + assert obj.setdefault('myattr', 'sdef') == 'myval' + assert obj.myattr == 'myval' + assert obj['myattr'] == 'myval' + assert obj.get('myattr') == 'myval' + + assert sorted(obj.keys()) == ['id', 'myattr', 'mydef', 'myitem'] - self.assertEqual(['id', 'myattr', 'mydef', 'myitem'], - sorted(obj.keys())) - self.assertEqual(['itval', 'myid', 'myval', 'sdef'], - sorted(obj.values())) + assert sorted(obj.values()) == ['itval', 'myid', 'myval', 'sdef'] # Illegal operations - self.assertRaises(ValueError, setattr, obj, 'foo', '') + with pytest.raises(ValueError): + obj.foo = '' - def test_refresh_from(self): + def test_refresh_from(self, mocker): obj = stripe.stripe_object.StripeObject.construct_from({ 'foo': 'bar', 'trans': 'me', }, 'mykey') - self.assertEqual('mykey', obj.api_key) - self.assertEqual('bar', obj.foo) - self.assertEqual('me', obj['trans']) - self.assertEqual(None, obj.stripe_version) - self.assertEqual(None, obj.stripe_account) - self.assertEqual(None, obj.last_response) + assert obj.api_key == 'mykey' + assert obj.foo == 'bar' + assert obj['trans'] == 'me' + assert obj.stripe_version is None + assert obj.stripe_account is None + assert obj.last_response is None - last_response = Mock() + last_response = mocker.Mock() obj.refresh_from( { 'foo': 'baz', @@ -120,21 +121,22 @@ def test_refresh_from(self): last_response=last_response ) - self.assertEqual(5, obj.johnny) - self.assertEqual('baz', obj.foo) - self.assertRaises(AttributeError, getattr, obj, 'trans') - self.assertEqual('key2', obj.api_key) - self.assertEqual('2017-08-15', obj.stripe_version) - self.assertEqual('acct_foo', obj.stripe_account) - self.assertEqual(last_response, obj.last_response) + assert obj.johnny == 5 + assert obj.foo == 'baz' + with pytest.raises(AttributeError): + obj.trans + assert obj.api_key == 'key2' + assert obj.stripe_version == '2017-08-15' + assert obj.stripe_account == 'acct_foo' + assert obj.last_response == last_response obj.refresh_from({ 'trans': 4, 'metadata': {'amount': 42} }, 'key2', True) - self.assertEqual('baz', obj.foo) - self.assertEqual(4, obj.trans) + assert obj.foo == 'baz' + assert obj.trans == 4 def test_passing_nested_refresh(self): obj = stripe.stripe_object.StripeObject.construct_from({ @@ -148,20 +150,19 @@ def test_passing_nested_refresh(self): nested = obj.foos.data[0] - self.assertEqual('key', obj.api_key) - self.assertEqual('nested', nested.id) - self.assertEqual('key', nested.api_key) - self.assertEqual('acct_foo', nested.stripe_account) + assert obj.api_key == 'key' + assert nested.id == 'nested' + assert nested.api_key == 'key' + assert nested.stripe_account == 'acct_foo' def test_refresh_from_nested_object(self): obj = stripe.stripe_object.StripeObject.construct_from( SAMPLE_INVOICE, 'key') - self.assertEqual(1, len(obj.lines.subscriptions)) - self.assertTrue( - isinstance(obj.lines.subscriptions[0], - stripe.stripe_object.StripeObject)) - self.assertEqual('month', obj.lines.subscriptions[0].plan.interval) + assert len(obj.lines.subscriptions) == 1 + assert isinstance(obj.lines.subscriptions[0], + stripe.stripe_object.StripeObject) + assert obj.lines.subscriptions[0].plan.interval == 'month' def test_to_json(self): obj = stripe.stripe_object.StripeObject.construct_from( @@ -171,17 +172,16 @@ def test_to_json(self): def check_invoice_data(self, data): # Check rough structure - self.assertEqual(20, len(list(data.keys()))) - self.assertEqual(3, len(list(data['lines'].keys()))) - self.assertEqual(0, len(data['lines']['invoiceitems'])) - self.assertEqual(1, len(data['lines']['subscriptions'])) + 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 # Check various data types - self.assertEqual(1338238728, data['date']) - self.assertEqual(None, data['next_payment_attempt']) - self.assertEqual(False, data['livemode']) - self.assertEqual('month', - data['lines']['subscriptions'][0]['plan']['interval']) + assert data['date'] == 1338238728 + assert data['next_payment_attempt'] is None + assert data['livemode'] is False + assert data['lines']['subscriptions'][0]['plan']['interval'] == 'month' def test_repr(self): obj = stripe.stripe_object.StripeObject( @@ -195,9 +195,9 @@ def test_repr(self): if six.PY2: res = six.text_type(repr(obj), 'utf-8') - self.assertTrue(u'=7.19 requests>=0.8.8 - mock - coverage commands = python setup.py clean --all - python -W all -bb -W error::BytesWarning -m coverage.__main__ run setup.py test {posargs} + python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe {posargs}" setenv = STRIPE_TEST_PYCURL = true [testenv:py27] deps = flake8 - unittest2 pycurl>=7.19 requests>=0.8.8 - mock - coverage commands = flake8 stripe tests python setup.py clean --all - python -W all -bb -W error::BytesWarning -m coverage.__main__ run setup.py test {posargs} + python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe {posargs}" [flake8] exclude = From d416e9e68c8eba804535541ce29d2d8f2d22b08c Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Sun, 25 Feb 2018 14:34:24 +0100 Subject: [PATCH 3/7] Remove deprecated code --- .vscode/settings.json | 4 +- bin/stripe | 344 ------------------ stripe/__init__.py | 43 +-- stripe/api_requestor.py | 131 ------- .../abstract/listable_api_resource.py | 10 - stripe/api_resources/customer.py | 61 +--- stripe/api_resources/ephemeral_key.py | 17 +- stripe/api_resources/list_object.py | 9 - stripe/api_resources/recipient.py | 6 - stripe/api_resources/source.py | 9 - stripe/api_resources/subscription.py | 3 +- stripe/api_resources/topup.py | 2 + stripe/resource.py | 38 -- stripe/stripe_object.py | 7 - tests/api_resources/test_customer.py | 90 ----- tests/api_resources/test_ephemeral_key.py | 21 -- tests/api_resources/test_recipient.py | 11 - tests/api_resources/test_source.py | 16 - tests/test_error.py | 18 +- 19 files changed, 21 insertions(+), 819 deletions(-) delete mode 100755 bin/stripe delete mode 100644 stripe/resource.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 393f4b47e..7a0cc7fe1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "python.linting.flake8Enabled": true, // Tests - "python.unitTest.unittestEnabled": true, - "python.unitTest.pyTestEnabled": false, + "python.unitTest.unittestEnabled": false, + "python.unitTest.pyTestEnabled": true, "python.unitTest.nosetestsEnabled": false } diff --git a/bin/stripe b/bin/stripe deleted file mode 100755 index b85a83e5c..000000000 --- a/bin/stripe +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/env python - -# WARNING: This client is now deprecated and will be removed in version 2.0 - -import logging -import optparse -import os -import re -import subprocess -import sys -import warnings - -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) -import stripe - -logger = logging.getLogger('') -logger.addHandler(logging.StreamHandler(sys.stderr)) -logger.setLevel(logging.INFO) - -class APIResourceClient(object): - def __init__(self, id=None): - self.id = id - - def to_dict(self, params): - dict = {} - for k, v in params: - dict[k] = v - return dict - - def logged_curl(self, method, url, params): - dict_params = self.to_dict(params) - self.log_request(method, url, params, dict_params) - rbody, rcode, _ = stripe.APIRequestor().request_raw(method, url, dict_params) - self.log_result(rbody, rcode) - return rbody, rcode - - def log_request(self, method, url, ordered_params, dict_params): - if method.lower() == 'get': - requestor = stripe.APIRequestor() - if dict_params: - url = '%s?%s' % (url, stripe.APIRequestor().encode(dict_params)) - ordered_params = [] - elif not ordered_params: - ordered_params = ' -X %s' % (method.upper(), ) - - logger.info('Running the equivalent of:') - logger.info('--') - if len(ordered_params): - term = ' \\' - else: - term = '' - curl = ['curl %s%s -H "Authorization: Bearer %s"%s' % (stripe.api_base, url, stripe.api_key, term)] - if isinstance(ordered_params, list): - for i, (k, v) in enumerate(ordered_params): - if i == len(ordered_params) - 1: - term = '' - else: - term = ' \\' - curl.append(' -d %s=%s%s' % (k, v, term)) - else: - curl.append(ordered_params) - logger.info('\n'.join(curl)) - logger.info('--') - - def log_result(self, rbody, rcode): - logger.info('Result (HTTP status code %d):' % (rcode, )) - logger.info('--') - logger.info(rbody.rstrip()) - logger.info('--') - - def class_url(self): - return self.client_for.class_url() - - def instance_url(self): - if not self.id: - raise ValueError('ID required. (HINT: provide the script a -i ID)') - return self.client_for(self.id).instance_url() - - def retrieve(self, params): - url = self.instance_url() - self.logged_curl('get', url, []) - -class ListableAPIResourceClient(APIResourceClient): - def all(self, params): - url = self.class_url() - self.logged_curl('get', url, params) - -class CreateableAPIResourceClient(APIResourceClient): - def create(self, params): - url = self.class_url() - self.logged_curl('post', url, params) - -class UpdateableAPIResourceClient(APIResourceClient): - def update(self, params): - url = self.instance_url() - self.logged_curl('post', url, params) - -class DeletableAPIResourceClient(APIResourceClient): - def delete(self, params): - url = self.instance_url() - self.logged_curl('delete', url, params) - -# API objects -class AccountClient(APIResourceClient): - client_for = stripe.Account - -class CardClient(UpdateableAPIResourceClient, DeletableAPIResourceClient): - client_for = stripe.Card - -class ChargeClient(CreateableAPIResourceClient, ListableAPIResourceClient): - client_for = stripe.Charge - - def refund(self, params): - url = self.instance_url() + '/refund' - self.logged_curl('post', url, params) - - def capture(self, params): - url = self.instance_url() + '/capture' - self.logged_curl('post', url, params) - - def update_dispute(self, params): - url = self.instance_url() + '/dispute' - self.logged_curl('post', url, params) - - def close_dispute(self): - url = self.instance_url() + '/dispute/close' - self.logged_curl('post', url, {}) - - -class CustomerClient(CreateableAPIResourceClient, UpdateableAPIResourceClient, - ListableAPIResourceClient, DeletableAPIResourceClient): - client_for = stripe.Customer - - def add_invoice_item(self, params): - params = params.copy() - params.append(['customer', self.id]) - InvoiceItemClient.create(params) - - def invoices(self, params): - params = params.copy() - params.append(['customer', self.id]) - InvoiceClient.all(params) - - def invoice_items(self, params): - params = params.copy() - params.append(['customer', self.id]) - InvoiceItem.all(params) - - def charges(self, params): - params = params.copy() - params.append(['customer', self.id]) - ChargeClient.all(params) - - def update_subscription(self, params): - url = self.instance_url() + '/subscription' - self.logged_curl('post', url, params) - - def cancel_subscription(self, params): - url = self.instance_url() + '/subscription' - self.logged_curl('delete', url, params) - -class InvoiceClient(CreateableAPIResourceClient, ListableAPIResourceClient, UpdateableAPIResourceClient): - client_for = stripe.Invoice - - def pay(self): - url = self.instance_url() + '/pay' - self.logged_curl('post', url, {}) - - @classmethod - def upcoming(cls, params): - url = cls.client_for.class_url() + '/upcoming' - cls().logged_curl('get', url, params) - -class InvoiceItemClient(CreateableAPIResourceClient, UpdateableAPIResourceClient, - ListableAPIResourceClient, DeletableAPIResourceClient): - client_for = stripe.InvoiceItem - -class PlanClient(CreateableAPIResourceClient, DeletableAPIResourceClient, ListableAPIResourceClient, UpdateableAPIResourceClient): - client_for = stripe.Plan - -class SubscriptionClient(UpdateableAPIResourceClient, DeletableAPIResourceClient): - client_for = stripe.Subscription - -class TokenClient(CreateableAPIResourceClient): - client_for = stripe.Token - -class CouponClient(CreateableAPIResourceClient, UpdateableAPIResourceClient, DeletableAPIResourceClient, ListableAPIResourceClient): - client_for = stripe.Coupon - -class ApplicationFeeClient(ListableAPIResourceClient): - client_for = stripe.ApplicationFee - -def main(): - # DeprecationWarning - sys.stderr.write( - 'The Python client binary is deprecated and will be removed in \n' - 'version 2.0 of the bindings. You may want to use: \n' - 'https://github.com/stripe-contrib/stripe-cli\n\n') - - klasses = { - 'account' : AccountClient, - 'card' : CardClient, - 'charge' : ChargeClient, - 'charges' : ChargeClient, - 'customer' : CustomerClient, - 'customers' : CustomerClient, - 'invoice' : InvoiceClient, - 'invoices' : InvoiceClient, - 'invoiceitem' : InvoiceItemClient, - 'invoiceitems' : InvoiceItemClient, - 'plan' : PlanClient, - 'plans' : PlanClient, - 'token' : TokenClient, - 'tokens' : TokenClient, - 'coupon' : CouponClient, - 'coupons' : CouponClient, - 'subscription' : SubscriptionClient, - 'subscriptions' : SubscriptionClient, - 'application_fee' : ApplicationFeeClient, - 'application_fees' : ApplicationFeeClient - } - parser = optparse.OptionParser("""%prog [options] class method [key=value|key ...] - -Valid methods: - -account - retrieve - -card - update - delete - -charge - all - create - retrieve - refund - capture - -customer - all - create - retrieve - update - delete - add_invoice_item - invoices - invoice_items - charges - update_subscription - cancel_subscription - -invoice - all - retrieve - upcoming - update - pay - -invoiceitem - all - create - retrieve - update - delete - -plan - create - retrieve - update - -subscription - update - delete - -coupon - all - create - retrieve - update - delete - -application_fee - all - retrieve - -token - create - retrieve""") - parser.add_option('-v', '--verbosity', help='Verbosity of debugging output.', - dest='verbosity', action='count', default=0) - parser.add_option('-k', '--api-key', help="API key. Defaults to value of environment variable STRIPE_API_KEY", dest='api_key') - parser.add_option('-b', '--api-base', help='API base URL', dest='api_base') - parser.add_option('-i', '--id', help="Object ID", dest='id') - opts, args = parser.parse_args() - if opts.verbosity == 1: - logger.setLevel(logging.INFO) - elif opts.verbosity >= 2: - logger.setLevel(logging.DEBUG) - if len(args) < 2: - parser.print_help() - return 1 - - klass_name = args[0] - method_name = args[1] - - stripe.api_key = opts.api_key or os.environ.get('STRIPE_API_KEY') - if not stripe.api_key: - parser.error('No API key provided (use -k option or set the STRIPE_API_KEY environment variable') - return 1 - - if opts.api_base: - stripe.api_base = opts.api_base - - params = [] - for arg in args[2:]: - try: - key = arg[:arg.index('=')] - value = arg[arg.index('=') + 1:] - except ValueError: - key = arg - value = None - if not value: - value = raw_input('%s= ' % (key, )) - params.append([key, value]) - - try: - klass = klasses[klass_name] - except KeyError: - parser.error('Invalid class %s' % (klass_name, )) - return 1 - else: - dispatch = klass(opts.id) - - try: - method = getattr(dispatch, method_name) - except AttributeError: - parser.error('Invalid method %s of %s' % (method_name, klass_name)) - return 1 - - return method(params) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/stripe/__init__.py b/stripe/__init__.py index 15d051cff..2035362e0 100644 --- a/stripe/__init__.py +++ b/stripe/__init__.py @@ -23,7 +23,7 @@ # Set to either 'debug' or 'info', controls console logging log = None -# Resource +# API resources from stripe.api_resources import * # noqa # OAuth @@ -32,47 +32,6 @@ # Webhooks from stripe.webhook import Webhook, WebhookSignature # noqa -# Error imports. Note that we may want to move these out of the root -# namespace in the future and you should prefer to access them via -# the fully qualified `stripe.error` module. - -from stripe.error import ( # noqa - APIConnectionError, - APIError, - AuthenticationError, - PermissionError, - RateLimitError, - CardError, - IdempotencyError, - InvalidRequestError, - SignatureVerificationError, - StripeError) - -# OAuth error classes are not imported into the root namespace and must be -# accessed via stripe.oauth_error. -from stripe import oauth_error # noqa - -# DEPRECATED: These imports will be moved out of the root stripe namespace -# in version 2.0 - -from stripe.version import VERSION # noqa -from stripe.api_requestor import APIRequestor # noqa - -from stripe.stripe_object import StripeObject # noqa -from stripe.api_resources.abstract import ( # noqa - APIResource, - CreateableAPIResource, - DeletableAPIResource, - ListableAPIResource, - SingletonAPIResource, - UpdateableAPIResource) - -from stripe.resource import StripeObjectEncoder # noqa -from stripe.util import ( # noqa - convert_to_stripe_object, - json, - logger) - # Sets some basic information about the running application that's sent along # with API requests. Useful for plugin authors to identify their plugin when diff --git a/stripe/api_requestor.py b/stripe/api_requestor.py index 4b127a8db..5088ec779 100644 --- a/stripe/api_requestor.py +++ b/stripe/api_requestor.py @@ -4,7 +4,6 @@ import datetime import platform import time -import warnings import stripe from stripe import error, oauth_error, http_client, version, util, six @@ -79,65 +78,6 @@ def __init__(self, key=None, client=None, api_base=None, api_version=None, http_client.new_default_http_client( verify_ssl_certs=verify, proxy=proxy) - @classmethod - def api_url(cls, url=''): - warnings.warn( - 'The `api_url` class method of APIRequestor is ' - 'deprecated and will be removed in version 2.0.' - 'If you need public access to this function, please email us ' - 'at support@stripe.com.', - DeprecationWarning) - return '%s%s' % (stripe.api_base, url) - - @classmethod - def _deprecated_encode(cls, stk, key, value): - warnings.warn( - 'The encode_* class methods of APIRequestor are deprecated and ' - 'will be removed in version 2.0. ' - 'If you need public access to this function, please email us ' - 'at support@stripe.com.', - DeprecationWarning, stacklevel=2) - stk.extend(_api_encode({key: value})) - - @classmethod - def encode_dict(cls, stk, key, value): - cls._deprecated_encode(stk, key, value) - - @classmethod - def encode_list(cls, stk, key, value): - cls._deprecated_encode(stk, key, value) - - @classmethod - def encode_datetime(cls, stk, key, value): - cls._deprecated_encode(stk, key, value) - - @classmethod - def encode_none(cls, stk, key, value): - cls._deprecated_encode(stk, key, value) - - @classmethod - def encode(cls, d): - """ - Internal: encode a string for url representation - """ - warnings.warn( - 'The `encode` class method of APIRequestor is deprecated and ' - 'will be removed in version 2.0.' - 'If you need public access to this function, please email us ' - 'at support@stripe.com.', - DeprecationWarning) - return urlencode(list(_api_encode(d))) - - @classmethod - def build_url(cls, url, params): - warnings.warn( - 'The `build_url` class method of APIRequestor is deprecated and ' - 'will be removed in version 2.0.' - 'If you need public access to this function, please email us ' - 'at support@stripe.com.', - DeprecationWarning) - return _build_api_url(url, cls.encode(params)) - @classmethod def format_app_info(cls, info): str = info['name'] @@ -365,74 +305,3 @@ def interpret_response(self, rbody, rcode, rheaders): self.handle_error_response(rbody, rcode, resp.data, rheaders) return resp - - # Deprecated request handling. Will all be removed in 2.0 - def _deprecated_request(self, impl, method, url, headers, params): - warnings.warn( - 'The *_request functions of APIRequestor are deprecated and ' - 'will be removed in version 2.0. Please use the client classes ' - ' in `stripe.http_client` instead', - DeprecationWarning, stacklevel=2) - - method = method.lower() - - if method == 'get' or method == 'delete': - if params: - url = self.build_url(url, params) - post_data = None - elif method == 'post': - post_data = self.encode(params) - else: - raise error.APIConnectionError( - 'Unrecognized HTTP method %r. This may indicate a bug in the ' - 'Stripe bindings. Please contact support@stripe.com for ' - 'assistance.' % (method,)) - - client = impl(verify_ssl_certs=self._client._verify_ssl_certs) - return client.request(method, url, headers, post_data) - - def _deprecated_handle_error(self, impl, *args): - warnings.warn( - 'The handle_*_error functions of APIRequestor are deprecated and ' - 'will be removed in version 2.0. Please use the client classes ' - ' in `stripe.http_client` instead', - DeprecationWarning, stacklevel=2) - - client = impl(verify_ssl_certs=self._client._verify_ssl_certs) - return client._handle_request_error(*args) - - def requests_request(self, meth, abs_url, headers, params): - from stripe.http_client import RequestsClient - return self._deprecated_request(RequestsClient, meth, abs_url, - headers, params) - - def handle_requests_error(self, err): - from stripe.http_client import RequestsClient - return self._deprecated_handle_error(RequestsClient, err) - - def pycurl_request(self, meth, abs_url, headers, params): - from stripe.http_client import PycurlClient - return self._deprecated_request(PycurlClient, meth, abs_url, - headers, params) - - def handle_pycurl_error(self, err): - from stripe.http_client import PycurlClient - return self._deprecated_handle_error(PycurlClient, err) - - def urlfetch_request(self, meth, abs_url, headers, params): - from stripe.http_client import UrlFetchClient - return self._deprecated_request(UrlFetchClient, meth, abs_url, - headers, params) - - def handle_urlfetch_error(self, err, abs_url): - from stripe.http_client import UrlFetchClient - return self._deprecated_handle_error(UrlFetchClient, err, abs_url) - - def urllib2_request(self, meth, abs_url, headers, params): - from stripe.http_client import Urllib2Client - return self._deprecated_request(Urllib2Client, meth, abs_url, - headers, params) - - def handle_urllib2_error(self, err, abs_url): - from stripe.http_client import Urllib2Client - return self._deprecated_handle_error(Urllib2Client, err, abs_url) diff --git a/stripe/api_resources/abstract/listable_api_resource.py b/stripe/api_resources/abstract/listable_api_resource.py index 0189520fa..52dc68b33 100644 --- a/stripe/api_resources/abstract/listable_api_resource.py +++ b/stripe/api_resources/abstract/listable_api_resource.py @@ -1,21 +1,11 @@ from __future__ import absolute_import, division, print_function -import warnings - from stripe import api_requestor, util from stripe.api_resources.abstract.api_resource import APIResource class ListableAPIResource(APIResource): - @classmethod - def all(cls, *args, **params): - warnings.warn("The `all` class method is deprecated and will" - "be removed in future versions. Please use the " - "`list` class method instead", - DeprecationWarning) - return cls.list(*args, **params) - @classmethod def auto_paging_iter(cls, *args, **params): return cls.list(*args, **params).auto_paging_iter() diff --git a/stripe/api_resources/customer.py b/stripe/api_resources/customer.py index 449021614..a5cb4ba4f 100644 --- a/stripe/api_resources/customer.py +++ b/stripe/api_resources/customer.py @@ -1,11 +1,6 @@ from __future__ import absolute_import, division, print_function -import warnings - -from stripe import api_requestor, util -from stripe.api_resources.charge import Charge -from stripe.api_resources.invoice import Invoice -from stripe.api_resources.invoice_item import InvoiceItem +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 @@ -21,62 +16,10 @@ class Customer(CreateableAPIResource, UpdateableAPIResource, ListableAPIResource, DeletableAPIResource): OBJECT_NAME = 'customer' - def add_invoice_item(self, idempotency_key=None, **params): - params['customer'] = self.id - ii = InvoiceItem.create(self.api_key, - idempotency_key=idempotency_key, **params) - return ii - - def invoices(self, **params): - params['customer'] = self.id - invoices = Invoice.list(self.api_key, **params) - return invoices - - def invoice_items(self, **params): - params['customer'] = self.id - iis = InvoiceItem.list(self.api_key, **params) - return iis - - def charges(self, **params): - params['customer'] = self.id - charges = Charge.list(self.api_key, **params) - return charges - - def update_subscription(self, idempotency_key=None, **params): - warnings.warn( - 'The `update_subscription` method is deprecated. Instead, use the ' - '`subscriptions` resource on the customer object to update a ' - 'subscription', - DeprecationWarning) - requestor = api_requestor.APIRequestor(self.api_key, - api_version=self.stripe_version, - account=self.stripe_account) - url = self.instance_url() + '/subscription' - headers = util.populate_headers(idempotency_key) - response, api_key = requestor.request('post', url, params, headers) - self.refresh_from({'subscription': response}, api_key, True) - return self.subscription - - def cancel_subscription(self, idempotency_key=None, **params): - warnings.warn( - 'The `cancel_subscription` method is deprecated. Instead, use the ' - '`subscriptions` resource on the customer object to cancel a ' - 'subscription', - DeprecationWarning) - requestor = api_requestor.APIRequestor(self.api_key, - api_version=self.stripe_version, - account=self.stripe_account) - url = self.instance_url() + '/subscription' - headers = util.populate_headers(idempotency_key) - response, api_key = requestor.request('delete', url, params, headers) - self.refresh_from({'subscription': response}, api_key, True) - return self.subscription - - # TODO: Remove arg in next major release. def delete_discount(self, **params): requestor = api_requestor.APIRequestor(self.api_key, api_version=self.stripe_version, account=self.stripe_account) url = self.instance_url() + '/discount' - _, api_key = requestor.request('delete', url) + _, api_key = requestor.request('delete', url, params) self.refresh_from({'discount': None}, api_key, True) diff --git a/stripe/api_resources/ephemeral_key.py b/stripe/api_resources/ephemeral_key.py index ce7d0c0c6..9ee0b29d1 100644 --- a/stripe/api_resources/ephemeral_key.py +++ b/stripe/api_resources/ephemeral_key.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - from stripe import api_requestor, util from stripe.api_resources.abstract import DeletableAPIResource @@ -16,18 +14,11 @@ def class_name(cls): @classmethod def create(cls, api_key=None, idempotency_key=None, stripe_version=None, stripe_account=None, - api_version=None, **params): + **params): if stripe_version is None: - if api_version is not None: - stripe_version = api_version - warnings.warn( - "The `api_version` parameter when creating an ephemeral " - "key is deprecated. Please use `stripe_version` instead.", - DeprecationWarning) - else: - raise ValueError( - "stripe_version must be specified to create an ephemeral " - "key") + raise ValueError( + "stripe_version must be specified to create an ephemeral " + "key") requestor = api_requestor.APIRequestor( api_key, diff --git a/stripe/api_resources/list_object.py b/stripe/api_resources/list_object.py index a956238bb..f1acbe626 100644 --- a/stripe/api_resources/list_object.py +++ b/stripe/api_resources/list_object.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - from stripe import util from stripe.stripe_object import StripeObject @@ -14,13 +12,6 @@ class ListObject(StripeObject): def list(self, **params): return self.request('get', self['url'], params) - def all(self, **params): - warnings.warn("The `all` method is deprecated and will" - "be removed in future versions. Please use the " - "`list` method instead", - DeprecationWarning) - return self.list(**params) - def auto_paging_iter(self): page = self params = dict(self._retrieve_params) diff --git a/stripe/api_resources/recipient.py b/stripe/api_resources/recipient.py index ebd4dba2b..f4eb8efec 100644 --- a/stripe/api_resources/recipient.py +++ b/stripe/api_resources/recipient.py @@ -1,6 +1,5 @@ from __future__ import absolute_import, division, print_function -from stripe.api_resources.transfer import Transfer from stripe.api_resources.abstract import CreateableAPIResource from stripe.api_resources.abstract import DeletableAPIResource from stripe.api_resources.abstract import UpdateableAPIResource @@ -10,8 +9,3 @@ class Recipient(CreateableAPIResource, UpdateableAPIResource, ListableAPIResource, DeletableAPIResource): OBJECT_NAME = 'recipient' - - def transfers(self, **params): - params['recipient'] = self.id - transfers = Transfer.list(self.api_key, **params) - return transfers diff --git a/stripe/api_resources/source.py b/stripe/api_resources/source.py index 8f3862257..53803e907 100644 --- a/stripe/api_resources/source.py +++ b/stripe/api_resources/source.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - from stripe import util from stripe.api_resources import Customer from stripe.api_resources.abstract import CreateableAPIResource @@ -30,13 +28,6 @@ def detach(self, idempotency_key=None, **params): "This source object does not appear to be currently attached " "to a customer object.") - def delete(self, **params): - warnings.warn("The `Source.delete` method is deprecated and will " - "be removed in future versions. Please use the " - "`Source.detach` method instead", - DeprecationWarning) - self.detach(**params) - def source_transactions(self, **params): return self.request( 'get', self.instance_url() + '/source_transactions', params) diff --git a/stripe/api_resources/subscription.py b/stripe/api_resources/subscription.py index e0e7a0f1c..2a9ca8662 100644 --- a/stripe/api_resources/subscription.py +++ b/stripe/api_resources/subscription.py @@ -11,13 +11,12 @@ class Subscription(CreateableAPIResource, DeletableAPIResource, UpdateableAPIResource, ListableAPIResource): OBJECT_NAME = 'subscription' - # TODO: Remove arg in next major release. def delete_discount(self, **params): requestor = api_requestor.APIRequestor(self.api_key, api_version=self.stripe_version, account=self.stripe_account) url = self.instance_url() + '/discount' - _, api_key = requestor.request('delete', url) + _, api_key = requestor.request('delete', url, params) self.refresh_from({'discount': None}, api_key, True) @classmethod diff --git a/stripe/api_resources/topup.py b/stripe/api_resources/topup.py index 51fda2c83..72f55b737 100644 --- a/stripe/api_resources/topup.py +++ b/stripe/api_resources/topup.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import, division, print_function + from stripe.api_resources.abstract import CreateableAPIResource from stripe.api_resources.abstract import UpdateableAPIResource from stripe.api_resources.abstract import ListableAPIResource diff --git a/stripe/resource.py b/stripe/resource.py deleted file mode 100644 index 3f19537c1..000000000 --- a/stripe/resource.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import absolute_import, division, print_function - -# -# This module doesn't serve much purpose anymore. It's only here to maintain -# backwards compatibility. -# -# TODO: get rid of this module in the next major version. -# - -import warnings - -from stripe import util -from stripe.util import ( # noqa - convert_array_to_dict, - convert_to_stripe_object, -) -from stripe.stripe_object import StripeObject # noqa -from stripe.api_resources.abstract import ( # noqa - APIResource, - CreateableAPIResource, - DeletableAPIResource, - ListableAPIResource, - SingletonAPIResource, - UpdateableAPIResource, -) -from stripe.api_resources import * # noqa - - -class StripeObjectEncoder(util.json.JSONEncoder): - - def __init__(self, *args, **kwargs): - warnings.warn( - '`StripeObjectEncoder` is deprecated and will be removed in ' - 'version 2.0 of the Stripe bindings. StripeObject is now a ' - 'subclass of `dict` and is handled natively by the built-in ' - 'json library.', - DeprecationWarning) - super(StripeObjectEncoder, self).__init__(*args, **kwargs) diff --git a/stripe/stripe_object.py b/stripe/stripe_object.py index b560f153e..921e53617 100644 --- a/stripe/stripe_object.py +++ b/stripe/stripe_object.py @@ -1,7 +1,6 @@ from __future__ import absolute_import, division, print_function import datetime -import warnings from copy import deepcopy import stripe @@ -232,12 +231,6 @@ def __str__(self): indent=2, cls=self.ReprJSONEncoder) def to_dict(self): - warnings.warn( - 'The `to_dict` method is deprecated and will be removed in ' - 'version 2.0 of the Stripe bindings. The StripeObject is ' - 'itself now a subclass of `dict`.', - DeprecationWarning) - return dict(self) def to_dict_recursive(self): diff --git a/tests/api_resources/test_customer.py b/tests/api_resources/test_customer.py index 6c6d0c61e..f2f0dc4d7 100644 --- a/tests/api_resources/test_customer.py +++ b/tests/api_resources/test_customer.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - import stripe @@ -68,55 +66,6 @@ def test_is_deletable(self, request_mock): ) assert resource.deleted is True - def test_can_add_invoice_item(self, request_mock): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.add_invoice_item( - amount=100, - currency='usd' - ) - request_mock.assert_requested( - 'post', - '/v1/invoiceitems', - { - 'amount': 100, - 'currency': 'usd', - 'customer': '%s' % resource.id - } - ) - - def test_can_invoices(self, request_mock): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.invoices() - request_mock.assert_requested( - 'get', - '/v1/invoices', - { - 'customer': '%s' % resource.id - } - ) - - def test_can_invoice_items(self, request_mock): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.invoice_items() - request_mock.assert_requested( - 'get', - '/v1/invoiceitems', - { - 'customer': '%s' % resource.id - } - ) - - def test_can_list_charges(self, request_mock): - resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) - resource.charges() - request_mock.assert_requested( - 'get', - '/v1/charges', - { - 'customer': '%s' % resource.id - } - ) - def test_can_delete_discount(self, request_mock): resource = stripe.Customer.retrieve(TEST_RESOURCE_ID) resource.delete_discount() @@ -126,45 +75,6 @@ def test_can_delete_discount(self, request_mock): ) -# stripe-mock does not handle the legacy subscription endpoint so we stub -class TestCustomerLegacySubscription(object): - def construct_resource(self): - res_dict = { - 'id': TEST_RESOURCE_ID, - 'object': 'customer', - 'metadata': {}, - } - return stripe.Customer.construct_from(res_dict, stripe.api_key) - - def test_can_update_legacy_subscription(self, request_mock): - request_mock.stub_request( - 'post', - '/v1/customers/%s/subscription' % TEST_RESOURCE_ID, - ) - resource = self.construct_resource() - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - resource.update_subscription(plan='plan') - request_mock.assert_requested( - 'post', - '/v1/customers/%s/subscription' % TEST_RESOURCE_ID - ) - - def test_can_delete_legacy_subscription(self, request_mock): - request_mock.stub_request( - 'delete', - '/v1/customers/%s/subscription' % TEST_RESOURCE_ID - ) - resource = self.construct_resource() - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - resource.cancel_subscription() - request_mock.assert_requested( - 'delete', - '/v1/customers/%s/subscription' % TEST_RESOURCE_ID - ) - - class TestCustomerSources(object): def test_is_creatable(self, request_mock): stripe.Customer.create_source( diff --git a/tests/api_resources/test_ephemeral_key.py b/tests/api_resources/test_ephemeral_key.py index 2652dc673..69e46cb07 100644 --- a/tests/api_resources/test_ephemeral_key.py +++ b/tests/api_resources/test_ephemeral_key.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - import pytest import stripe @@ -21,25 +19,6 @@ def test_is_creatable(self, request_mock): ) assert isinstance(resource, stripe.EphemeralKey) - def test_raises_a_warning_when_using_api_version_arg(self, request_mock): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - - resource = stripe.EphemeralKey.create( - customer='cus_123', - api_version='2017-05-25' - ) - request_mock.assert_api_version('2017-05-25') - request_mock.assert_requested( - 'post', - '/v1/ephemeral_keys', - {'customer': 'cus_123'} - ) - assert isinstance(resource, stripe.EphemeralKey) - - assert len(w) == 1 - assert w[0].category == DeprecationWarning - def test_is_not_creatable_without_an_explicit_api_version(self): with pytest.raises(ValueError, message='stripe_version must be specified'): diff --git a/tests/api_resources/test_recipient.py b/tests/api_resources/test_recipient.py index a0cf4df16..67060a36b 100644 --- a/tests/api_resources/test_recipient.py +++ b/tests/api_resources/test_recipient.py @@ -66,14 +66,3 @@ def test_is_deletable(self, request_mock): '/v1/recipients/%s' % resource_id ) assert resource.deleted is True - - def test_can_list_transfers(self, request_mock): - recipient = stripe.Recipient.retrieve(TEST_RESOURCE_ID) - resources = recipient.transfers() - request_mock.assert_requested( - 'get', - '/v1/transfers', - {'recipient': recipient.id} - ) - assert isinstance(resources.data, list) - assert isinstance(resources.data[0], stripe.Transfer) diff --git a/tests/api_resources/test_source.py b/tests/api_resources/test_source.py index 014f86e0e..f6e956947 100644 --- a/tests/api_resources/test_source.py +++ b/tests/api_resources/test_source.py @@ -1,7 +1,5 @@ from __future__ import absolute_import, division, print_function -import warnings - import pytest import stripe @@ -68,20 +66,6 @@ def test_is_not_detachable_when_unattached(self): with pytest.raises(NotImplementedError): resource.detach() - def test_raises_a_warning_when_calling_delete(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - - resource = stripe.Source.construct_from({ - 'id': TEST_RESOURCE_ID, - 'object': 'source', - 'customer': 'cus_123' - }, stripe.api_key) - resource.delete() - - assert len(w) == 1 - assert w[0].category == DeprecationWarning - def test_is_verifiable(self, request_mock): resource = stripe.Source.retrieve(TEST_RESOURCE_ID) source = resource.verify(values=[1, 2]) diff --git a/tests/test_error.py b/tests/test_error.py index 652f9455d..00f072cde 100644 --- a/tests/test_error.py +++ b/tests/test_error.py @@ -2,12 +2,12 @@ from __future__ import absolute_import, division, print_function -from stripe import CardError, StripeError, six +from stripe import six, error class TestStripeError(object): def test_formatting(self): - err = StripeError(u'öre') + err = error.StripeError(u'öre') assert six.text_type(err) == u'öre' if six.PY2: assert str(err) == '\xc3\xb6re' @@ -15,15 +15,15 @@ def test_formatting(self): assert str(err) == u'öre' def test_formatting_with_request_id(self): - err = StripeError(u'öre', headers={'request-id': '123'}) + err = error.StripeError(u'öre', headers={'request-id': '123'}) assert six.text_type(err) == u'Request 123: öre' if six.PY2: assert str(err) == 'Request 123: \xc3\xb6re' else: assert str(err) == u'Request 123: öre' - def test_formatting_with_message_none_and_request_id(self): - err = StripeError(None, headers={'request-id': '123'}) + def test_formatting_with_none(self): + err = error.StripeError(None, headers={'request-id': '123'}) assert six.text_type(err) == u'Request 123: ' if six.PY2: assert str(err) == 'Request 123: ' @@ -31,7 +31,7 @@ def test_formatting_with_message_none_and_request_id(self): assert str(err) == 'Request 123: ' def test_formatting_with_message_none_and_request_id_none(self): - err = StripeError(None) + err = error.StripeError(None) assert six.text_type(err) == u'' if six.PY2: assert str(err) == '' @@ -39,7 +39,7 @@ def test_formatting_with_message_none_and_request_id_none(self): assert str(err) == u'' def test_repr(self): - err = StripeError(u'öre', headers={'request-id': '123'}) + err = error.StripeError(u'öre', headers={'request-id': '123'}) if six.PY2: assert repr(err) == \ "StripeError(message=u'\\xf6re', http_status=None, " \ @@ -52,8 +52,8 @@ def test_repr(self): class TestStripeErrorWithParamCode(object): def test_repr(self): - err = CardError(u'öre', param='cparam', code='ccode', http_status=403, - headers={'request-id': '123'}) + err = error.CardError(u'öre', param='cparam', code='ccode', + http_status=403, headers={'request-id': '123'}) if six.PY2: assert repr(err) == \ "CardError(message=u'\\xf6re', param='cparam', " \ From 2eb48d8280121fedcb4226ad913cccc4264e9443 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Wed, 28 Feb 2018 16:53:03 +0100 Subject: [PATCH 4/7] Remove util.json and use json module directly everywhere --- stripe/api_requestor.py | 3 ++- stripe/stripe_object.py | 7 ++++--- stripe/stripe_response.py | 6 ++++-- stripe/util.py | 2 -- stripe/webhook.py | 3 ++- tests/api_resources/test_list_object.py | 2 +- tests/request_mock.py | 4 +++- tests/test_api_requestor.py | 8 ++++---- tests/test_stripe_object.py | 7 ++++--- tests/test_stripe_response.py | 5 +++-- 10 files changed, 27 insertions(+), 20 deletions(-) diff --git a/stripe/api_requestor.py b/stripe/api_requestor.py index 5088ec779..8625835c5 100644 --- a/stripe/api_requestor.py +++ b/stripe/api_requestor.py @@ -2,6 +2,7 @@ import calendar import datetime +import json import platform import time @@ -209,7 +210,7 @@ def request_headers(self, api_key, method): ua['application'] = stripe.app_info headers = { - 'X-Stripe-Client-User-Agent': util.json.dumps(ua), + 'X-Stripe-Client-User-Agent': json.dumps(ua), 'User-Agent': user_agent, 'Authorization': 'Bearer %s' % (api_key,), } diff --git a/stripe/stripe_object.py b/stripe/stripe_object.py index 921e53617..d574610b0 100644 --- a/stripe/stripe_object.py +++ b/stripe/stripe_object.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, division, print_function import datetime +import json from copy import deepcopy import stripe @@ -33,7 +34,7 @@ def _serialize_list(array, previous): class StripeObject(dict): - class ReprJSONEncoder(util.json.JSONEncoder): + class ReprJSONEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime.datetime): return api_requestor._encode_datetime(obj) @@ -227,8 +228,8 @@ def __repr__(self): return unicode_repr def __str__(self): - return util.json.dumps(self.to_dict_recursive(), sort_keys=True, - indent=2, cls=self.ReprJSONEncoder) + return json.dumps(self.to_dict_recursive(), sort_keys=True, + indent=2, cls=self.ReprJSONEncoder) def to_dict(self): return dict(self) diff --git a/stripe/stripe_response.py b/stripe/stripe_response.py index 10b963969..cf5e50c38 100644 --- a/stripe/stripe_response.py +++ b/stripe/stripe_response.py @@ -1,4 +1,6 @@ -from stripe import util +from __future__ import absolute_import, division, print_function + +import json class StripeResponse: @@ -7,7 +9,7 @@ def __init__(self, body, code, headers): self.body = body self.code = code self.headers = headers - self.data = util.json.loads(body) + self.data = json.loads(body) @property def idempotency_key(self): diff --git a/stripe/util.py b/stripe/util.py index ee50a8899..759921a78 100644 --- a/stripe/util.py +++ b/stripe/util.py @@ -2,7 +2,6 @@ import hmac import io -import json import logging import sys import os @@ -20,7 +19,6 @@ __all__ = [ 'io', 'parse_qsl', - 'json', 'utf8', 'log_info', 'log_debug', diff --git a/stripe/webhook.py b/stripe/webhook.py index 477dbc4a0..060452b41 100644 --- a/stripe/webhook.py +++ b/stripe/webhook.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, division, print_function import hmac +import json import time from hashlib import sha256 @@ -18,7 +19,7 @@ def construct_event(payload, sig_header, secret, payload = payload.decode('utf-8') if api_key is None: api_key = stripe.api_key - data = util.json.loads(payload) + data = json.loads(payload) event = stripe.Event.construct_from(data, api_key) WebhookSignature.verify_header(payload, sig_header, secret, tolerance) diff --git a/tests/api_resources/test_list_object.py b/tests/api_resources/test_list_object.py index 9c8025c76..f6497394b 100644 --- a/tests/api_resources/test_list_object.py +++ b/tests/api_resources/test_list_object.py @@ -133,7 +133,7 @@ def test_serialize_nested_empty_list(self): 'nested': empty, }, 'mykey') serialized = str(obj) - deserialized = stripe.StripeObject.construct_from( + deserialized = stripe.stripe_object.StripeObject.construct_from( json.loads(serialized), 'mykey') assert deserialized.nested == empty diff --git a/tests/request_mock.py b/tests/request_mock.py index 968705dd6..f9b426914 100644 --- a/tests/request_mock.py +++ b/tests/request_mock.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, division, print_function +import json + import stripe from stripe import six from stripe.stripe_response import StripeResponse @@ -100,7 +102,7 @@ def get_response(self, method, url): if (method, url) in self._entries: rbody, rcode, rheaders = self._entries.pop((method, url)) if not isinstance(rbody, six.string_types): - rbody = stripe.util.json.dumps(rbody) + rbody = json.dumps(rbody) stripe_response = StripeResponse(rbody, rcode, rheaders) return stripe_response diff --git a/tests/test_api_requestor.py b/tests/test_api_requestor.py index f18a1b565..98e1347cf 100644 --- a/tests/test_api_requestor.py +++ b/tests/test_api_requestor.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, division, print_function import datetime +import json import tempfile import pytest @@ -8,7 +9,6 @@ import stripe from stripe import six from stripe.stripe_response import StripeResponse -from stripe import util from six.moves.urllib.parse import urlsplit @@ -76,7 +76,7 @@ def _user_agent_match(self, other): def _x_stripe_ua_contains_app_info(self, other): if self.app_info: - ua = stripe.util.json.loads(other['X-Stripe-Client-User-Agent']) + ua = json.loads(other['X-Stripe-Client-User-Agent']) if 'application' not in ua: return False return ua['application'] == self.app_info @@ -311,7 +311,7 @@ def test_empty_methods(self, requestor, mock_response, check_call): assert isinstance(resp, StripeResponse) assert resp.data == {} - assert resp.data == util.json.loads(resp.body) + assert resp.data == json.loads(resp.body) def test_methods_with_params_and_response(self, requestor, mock_response, check_call): @@ -330,7 +330,7 @@ def test_methods_with_params_and_response(self, requestor, mock_response, assert isinstance(resp, StripeResponse) assert resp.data == {'foo': 'bar', 'baz': 6} - assert resp.data == util.json.loads(resp.body) + assert resp.data == json.loads(resp.body) if method == 'post': check_call( diff --git a/tests/test_stripe_object.py b/tests/test_stripe_object.py index a6a5d566d..c966485ec 100644 --- a/tests/test_stripe_object.py +++ b/tests/test_stripe_object.py @@ -1,16 +1,17 @@ from __future__ import absolute_import, division, print_function import datetime +import json import pickle from copy import copy, deepcopy import pytest import stripe -from stripe import util, six +from stripe import six -SAMPLE_INVOICE = stripe.util.json.loads(""" +SAMPLE_INVOICE = json.loads(""" { "amount_due": 1305, "attempt_count": 0, @@ -168,7 +169,7 @@ def test_to_json(self): obj = stripe.stripe_object.StripeObject.construct_from( SAMPLE_INVOICE, 'key') - self.check_invoice_data(util.json.loads(str(obj))) + self.check_invoice_data(json.loads(str(obj))) def check_invoice_data(self, data): # Check rough structure diff --git a/tests/test_stripe_response.py b/tests/test_stripe_response.py index fff4e3396..d6b5b4191 100644 --- a/tests/test_stripe_response.py +++ b/tests/test_stripe_response.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, division, print_function -from stripe import util +import json + from stripe.stripe_response import StripeResponse @@ -27,7 +28,7 @@ def test_body(self): def test_data(self): response, headers, body, code = self.mock_stripe_response() - assert response.data == util.json.loads(body) + assert response.data == json.loads(body) @staticmethod def mock_stripe_response(): From 795a5dd41b3f7c819455430296da433abb35e3b7 Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Mon, 5 Mar 2018 17:26:25 +0100 Subject: [PATCH 5/7] Update setup.py and test flow --- .coveragerc | 4 ++++ .flake8 | 3 +++ .travis.yml | 20 ++------------------ MANIFEST.in | 2 +- pytest.ini | 2 ++ setup.cfg | 3 --- setup.py | 49 +++++++++++++++++++++++++++++++++++-------------- tox.ini | 22 ++-------------------- 8 files changed, 49 insertions(+), 56 deletions(-) create mode 100644 .coveragerc create mode 100644 .flake8 create mode 100644 pytest.ini diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..7492b713f --- /dev/null +++ b/.coveragerc @@ -0,0 +1,4 @@ +[run] +source = stripe +omit = + stripe/six.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..c209acb60 --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +exclude = + six.py diff --git a/.travis.yml b/.travis.yml index 1e06fda89..2452f46e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,22 +12,14 @@ python: - "pypy3" cache: - apt: true directories: - stripe-mock pip: false env: global: - - PYCURL_SSL_LIBRARY=gnutls - STRIPE_MOCK_VERSION=0.19.0 -addons: - apt: - packages: - - libcurl4-gnutls-dev - - librtmp-dev - before_install: # Unpack and start stripe-mock so that the test suite can talk to it - | @@ -41,20 +33,12 @@ before_install: STRIPE_MOCK_PID=$! install: - - pip install -U setuptools pip - - pip install pycurl flake8 coveralls - - python setup.py clean --all + - pip install -U setuptools pip flake8 coveralls - python setup.py install script: - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then flake8 stripe tests; fi - - python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe" + - python setup.py test -a "-n 8" after_success: coveralls - -matrix: - allow_failures: - - python: 3.7-dev - - python: pypy - - python: pypy3 diff --git a/MANIFEST.in b/MANIFEST.in index 498ecd137..4293df995 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ -include CHANGELOG.md LICENSE LONG_DESCRIPTION.rst README.md VERSION tox.ini +include .coveragerc .flake8 CHANGELOG.md LICENSE LONG_DESCRIPTION.rst README.md VERSION pytest.ini tox.ini recursive-include tests *.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..1ceab9429 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = -p no:warnings diff --git a/setup.cfg b/setup.cfg index 3caebad48..ed8a958e0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,3 @@ -[aliases] -test=pytest - [bdist_wheel] universal = 1 diff --git a/setup.py b/setup.py index 2b604a620..f6de7988f 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,31 @@ -import os import sys +from codecs import open +from os import path +from setuptools import setup, find_packages +from setuptools.command.test import test as TestCommand -try: - from setuptools import setup -except ImportError: - from distutils.core import setup +class PyTest(TestCommand): + user_options = [('pytest-args=', 'a', "Arguments to pass into py.test")] -path, script = os.path.split(sys.argv[0]) -os.chdir(os.path.abspath(path)) + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '-n auto' -with open('LONG_DESCRIPTION.rst') as f: + def run_tests(self): + import shlex + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + + +here = path.abspath(path.dirname(__file__)) + +with open(path.join(here, 'LONG_DESCRIPTION.rst'), encoding='utf-8') as f: long_description = f.read() version_contents = {} -with open(os.path.join('stripe', 'version.py')) as f: +with open(path.join(here, 'stripe', 'version.py'), encoding='utf-8') as f: exec(f.read(), version_contents) tests_require = [ @@ -31,18 +42,27 @@ author_email='support@stripe.com', url='https://github.com/stripe/stripe-python', license='MIT', - packages=['stripe', 'stripe.api_resources', - 'stripe.api_resources.abstract'], + keywords='stripe api payments', + packages=find_packages(exclude=['tests', 'tests.*']), package_data={'stripe': ['data/ca-certificates.crt']}, + zip_safe=False, install_requires=[ - 'requests >= 0.8.8', + 'requests >= 2', + 'requests[security] >= 2; python_version < "3.0"', ], - setup_requires=['pytest-runner'], + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", tests_require=[ 'pytest >= 3.4', 'pytest-mock >= 1.7', + 'pytest-xdist >= 1.22', 'pytest-cov >= 2.5', ], + cmdclass={'test': PyTest}, + project_urls={ + 'Bug Tracker': 'https://github.com/stripe/stripe-python/issues', + 'Documentation': 'https://stripe.com/docs/api/python', + 'Source Code': 'https://github.com/stripe/stripe-python', + }, classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -57,4 +77,5 @@ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", - ]) + ], +) diff --git a/tox.ini b/tox.ini index cb04c2019..9a0a17d93 100644 --- a/tox.ini +++ b/tox.ini @@ -7,30 +7,12 @@ envlist = py27, py34, py35, py36, pypy, pypy3 [testenv] -deps = - pycurl>=7.19 - requests>=0.8.8 commands = - python setup.py clean --all - python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe {posargs}" -setenv = - STRIPE_TEST_PYCURL = true + python setup.py test -a "{posargs:-n auto}" [testenv:py27] deps = flake8 - pycurl>=7.19 - requests>=0.8.8 commands = flake8 stripe tests - python setup.py clean --all - python -W all -bb -W error::BytesWarning setup.py test --addopts "--cov=stripe {posargs}" - -[flake8] -exclude = - six.py - -[coverage:run] -source = stripe -omit = - stripe/six.py + python setup.py test -a "{posargs:-n auto}" From 555a4c668e8da853ce6345bd0d0fb829b5fa4eec Mon Sep 17 00:00:00 2001 From: Olivier Bellone Date: Tue, 13 Mar 2018 15:03:19 +0100 Subject: [PATCH 6/7] Use pipenv for managing developement virtualenv --- .travis.yml | 10 +- Makefile | 11 ++ Pipfile | 27 ++++ Pipfile.lock | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 22 ++-- setup.py | 2 +- tox.ini | 25 ++-- 7 files changed, 420 insertions(+), 24 deletions(-) create mode 100644 Makefile create mode 100644 Pipfile create mode 100644 Pipfile.lock diff --git a/.travis.yml b/.travis.yml index 2452f46e6..e14ebd483 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,12 @@ before_install: STRIPE_MOCK_PID=$! install: - - pip install -U setuptools pip flake8 coveralls - - python setup.py install + - pip install --upgrade pipenv + - pipenv install --dev script: - - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then flake8 stripe tests; fi - - python setup.py test -a "-n 8" + - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then make lint; fi + - make ci after_success: - coveralls + make coveralls diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..0bd069447 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +test: + pipenv run detox + +ci: + pipenv run pytest --cov=stripe -n 8 + +coveralls: + pipenv run coveralls + +lint: + pipenv run tox -e lint diff --git a/Pipfile b/Pipfile new file mode 100644 index 000000000..901f8c91d --- /dev/null +++ b/Pipfile @@ -0,0 +1,27 @@ +[[source]] + +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + + +[packages] + +"stripe" = {path = ".", editable = true} + + +[dev-packages] + +pytest = ">=3.4" +pytest-mock = ">=1.7" +pytest-xdist = ">=1.22" +pytest-cov = ">=2.5" +tox = "*" +detox = "*" +"flake8" = "*" +coveralls = "*" + + +[requires] + +python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 000000000..f8882f61f --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,347 @@ +{ + "_meta": { + "hash": { + "sha256": "619e1f38cced6fe1a1d1282c4187c219f31b7198bece226d595eb90ebfc3bde4" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", + "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" + ], + "version": "==2018.4.16" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "idna": { + "hashes": [ + "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", + "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" + ], + "version": "==2.7" + }, + "requests": { + "hashes": [ + "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", + "sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a" + ], + "markers": "python_version != '3.1.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", + "version": "==2.19.1" + }, + "stripe": { + "editable": true, + "path": "." + }, + "urllib3": { + "hashes": [ + "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", + "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" + ], + "markers": "python_version != '3.1.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", + "version": "==1.23" + } + }, + "develop": { + "apipkg": { + "hashes": [ + "sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6", + "sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c" + ], + "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", + "version": "==1.5" + }, + "atomicwrites": { + "hashes": [ + "sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585", + "sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6" + ], + "version": "==1.1.5" + }, + "attrs": { + "hashes": [ + "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265", + "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b" + ], + "version": "==18.1.0" + }, + "certifi": { + "hashes": [ + "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", + "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" + ], + "version": "==2018.4.16" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "coverage": { + "hashes": [ + "sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba", + "sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed", + "sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640", + "sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162", + "sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508", + "sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249", + "sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694", + "sha256:3c79a6f7b95751cdebcd9037e4d06f8d5a9b60e4ed0cd231342aa8ad7124882a", + "sha256:3d72c20bd105022d29b14a7d628462ebdc61de2f303322c0212a054352f3b287", + "sha256:3eb42bf89a6be7deb64116dd1cc4b08171734d721e7a7e57ad64cc4ef29ed2f1", + "sha256:4635a184d0bbe537aa185a34193898eee409332a8ccb27eea36f262566585000", + "sha256:56e448f051a201c5ebbaa86a5efd0ca90d327204d8b059ab25ad0f35fbfd79f1", + "sha256:5a13ea7911ff5e1796b6d5e4fbbf6952381a611209b736d48e675c2756f3f74e", + "sha256:69bf008a06b76619d3c3f3b1983f5145c75a305a0fea513aca094cae5c40a8f5", + "sha256:6bc583dc18d5979dc0f6cec26a8603129de0304d5ae1f17e57a12834e7235062", + "sha256:701cd6093d63e6b8ad7009d8a92425428bc4d6e7ab8d75efbb665c806c1d79ba", + "sha256:7608a3dd5d73cb06c531b8925e0ef8d3de31fed2544a7de6c63960a1e73ea4bc", + "sha256:76ecd006d1d8f739430ec50cc872889af1f9c1b6b8f48e29941814b09b0fd3cc", + "sha256:7aa36d2b844a3e4a4b356708d79fd2c260281a7390d678a10b91ca595ddc9e99", + "sha256:7d3f553904b0c5c016d1dad058a7554c7ac4c91a789fca496e7d8347ad040653", + "sha256:7e1fe19bd6dce69d9fd159d8e4a80a8f52101380d5d3a4d374b6d3eae0e5de9c", + "sha256:8c3cb8c35ec4d9506979b4cf90ee9918bc2e49f84189d9bf5c36c0c1119c6558", + "sha256:9d6dd10d49e01571bf6e147d3b505141ffc093a06756c60b053a859cb2128b1f", + "sha256:be6cfcd8053d13f5f5eeb284aa8a814220c3da1b0078fa859011c7fffd86dab9", + "sha256:c1bb572fab8208c400adaf06a8133ac0712179a334c09224fb11393e920abcdd", + "sha256:de4418dadaa1c01d497e539210cb6baa015965526ff5afc078c57ca69160108d", + "sha256:e05cb4d9aad6233d67e0541caa7e511fa4047ed7750ec2510d466e806e0255d6", + "sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80" + ], + "markers": "python_version != '3.1.*' and python_version < '4' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", + "version": "==4.5.1" + }, + "coveralls": { + "hashes": [ + "sha256:32569a43c9dbc13fa8199247580a4ab182ef439f51f65bb7f8316d377a1340e8", + "sha256:664794748d2e5673e347ec476159a9d87f43e0d2d44950e98ed0e27b98da8346" + ], + "index": "pypi", + "version": "==1.3.0" + }, + "detox": { + "hashes": [ + "sha256:cb24895a0e4f95c0bcb1087a201c453600e075568af00848e91518fb2b984568", + "sha256:f3119bca4444f1e8a1d7189b064c52cfdd9a89ad3a1c921d78b49bf7f5dc5b1b" + ], + "index": "pypi", + "version": "==0.12" + }, + "docopt": { + "hashes": [ + "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491" + ], + "version": "==0.6.2" + }, + "eventlet": { + "hashes": [ + "sha256:06cffa55b335cc4fc32d0079242a81e8a9cddf2581d64d5f0543e2d412b26ca8", + "sha256:554a50dad7abee0a9775b0780ce9d9c0bd9123dda4743c46d4314170267c6c47" + ], + "version": "==0.23.0" + }, + "execnet": { + "hashes": [ + "sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a", + "sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83" + ], + "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", + "version": "==1.5.0" + }, + "flake8": { + "hashes": [ + "sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0", + "sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37" + ], + "index": "pypi", + "version": "==3.5.0" + }, + "greenlet": { + "hashes": [ + "sha256:09ef2636ea35782364c830f07127d6c7a70542b178268714a9a9ba16318e7e8b", + "sha256:0fef83d43bf87a5196c91e73cb9772f945a4caaff91242766c5916d1dd1381e4", + "sha256:1b7df09c6598f5cfb40f843ade14ed1eb40596e75cd79b6fa2efc750ba01bb01", + "sha256:1fff21a2da5f9e03ddc5bd99131a6b8edf3d7f9d6bc29ba21784323d17806ed7", + "sha256:42118bf608e0288e35304b449a2d87e2ba77d1e373e8aa221ccdea073de026fa", + "sha256:50643fd6d54fd919f9a0a577c5f7b71f5d21f0959ab48767bd4bb73ae0839500", + "sha256:58798b5d30054bb4f6cf0f712f08e6092df23a718b69000786634a265e8911a9", + "sha256:5b49b3049697aeae17ef7bf21267e69972d9e04917658b4e788986ea5cc518e8", + "sha256:75c413551a436b462d5929255b6dc9c0c3c2b25cbeaee5271a56c7fda8ca49c0", + "sha256:769b740aeebd584cd59232be84fdcaf6270b8adc356596cdea5b2152c82caaac", + "sha256:a1852b51b06d1367e2d70321f6801844f5122852c9e5169bdfdff3f4d81aae30", + "sha256:ad2383d39f13534f3ca5c48fe1fc0975676846dc39c2cece78c0f1f9891418e0", + "sha256:b417bb7ff680d43e7bd7a13e2e08956fa6acb11fd432f74c97b7664f8bdb6ec1", + "sha256:b6ef0cabaf5a6ecb5ac122e689d25ba12433a90c7b067b12e5f28bdb7fb78254", + "sha256:c2de19c88bdb0366c976cc125dca1002ec1b346989d59524178adfd395e62421", + "sha256:c7b04a6dc74087b1598de8d713198de4718fa30ec6cbb84959b26426c198e041", + "sha256:f8f2a0ae8de0b49c7b5b2daca4f150fdd9c1173e854df2cce3b04123244f9f45", + "sha256:fcfadaf4bf68a27e5dc2f42cbb2f4b4ceea9f05d1d0b8f7787e640bed2801634" + ], + "version": "==0.4.13" + }, + "idna": { + "hashes": [ + "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", + "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" + ], + "version": "==2.7" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "more-itertools": { + "hashes": [ + "sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8", + "sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3", + "sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0" + ], + "version": "==4.2.0" + }, + "packaging": { + "hashes": [ + "sha256:e9215d2d2535d3ae866c3d6efc77d5b24a0192cce0ff20e42896cc0664f889c0", + "sha256:f019b770dd64e585a99714f1fd5e01c7a8f11b45635aa953fd41c689a657375b" + ], + "version": "==17.1" + }, + "pluggy": { + "hashes": [ + "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff", + "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c", + "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5" + ], + "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", + "version": "==0.6.0" + }, + "py": { + "hashes": [ + "sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7", + "sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e" + ], + "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", + "version": "==1.5.4" + }, + "pycodestyle": { + "hashes": [ + "sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766", + "sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9" + ], + "version": "==2.3.1" + }, + "pyflakes": { + "hashes": [ + "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f", + "sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805" + ], + "version": "==1.6.0" + }, + "pyparsing": { + "hashes": [ + "sha256:0832bcf47acd283788593e7a0f542407bd9550a55a8a8435214a1960e04bcb04", + "sha256:fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010" + ], + "version": "==2.2.0" + }, + "pytest": { + "hashes": [ + "sha256:0453c8676c2bee6feb0434748b068d5510273a916295fd61d306c4f22fbfd752", + "sha256:4b208614ae6d98195430ad6bde03641c78553acee7c83cec2e85d613c0cd383d" + ], + "index": "pypi", + "version": "==3.6.3" + }, + "pytest-cov": { + "hashes": [ + "sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d", + "sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec" + ], + "index": "pypi", + "version": "==2.5.1" + }, + "pytest-forked": { + "hashes": [ + "sha256:e4500cd0509ec4a26535f7d4112a8cc0f17d3a41c29ffd4eab479d2a55b30805", + "sha256:f275cb48a73fc61a6710726348e1da6d68a978f0ec0c54ece5a5fae5977e5a08" + ], + "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", + "version": "==0.2" + }, + "pytest-mock": { + "hashes": [ + "sha256:53801e621223d34724926a5c98bd90e8e417ce35264365d39d6c896388dcc928", + "sha256:d89a8209d722b8307b5e351496830d5cc5e192336003a485443ae9adeb7dd4c0" + ], + "index": "pypi", + "version": "==1.10.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:be2662264b035920ba740ed6efb1c816a83c8a22253df7766d129f6a7bfdbd35", + "sha256:e8f5744acc270b3e7d915bdb4d5f471670f049b6fbd163d4cbd52203b075d30f" + ], + "index": "pypi", + "version": "==1.22.2" + }, + "requests": { + "hashes": [ + "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", + "sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a" + ], + "markers": "python_version != '3.1.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", + "version": "==2.19.1" + }, + "six": { + "hashes": [ + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" + ], + "version": "==1.11.0" + }, + "tox": { + "hashes": [ + "sha256:017b7c0b2483f417dffbe05bd2b8b435c6982190a774b60c1225ba3c099b2d31", + "sha256:de70c2ab27aa4c4af5534261db7d52f9e52e2a9f2d4061eb99eefb0beb52a32b" + ], + "index": "pypi", + "version": "==3.1.0" + }, + "urllib3": { + "hashes": [ + "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", + "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" + ], + "markers": "python_version != '3.1.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", + "version": "==1.23" + }, + "virtualenv": { + "hashes": [ + "sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669", + "sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752" + ], + "markers": "python_version != '3.1.*' and python_version != '3.2.*' and python_version >= '2.7' and python_version != '3.0.*'", + "version": "==16.0.0" + } + } +} diff --git a/README.md b/README.md index 138937872..90e1fb76f 100644 --- a/README.md +++ b/README.md @@ -144,33 +144,37 @@ instructions for installing via Homebrew and other methods): go get -u github.com/stripe/stripe-mock stripe-mock -Tests are managed by `tox`. Install using `pip` +Install [pipenv][pipenv], then install all dependencies for the project: - pip install tox + pipenv install --dev -Run all tests (modify `-e` according to your Python target): +Run all tests on all supported Python versions: - tox -e py27 + make test + +Run all tests for a specific Python version (modify `-e` according to your Python target): + + pipenv run tox -e py27 Run all tests in a single file: - tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py + pipenv run tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py Run a single test suite: - tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource + pipenv run tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource Run a single test: - tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource::test_save + pipenv run tox -e py27 -- tests/api_resources/abstract/test_updateable_api_resource.py::TestUpdateableAPIResource::test_save Run the linter with: - pip install flake8 - flake8 stripe tests + make lint [api-keys]: https://dashboard.stripe.com/account/apikeys [connect]: https://stripe.com/connect +[pipenv]: https://github.com/pypa/pipenv [stripe-mock]: https://github.com/stripe/stripe-mock