Skip to content
Browse files

pep8

  • Loading branch information...
1 parent b9fda9a commit 3c121863a384f53897de0c8ec7ab3a64c60b6d83 @hmarr hmarr committed Jul 9, 2012
View
12 gocardless/__init__.py
@@ -23,14 +23,16 @@
VERSION = (0, 1, 2)
+
def get_version():
return '.'.join(str(part) for part in VERSION)
from .client import Client
#import as clientlib so that we don't shadow with the client variable
import client as clientlib
-from gocardless.resources import Bill, Subscription, PreAuthorization, User, Merchant
+from gocardless.resources import (Bill, Subscription, PreAuthorization, User,
+ Merchant)
environment = 'production'
"""The environment GoCardless executes API requests against, should be
@@ -42,7 +44,9 @@ def get_version():
:py:func:`gocardless.set_details` has been called.
"""
-def set_details(app_id=None, app_secret=None, access_token=None, merchant_id=None):
+
+def set_details(app_id=None, app_secret=None, access_token=None,
+ merchant_id=None):
"""Set the global account details to use for requests
The parameters are your security details which can be found
@@ -58,6 +62,6 @@ def set_details(app_id=None, app_secret=None, access_token=None, merchant_id=Non
raise ValueError("merchant_id is required")
global client
- client = Client(app_id, app_secret, access_token=access_token,
- merchant_id=merchant_id)
+ client = Client(app_id, app_secret, access_token=access_token,
+ merchant_id=merchant_id)
View
124 gocardless/client.py
@@ -6,10 +6,12 @@
from gocardless.utils import generate_signature, to_query, signature_valid
from gocardless.request import Request
from gocardless.exceptions import ClientError, SignatureError
-from gocardless.resources import Merchant, Subscription, Bill, PreAuthorization, User
+from gocardless.resources import (Merchant, Subscription, Bill,
+ PreAuthorization, User)
logger = logging.getLogger(__name__)
+
class Client(object):
"""The main interface to the GoCardless API
@@ -27,8 +29,8 @@ class Client(object):
API_PATH = '/api/v1'
BASE_URLS = {
- 'production': 'https://gocardless.com',
- 'sandbox': 'https://sandbox.gocardless.com',
+ 'production': 'https://gocardless.com',
+ 'sandbox': 'https://sandbox.gocardless.com',
}
base_url = None
@@ -42,16 +44,17 @@ def get_base_url(cls):
return cls.base_url or cls.BASE_URLS[gocardless.environment]
def __init__(self, app_id, app_secret, access_token=None,
- merchant_id=None):
+ merchant_id=None):
"""Create a client
:param string app_id: Your application id.
:param string app_secret: Your app secret.
- :param string access_token: The access token for this account, this should
- be your access token from the developer settings page unless you are
- trying to manage another merchants' account via OAuth.
- :param string merchant_id: The merchant id for this account, should be your
- merchant id unless you are trying to manage another account via OAuth.
+ :param string access_token: The access token for this account, this
+ should be your access token from the developer settings page unless
+ you are trying to manage another merchants' account via OAuth.
+ :param string merchant_id: The merchant id for this account, should be
+ your merchant id unless you are trying to manage another account
+ via OAuth.
"""
self._app_id = app_id
self._app_secret = app_secret
@@ -75,7 +78,7 @@ def api_post(self, path, data, **kwargs):
:param data: The data to post to the url.
"""
return self._request('post', Client.API_PATH + path, data=data,
- **kwargs)
+ **kwargs)
def api_delete(self, path, **kwargs):
"""Issue a delete to the API server.
@@ -114,7 +117,8 @@ def merchant(self):
"""
Returns the current Merchant's details.
"""
- return Merchant(self.api_get('/merchants/%s' % self._merchant_id), self)
+ merchant_url = '/merchants/%s' % self._merchant_id
+ return Merchant(self.api_get(mechant_url), self)
def user(self, id):
"""
@@ -157,13 +161,12 @@ def create_bill(self, amount, pre_auth_id, name=None, description=None):
"""
return Bill.create_under_preauth(amount, pre_auth_id, self,
- name=name, description=description)
-
+ name=name, description=description)
def new_subscription_url(self, amount, interval_length, interval_unit,
- name=None, description=None, interval_count=None, start_at=None,
- expires_at=None, redirect_uri=None, cancel_uri=None, state=None,
- user=None):
+ name=None, description=None, interval_count=None,
+ start_at=None, expires_at=None, redirect_uri=None,
+ cancel_uri=None, state=None, user=None):
"""Generate a url for creating a new subscription
:param amount: The amount to charge each time
@@ -194,18 +197,19 @@ def new_subscription_url(self, amount, interval_length, interval_unit,
- `email`
"""
- params = urlbuilder.SubscriptionParams(amount, self._merchant_id,
- interval_length, interval_unit, name=name,
- description=description, interval_count=interval_count,
- expires_at=expires_at, start_at=start_at, user=user)
+ params = urlbuilder.SubscriptionParams(
+ amount, self._merchant_id,
+ interval_length, interval_unit, name=name,
+ description=description, interval_count=interval_count,
+ expires_at=expires_at, start_at=start_at, user=user
+ )
builder = urlbuilder.UrlBuilder(self)
return builder.build_and_sign(params, redirect_uri=redirect_uri,
- cancel_uri=cancel_uri, state=state)
-
+ cancel_uri=cancel_uri, state=state)
def new_bill_url(self, amount, name=None, description=None,
- redirect_uri=None, cancel_uri=None, state=None,
- user=None):
+ redirect_uri=None, cancel_uri=None, state=None,
+ user=None):
"""Generate a url for creating a new bill
:param amount: The amount to bill the customer
@@ -226,15 +230,16 @@ def new_bill_url(self, amount, name=None, description=None,
"""
params = urlbuilder.BillParams(amount, self._merchant_id, name=name,
- description=description, user=user)
+ description=description, user=user)
builder = urlbuilder.UrlBuilder(self)
return builder.build_and_sign(params, redirect_uri=redirect_uri,
- cancel_uri=cancel_uri, state=state)
+ cancel_uri=cancel_uri, state=state)
- def new_preauthorization_url(self,max_amount, interval_length,\
- interval_unit, expires_at=None, name=None, description=None,\
- interval_count=None, calendar_intervals=None,
- redirect_uri=None, cancel_uri=None, state=None, user=None):
+ def new_preauthorization_url(self, max_amount, interval_length,
+ interval_unit, expires_at=None, name=None,
+ description=None, interval_count=None,
+ calendar_intervals=None, redirect_uri=None,
+ cancel_uri=None, state=None, user=None):
"""Get a url for creating new pre_authorizations
:param max_amount: A float which is the maximum amount for this
@@ -252,9 +257,9 @@ def new_preauthorization_url(self,max_amount, interval_length,\
pre_authorization is for.
:param interval_count: calculates expires_at based on the number of
payment intervals you would like the resource to have. Must be a
- positive integer greater than 0. If you specify both an interval_count
- and an expires_at argument then the expires_at argument will take
- precedence.
+ positive integer greater than 0. If you specify both an
+ interval_count and an expires_at argument then the expires_at
+ argument will take precedence.
:param calendar_intervals: Describes whether the interval resource
should be aligned with calendar weeks or months, default is False
:param redirect_uri: URI to redirect to after the authorization process
@@ -270,14 +275,15 @@ def new_preauthorization_url(self,max_amount, interval_length,\
- `email`
"""
- params = urlbuilder.PreAuthorizationParams(max_amount,
- self._merchant_id, interval_length, interval_unit,
- expires_at=expires_at, name=name, description=description,
- interval_count=interval_count, user=user,
- calendar_intervals=calendar_intervals)
+ params = urlbuilder.PreAuthorizationParams(
+ max_amount, self._merchant_id, interval_length, interval_unit,
+ expires_at=expires_at, name=name, description=description,
+ interval_count=interval_count, user=user,
+ calendar_intervals=calendar_intervals
+ )
builder = urlbuilder.UrlBuilder(self)
return builder.build_and_sign(params, redirect_uri=redirect_uri,
- cancel_uri=cancel_uri, state=state)
+ cancel_uri=cancel_uri, state=state)
def confirm_resource(self, params):
"""Confirm a payment
@@ -291,17 +297,18 @@ def confirm_resource(self, params):
- state (if any)
"""
keys = ["resource_uri", "resource_id", "resource_type", "state"]
- to_check = dict([[k,v] for k,v in params.items() if k in keys])
+ to_check = dict([[k, v] for k, v in params.items() if k in keys])
signature = generate_signature(to_check, self._app_secret)
if not signature == params["signature"]:
raise SignatureError("Invalid signature when confirming resource")
auth_string = base64.b64encode("{0}:{1}".format(
self._app_id, self._app_secret))
to_post = {
- "resource_id":params["resource_id"],
- "resource_type":params["resource_type"]
- }
- self.api_post("/confirm", to_post, auth=(self._app_id, self._app_secret))
+ "resource_id": params["resource_id"],
+ "resource_type": params["resource_type"],
+ }
+ auth_details = (self._app_id, self._app_secret)
+ self.api_post("/confirm", to_post, auth=auth_details)
def new_merchant_url(self, redirect_uri, state=None, merchant=None):
"""Get a URL for managing a new merchant
@@ -331,17 +338,17 @@ def new_merchant_url(self, redirect_uri, state=None, merchant=None):
"""
params = {
- "client_id":self._app_id,
- "redirect_uri":redirect_uri,
- "scope":"manage_merchant",
- "response_type":"code"
- }
+ "client_id": self._app_id,
+ "redirect_uri": redirect_uri,
+ "scope": "manage_merchant",
+ "response_type": "code",
+ }
if state:
params["state"] = state
if merchant:
params["merchant"] = merchant
return "{0}/oauth/authorize?{1}".format(self.get_base_url(),
- to_query(params))
+ to_query(params))
def fetch_access_token(self, redirect_uri, authorization_code):
"""Fetch the access token for a merchant
@@ -359,17 +366,18 @@ def fetch_access_token(self, redirect_uri, authorization_code):
"""
params = {
- "client_id":self._app_id,
- "code":authorization_code,
- "redirect_uri":redirect_uri,
- "grant_type":"authorization_code"
- }
+ "client_id": self._app_id,
+ "code": authorization_code,
+ "redirect_uri": redirect_uri,
+ "grant_type": "authorization_code"
+ }
query = to_query(params)
url = "/oauth/access_token?{0}".format(query)
- #just to test the oauth call
+ # just to test the oauth call
self.base_url = "http://sandbox.gocardless.com"
- #have to use _request so we don't add api_base to the url
- result = self._request("post", url, auth=(self._app_id, self._app_secret))
+ # have to use _request so we don't add api_base to the url
+ auth_details = (self._app_id, self._app_secret)
+ result = self._request("post", url, auth=auth_details)
self._access_token = result["access_token"]
self._merchant_id = result["scope"].split(":")[1]
return self._access_token
View
6 gocardless/merchant.py
@@ -1,4 +1,3 @@
-
class Merchant(object):
def __init__(self, client, data):
@@ -29,6 +28,5 @@ def pre_authorization(self, pre_authorization_id):
"""
Return the pre_authorization with `pre_authorization_id` or `None`
"""
-
-
-
+ return self.client.pre_authorization(subscription_id)
+
View
5 gocardless/request.py
@@ -10,8 +10,9 @@ def __init__(self, method, url):
self._url = url
headers = {}
headers["Accept"] = "application/json"
- headers["User-Agent"] = "gocardless-python/{0}".format(gocardless.get_version())
- self._opts = {"headers" : headers }
+ lib_version = gocardless.get_version()
+ headers["User-Agent"] = "gocardless-python/{0}".format(lib_version)
+ self._opts = {"headers": headers}
if not self._valid_method(method):
raise ValueError('Invalid method {}'.format(method))
View
45 gocardless/resources.py
@@ -26,11 +26,11 @@ class Resource(object):
The class attribute `endpoint` is the path to the resource on the server.
- The class attribute `date_fields` names fields which will be converted
+ The class attribute `date_fields` names fields which will be converted
into `datetime.datetime` objects on construction.
The class attribute `reference_fields` names fields which are uris to other
- resources and will be converted into functions which can be called to
+ resources and will be converted into functions which can be called to
retrieve those resources.
"""
__metaclass__ = ResourceMetaClass
@@ -39,10 +39,10 @@ class Resource(object):
reference_fields = []
def __init__(self, in_attrs, client):
- """Construct a resource
+ """Construct a resource
- :param in_attrs: A dictionary of attributes, usually obtained from a
- JSON response.
+ :param in_attrs: A dictionary of attributes, usually obtained from a
+ JSON response.
:param client: an instance of gocardless.Client
"""
attrs = in_attrs.copy()
@@ -57,24 +57,25 @@ def __init__(self, in_attrs, client):
path = re.sub(".*/api/v1", "", uri)
sub_klass = self._get_klass_from_name(name)
def create_get_resource_func(the_path, the_klass):
- #In python functions close over their environment so in
- #order to create the correct closure we need a function
- #creator, see
- #http://stackoverflow.com/questions/233673/
- # lexical-closures-in-python/235764#235764
+ # In python functions close over their environment so in
+ # order to create the correct closure we need a function
+ # creator, see
+ # http://stackoverflow.com/questions/233673/
+ # lexical-closures-in-python/235764#235764
def get_resources(inst):
data = inst.client.api_get(the_path)
return [the_klass(attrs, self.client) for attrs in data]
return get_resources
res_func = create_get_resource_func(path, sub_klass)
func_name = "{0}".format(name)
res_func.name = func_name
- setattr(self, func_name, types.MethodType(res_func, self, self.__class__))
+ setattr(self, func_name,
+ types.MethodType(res_func, self, self.__class__))
for fieldname in self.date_fields:
val = attrs.pop(fieldname)
if val is not None:
- setattr(self, fieldname,
+ setattr(self, fieldname,
datetime.datetime.strptime(val, "%Y-%m-%dT%H:%M:%SZ"))
else:
setattr(self, fieldname, None)
@@ -98,15 +99,14 @@ def _get_klass_from_name(self, name):
klass = getattr(module, utils.singularize(utils.camelize(name)))
return klass
-
def get_endpoint(self):
return self.endpoint.replace(":id", self.id)
def __eq__(self, other):
if isinstance(other, self.__class__):
return self._raw_attrs == other._raw_attrs
return False
-
+
def __hash__(self):
return hash(self._raw_attrs["id"])
@@ -144,7 +144,7 @@ class PreAuthorization(Resource):
def create_bill(self, amount, name=None, description=None):
return Bill.create_under_preauth(amount, self.id, self.client,
- name=name, description=description)
+ name=name, description=description)
class Bill(Resource):
@@ -153,14 +153,15 @@ class Bill(Resource):
reference_fields = ["merchant_id", "user_id"]
@classmethod
- def create_under_preauth(self, amount, pre_auth_id, client, name=None,
- description=None):
+ def create_under_preauth(self, amount, pre_auth_id, client, name=None,
+ description=None):
path = "/bills"
- params = {"bill":{
- "amount":amount,
- "pre_authorization_id":pre_auth_id
- }
- }
+ params = {
+ "bill": {
+ "amount": amount,
+ "pre_authorization_id": pre_auth_id
+ }
+ }
if name:
params["bill"]["name"] = name
if description:
View
103 gocardless/urlbuilder.py
@@ -3,6 +3,7 @@
import os
import utils
+
class UrlBuilder(object):
"""Handles correctly encoding and signing api urls"""
@@ -14,8 +15,8 @@ def __init__(self, client):
"""
self.client = client
- def build_and_sign(self, params, state=None, redirect_uri=None,
- cancel_uri=None):
+ def build_and_sign(self, params, state=None, redirect_uri=None,
+ cancel_uri=None):
"""Builds a url and returns it as a string
:param params: A Params class corresponding to the resource for which
@@ -28,29 +29,36 @@ def build_and_sign(self, params, state=None, redirect_uri=None,
cancel the resource creation
"""
param_dict = {}
- param_dict[utils.singularize(params.resource_name)] = params.to_dict().copy()
+ resource_name = utils.singularize(params.resource_name)
+ param_dict[resource_name] = params.to_dict().copy()
if state:
param_dict["state"] = state
if redirect_uri:
param_dict["redirect_uri"] = redirect_uri
if cancel_uri:
param_dict["cancel_uri"] = cancel_uri
- param_dict["client_id"] = self.client._app_id
- param_dict["timestamp"] = datetime.datetime.utcnow().isoformat()[:-7] + "Z"
+ param_dict["client_id"] = self.client._app_id
+ iso_time = datetime.datetime.utcnow().isoformat()
+ param_dict["timestamp"] = iso_time[:-7] + "Z"
param_dict["nonce"] = base64.b64encode(os.urandom(40))
signature = utils.generate_signature(param_dict, self.client._app_secret)
param_dict["signature"] = signature
- url = self.client.get_base_url() + "/connect/" + params.resource_name + \
- "/new?" + utils.to_query(param_dict)
+ url = "{0}/connect/{1}/new?{2}".format(
+ self.client.get_base_url(),
+ params.resource_name,
+ utils.to_query(param_dict),
+ )
return url
+
class BasicParams(object):
- def __init__(self, amount, merchant_id, name=None, description=None, user=None):
+ def __init__(self, amount, merchant_id, name=None, description=None,
+ user=None):
if not amount > 0:
raise ValueError("amount must be positive, value passed was"
- " {0}".format(amount))
+ " {0}".format(amount))
self.amount = amount
self.merchant_id = merchant_id
@@ -74,10 +82,10 @@ def to_dict(self):
class PreAuthorizationParams(object):
-
- def __init__(self,max_amount, merchant_id, interval_length,\
- interval_unit, expires_at=None, name=None, description=None,\
- interval_count=None, calendar_intervals=None, user=None):
+
+ def __init__(self, max_amount, merchant_id, interval_length,
+ interval_unit, expires_at=None, name=None, description=None,
+ interval_count=None, calendar_intervals=None, user=None):
self.merchant_id = merchant_id
self.resource_name = "pre_authorizations"
@@ -92,42 +100,45 @@ def __init__(self,max_amount, merchant_id, interval_length,\
if not interval_length > 0:
raise ValueError("interval_length must be positive, value "
- "passed was {0}".format(interval_length))
+ "passed was {0}".format(interval_length))
self.interval_length = interval_length
valid_units = ["month", "day", "week"]
if interval_unit not in valid_units:
- raise ValueError("interval_unit must be one of {0},"
- "value passed was {1}".format(valid_units, interval_unit))
+ message = "interval_unit must be one of {0}, value passed was {1}"
+ raise ValueError(message.format(valid_units, interval_unit))
self.interval_unit = interval_unit
if expires_at:
if (expires_at - datetime.datetime.now()).total_seconds() < 0:
+ time_str = expires_at.isoformat()
raise ValueError("expires_at must be in the future, date "
- "passed was {0}".format(expires_at.isoformat()))
+ "passed was {0}".format(time_str))
self.expires_at = expires_at
else:
self.expires_at = None
if interval_count:
if interval_count < 0:
raise ValueError("interval_count must be positive "
- "value passed was {0}".format(interval_count))
+ "value passed was {0}".format(interval_count))
self.interval_count = interval_count
- else:
+ else:
self.interval_count = None
self.name = name if name else None
self.description = description if description else None
- self.calendar_intervals = calendar_intervals if calendar_intervals\
- else None
+ self.calendar_intervals = None
+ if calendar_intervals:
+ self.calendar_intervals = calendar_intervals
def to_dict(self):
result = {}
- attrnames = ["merchant_id", "name", "description",
- "interval_count", "interval_unit", "interval_length",
- "max_amount", "calendar_intervals", "expires_at",
- "user"]
+ attrnames = [
+ "merchant_id", "name", "description", "interval_count",
+ "interval_unit", "interval_length", "max_amount",
+ "calendar_intervals", "expires_at", "user"
+ ]
for attrname in attrnames:
val = getattr(self, attrname, None)
if val:
@@ -136,33 +147,33 @@ def to_dict(self):
class BillParams(BasicParams):
-
- def __init__(self, amount, merchant_id, name=None, description=None, user=None):
- BasicParams.__init__(self, amount, merchant_id, name=name,
- user=user, description=description)
- self.resource_name = "bills"
+ def __init__(self, amount, merchant_id, name=None, description=None,
+ user=None):
+ BasicParams.__init__(self, amount, merchant_id, name=name,
+ user=user, description=description)
+ self.resource_name = "bills"
class SubscriptionParams(BasicParams):
def __init__(self, amount, merchant_id, interval_length, interval_unit,
- name=None, description=None,start_at=None, expires_at=None,
- interval_count=None, user=None):
- BasicParams.__init__(self, amount, merchant_id,
- user=user, description=description, name=name)
+ name=None, description=None, start_at=None, expires_at=None,
+ interval_count=None, user=None):
+ BasicParams.__init__(self, amount, merchant_id, user=user,
+ description=description, name=name)
self.resource_name = "subscriptions"
self.merchant_id = merchant_id
if not interval_length > 0:
raise ValueError("interval_length must be positive, value "
- "passed was {0}".format(interval_length))
+ "passed was {0}".format(interval_length))
self.interval_length = interval_length
valid_units = ["month", "day", "week"]
if interval_unit not in valid_units:
- raise ValueError("interval_unit must be one of {0},"
- "value passed was {1}".format(valid_units, interval_unit))
+ message = "interval_unit must be one of {0}, value passed was {1}"
+ raise ValueError(message.format(valid_units, interval_unit))
self.interval_unit = interval_unit
if expires_at:
@@ -172,29 +183,29 @@ def __init__(self, amount, merchant_id, interval_length, interval_unit,
if start_at:
self.check_date_in_future(start_at, "start_at")
self.start_at = start_at
-
+
if expires_at and start_at:
if (expires_at - start_at).total_seconds() < 0:
raise ValueError("start_at must be before expires_at")
if interval_count:
if interval_count < 0:
raise ValueError("interval_count must be positive "
- "value passed was {0}".format(interval_count))
+ "value passed was {0}".format(interval_count))
self.interval_count = interval_count
self.name = name if name else None
self.description = description if description else None
-
- self.attrnames.extend(["description", "interval_count",
- "interval_unit", "interval_length", "expires_at",
- "start_at"])
+
+ self.attrnames.extend([
+ "description", "interval_count", "interval_unit",
+ "interval_length", "expires_at", "start_at"
+ ])
def check_date_in_future(self, date, argname):
if (date - datetime.datetime.now()).total_seconds() < 0:
raise ValueError("{0} must be in the future, date passed was"
- "{1}".format(argname, date.isoformat()))
-
+ "{1}".format(argname, date.isoformat()))
def to_dict(self):
result = {}
@@ -207,5 +218,3 @@ def to_dict(self):
result[attrname] = val
return result
-
-
View
7 gocardless/utils.py
@@ -3,10 +3,12 @@
import hmac
import re
+
def percent_encode(string):
"""A version of urllibs' quote which correctly quotes '~'"""
return urllib.quote(string.encode('utf-8'), '~')
+
def to_query(obj, ns=None):
"""Create a query string from a list or dictionary"""
if isinstance(obj, dict):
@@ -20,6 +22,7 @@ def to_query(obj, ns=None):
else:
return [(percent_encode(unicode(ns)), percent_encode(unicode(obj)))]
+
def generate_signature(data, secret):
"""
signature takes a dict / tuple /string
@@ -28,17 +31,21 @@ def generate_signature(data, secret):
"""
return hmac.new(secret, to_query(data), hashlib.sha256).hexdigest()
+
def signature_valid(data, secret):
params = data.copy()
sig = params.pop("signature")
valid_sig = generate_signature(params, secret)
return sig == valid_sig
+
def camelize(to_uncamel):
result = []
for word in re.split("_", to_uncamel):
result.append(word[0].upper() + word[1:])
return "".join(result)
+
def singularize(to_sing):
return re.sub("s$", "", to_sing)
+
View
55 test/test_client.py
@@ -16,23 +16,26 @@
from gocardless import utils, urlbuilder, resources
from gocardless.exceptions import SignatureError, ClientError
from test_resources import create_mock_attrs
+
mock_account_details = {
- 'app_id': 'id01',
- 'app_secret': 'sec01',
- 'token': 'tok01',
- 'merchant_id': fixtures.merchant_json["id"],
- }
+ 'app_id': 'id01',
+ 'app_secret': 'sec01',
+ 'token': 'tok01',
+ 'merchant_id': fixtures.merchant_json["id"],
+}
+
+
def create_mock_client(details):
return Client(details["app_id"],
details["app_secret"],
access_token=details["token"],
merchant_id=details["merchant_id"])
+
def get_url_params(url):
param_dict = urlparse.parse_qs(urlparse.urlparse(url).query)
return dict([[k,v[0]] for k,v in param_dict.items()])
-
class ClientTestCase(unittest.TestCase):
@@ -95,7 +98,7 @@ def test_get_pre_authorization(self):
"expires_at":mock_date,
"next_interval_start":mock_date
}
- self._get_resource_tester("pre_authorization",
+ self._get_resource_tester("pre_authorization",
create_mock_attrs(mock_attrs))
def test_get_bill(self):
@@ -140,7 +143,7 @@ def test_create_bill(self):
mock_bill = resources.Bill(fixtures.bill_json.copy(), self.client)
mock_post.return_value = fixtures.bill_json
res = self.client.create_bill(10, "someid")
- mock_post.assert_called_with("/bills",
+ mock_post.assert_called_with("/bills",
{"bill":expected_params})
self.assertEqual(res, mock_bill)
@@ -170,7 +173,7 @@ def test_incorrect_signature_raises(self):
self.client.confirm_resource(self.params)
def test_resource_posts(self):
- self.params["signature"] = utils.generate_signature(self.params,
+ self.params["signature"] = utils.generate_signature(self.params,
mock_account_details["app_secret"])
with patch.object(self.client, 'api_post') as mock_post:
expected_data = {
@@ -181,7 +184,7 @@ def test_resource_posts(self):
mock_account_details["app_secret"])
self.client.confirm_resource(self.params)
expected_path = "/confirm"
- mock_post.assert_called_with(expected_path,
+ mock_post.assert_called_with(expected_path,
expected_data, auth=expected_auth)
@@ -228,7 +231,7 @@ def test_resource_name_is_singularized_in_url(self):
url = self.urlbuilder.build_and_sign(params)
urlparams = get_url_params(url)
self.assertTrue(urlparams.has_key("bill[amount]"))
-
+
def test_add_merchant_id_to_limit(self):
params = self.make_mock_params({"resource_name": "bill",
@@ -251,7 +254,7 @@ def test_url_contains_redirect(self):
def test_url_contains_cancel(self):
params = self.make_mock_params({})
- url = self.urlbuilder.build_and_sign(params,
+ url = self.urlbuilder.build_and_sign(params,
cancel_uri="http://cancel")
urlparams = get_url_params(url)
self.assertEqual(urlparams["cancel_uri"], "http://cancel")
@@ -333,7 +336,7 @@ def test_merchant_url_parameters(self):
"response_type":"code"
}
self.assertEqual(expected, params)
-
+
def test_merchant_url_with_merchant_prepop(self):
merchant = {
"name":"merchname",
@@ -352,7 +355,7 @@ def test_merchant_url_with_merchant_prepop(self):
params = get_url_params(url)
self.assertEqual(params["merchant[name]"], "merchname")
self.assertEqual(params["merchant[user][first_name]"], "nameone")
-
+
def test_merchant_url_state(self):
url = self.client.new_merchant_url("http://someurl", state="thestate")
params = get_url_params(url)
@@ -374,7 +377,7 @@ def test_fetch_client_access_token_basic_authorization(self):
mock_request.return_value = self.access_token_response
self.client.fetch_access_token(expected_data["redirect_uri"],
self.mock_auth_code)
- mock_request.assert_called_with("post", "/oauth/"
+ mock_request.assert_called_with("post", "/oauth/"
"access_token?{0}".format(query), auth=expected_auth)
def test_fetch_client_sets_access_token_and_merchant_id(self):
@@ -401,7 +404,7 @@ def __eq__(self, other):
class ClientUrlBuilderTestCase(unittest.TestCase):
"""Integration test for the Client <-> UrlBuilder relationship
- Tests that the url building methods on the client correctly
+ Tests that the url building methods on the client correctly
call methods on the urlbuilder class
"""
@@ -415,20 +418,20 @@ def urlbuilder_argument_check(self, method, expected_type, *args):
matcher = Matcher(lambda x: type(x) == expected_type)
mock_inst.build_and_sign.assert_called_with(matcher,
cancel_uri=None, redirect_uri=None, state=None)
-
+
def params_argument_check(self, method, params_class, *args, **kwargs):
with patch('gocardless.urlbuilder.UrlBuilder') as mock_builder:
with patch('gocardless.urlbuilder.{0}'.format(params_class.__name__)) as mock_class:
c = create_mock_client(mock_account_details)
getattr(c, method)(*args, **kwargs)
arg1 = args[0]
rest = args[1:]
- mock_class.assert_called_with(arg1,
+ mock_class.assert_called_with(arg1,
mock_account_details["merchant_id"], *rest,
**kwargs)
-
+
def test_new_preauth_calls_urlbuilder(self):
- self.urlbuilder_argument_check("new_preauthorization_url",
+ self.urlbuilder_argument_check("new_preauthorization_url",
urlbuilder.PreAuthorizationParams,
3, 7, "day")
@@ -438,7 +441,7 @@ def test_new_preauth_params_constructor(self):
3, 7, "day", expires_at=datetime.datetime.now(),
name="aname", description="desc", interval_count=5,
calendar_intervals=False, user={"somekey":"somval"})
-
+
def test_new_bill_calls_urlbuilder(self):
self.urlbuilder_argument_check("new_bill_url",
urlbuilder.BillParams,
@@ -457,16 +460,10 @@ def test_new_subscription_calls_urlbuilder(self):
def test_new_sub_params_constructor(self):
self.params_argument_check("new_subscription_url",
- urlbuilder.SubscriptionParams,
- 10, 23, "day", name="name", description="adesc",
+ urlbuilder.SubscriptionParams,
+ 10, 23, "day", name="name", description="adesc",
start_at=datetime.datetime.now(),
expires_at=datetime.datetime.now() + datetime.timedelta(100),
interval_count=20, user={"key":"val"})
-
-
-
-
-
-
View
43 test/test_resources.py
@@ -9,33 +9,38 @@
import gocardless
from gocardless.resources import Resource, Subscription, Bill, PreAuthorization
+
class TestResource(Resource):
endpoint = "/testendpoint/:id"
def __init__(self, attrs, client):
attrs = create_mock_attrs(attrs)
Resource.__init__(self, attrs, client)
+
class TestSubResource(Resource):
endpoint = "/subresource/:id"
+
class OtherTestSubResource(Resource):
endpoint = "/subresource2/:id"
+
def create_mock_attrs(to_merge):
"""
- Creats an attribute set for creating a resource from,
+ Creats an attribute set for creating a resource from,
includes the basic created, modified and id keys. Merges
that with to_merge
"""
attrs = {
- "created_at":"2012-04-18T17:53:12Z",
- "id":"1",
- "merchant_id":"amerchantid"
- }
+ "created_at": "2012-04-18T17:53:12Z",
+ "id": "1",
+ "merchant_id": "amerchantid"
+ }
attrs.update(to_merge)
return attrs
+
class ResourceTestCase(unittest.TestCase):
def test_endpoint_declared_by_class(self):
@@ -71,11 +76,11 @@ def test_resources_with_equal_attrs_are_equal(self):
class ResourceSubresourceTestCase(unittest.TestCase):
def setUp(self):
- self.resource = TestResource({"sub_resource_uris":
+ self.resource = TestResource({"sub_resource_uris":
{"test_sub_resources":
"https://gocardless.com/api/v1/merchants/WOQRUJU9OH2HH1/bills?\
source_id=1580",
- "other_test_sub_resources": "aurl"},
+ "other_test_sub_resources": "aurl"},
"id":"1"},
None)
@@ -105,7 +110,7 @@ def test_resource_is_correct_instance(self):
self.resource.client = mock_client
result = self.resource.test_sub_resources()
self.assertIsInstance(result[0], TestSubResource)
-
+
class FindResourceTestCase(unittest.TestCase):
@@ -139,9 +144,9 @@ def test_date_fields_are_converted(self):
mod_date = datetime.datetime.strptime("2020-10-10T01:01:00", "%Y-%m-%dT%H:%M:%S")
act_date = datetime.datetime.strptime("2020-10-10T01:01:03", "%Y-%m-%dT%H:%M:%S")
params = {
- "modified":mod_date.isoformat() + "Z",
- "activated":act_date.isoformat() + "Z"
- }
+ "modified":mod_date.isoformat() + "Z",
+ "activated":act_date.isoformat() + "Z"
+ }
res = TestDateResource(create_mock_attrs(params), None)
self.assertEqual(res.modified, mod_date)
self.assertEqual(res.activated, act_date)
@@ -153,17 +158,17 @@ class TestReferenceResource(Resource):
date_fields = []
class ReferenceResourceTestCase(unittest.TestCase):
-
+
def test_reference_fields_are_converted(self):
params = create_mock_attrs({"test_resource_id":"2345"})
res = TestReferenceResource(params, None)
self.assertTrue(hasattr(res, "test_resource"))
self.assertTrue(callable, res.test_resource)
-
+
def test_reference_function_calls_resource(self):
params = create_mock_attrs({"test_resource_id":"2345"})
res = TestReferenceResource(params, None)
- with patch.object(TestResource,
+ with patch.object(TestResource,
'find_with_client') as mock_res:
mock_res.return_value = "1234"
self.assertEqual("1234", res.test_resource())
@@ -176,7 +181,7 @@ def test_date_fields_inherited(self):
def test_date_with_null_attr_does_not_throw(self):
params = create_mock_attrs({"modified_at":None})
- testclass = type("TestModResource", (Resource,),
+ testclass = type("TestModResource", (Resource,),
{"date_fields":["modified_at"]})
res = testclass(params, None)
@@ -191,10 +196,8 @@ def test_cancel_puts(self):
fixtures.subscription_json["id"]))
-
-
class PreAuthBillCreationTestCase(unittest.TestCase):
-
+
def test_create_bill_calls_client_api_post(self):
client = mock.Mock()
client.api_post.return_value = fixtures.bill_json
@@ -220,7 +223,3 @@ def test_preauth_create_calls_bill_create(self, mock_bill_class):
description="adesc")
-
-
-
-

0 comments on commit 3c12186

Please sign in to comment.
Something went wrong with that request. Please try again.