summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatryk Zawadzki <patrys@room-303.com>2013-11-06 15:23:30 +0100
committerPatryk Zawadzki <patrys@room-303.com>2013-11-06 15:23:30 +0100
commitb7cf5500116329c48076efb3651a0f636d352c40 (patch)
treeb650b1df6b57f9b24f8e8f75e0de53a7155604a7
parent540c988db786d5b11eb2540ee190dea747042774 (diff)
downloaddjango-payments-taler-b7cf5500116329c48076efb3651a0f636d352c40.tar.gz
django-payments-taler-b7cf5500116329c48076efb3651a0f636d352c40.tar.bz2
django-payments-taler-b7cf5500116329c48076efb3651a0f636d352c40.zip
Make tests more robust
Make sure PayPal serializes properly, allow Travis CI to run the tests.
-rw-r--r--doc/modules.rst2
-rw-r--r--payments/dotpay/__init__.py4
-rw-r--r--payments/dotpay/forms.py3
-rw-r--r--payments/dotpay/tests.py4
-rw-r--r--payments/dummy/__init__.py8
-rw-r--r--payments/paypal-card/__init__.py37
-rw-r--r--payments/paypal/__init__.py17
-rw-r--r--payments/paypal/tests.py43
-rw-r--r--payments/tests.py5
-rw-r--r--payments/wallet/__init__.py10
-rw-r--r--payments/wallet/forms.py7
-rw-r--r--payments/wallet/tests.py89
-rwxr-xr-x[-rw-r--r--]setup.py8
-rw-r--r--test_settings.py2
14 files changed, 123 insertions, 116 deletions
diff --git a/doc/modules.rst b/doc/modules.rst
index 1328601..1b9500a 100644
--- a/doc/modules.rst
+++ b/doc/modules.rst
@@ -98,7 +98,7 @@ To specify the `postback URL` at the Merchant Settings page use direct url to `p
E.g: ``https://example.com/payments/process/wallet``
-Paypal
+PayPal
------
.. class:: payments.paypal.PaypalProvider(client_id, secret[, endpoint='https://api.paypal.com'])
diff --git a/payments/dotpay/__init__.py b/payments/dotpay/__init__.py
index 2b42132..16337aa 100644
--- a/payments/dotpay/__init__.py
+++ b/payments/dotpay/__init__.py
@@ -1,9 +1,7 @@
from django.http import HttpResponse, HttpResponseForbidden
from .forms import ProcessPaymentForm
-from .. import BasicProvider, get_payment_model
-
-Payment = get_payment_model()
+from .. import BasicProvider
class DotpayProvider(BasicProvider):
diff --git a/payments/dotpay/forms.py b/payments/dotpay/forms.py
index cfe24e4..54dfa45 100644
--- a/payments/dotpay/forms.py
+++ b/payments/dotpay/forms.py
@@ -2,9 +2,6 @@ import hashlib
from django import forms
-from .. import get_payment_model
-
-Payment = get_payment_model()
NO_MORE_CONFIRMATION = 0
NEW = 1
diff --git a/payments/dotpay/tests.py b/payments/dotpay/tests.py
index 7b5aecb..4f6443c 100644
--- a/payments/dotpay/tests.py
+++ b/payments/dotpay/tests.py
@@ -1,8 +1,8 @@
-from mock import MagicMock
import hashlib
+from unittest import TestCase
from django.http import HttpResponse, HttpResponseForbidden
-from django.test import TestCase
+from mock import MagicMock
from .forms import ACCEPTED
from . import DotpayProvider
diff --git a/payments/dummy/__init__.py b/payments/dummy/__init__.py
index 04550b3..505b4f6 100644
--- a/payments/dummy/__init__.py
+++ b/payments/dummy/__init__.py
@@ -7,16 +7,8 @@ from .. import BasicProvider, RedirectNeeded
class DummyProvider(BasicProvider):
'''
Dummy payment provider
-
- url:
- return URL, user will be bounced to this address after payment is
- processed
'''
- def __init__(self, *args, **kwargs):
- self._url = kwargs.pop('url')
- super(DummyProvider, self).__init__(*args, **kwargs)
-
def get_form(self, data=None):
form = DummyForm(data=data, hidden_inputs=False, provider=self,
payment=self.payment)
diff --git a/payments/paypal-card/__init__.py b/payments/paypal-card/__init__.py
deleted file mode 100644
index a780f5c..0000000
--- a/payments/paypal-card/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from django.http import HttpResponseForbidden
-
-from ..paypal import PaypalProvider
-from ..forms import PaymentForm
-from .. import get_payment_model, RedirectNeeded
-
-Payment = get_payment_model()
-
-
-class PaypalCardProvider(PaypalProvider):
- '''
- paypal.com credit card payment provider
- '''
- def get_form(self, data=None):
- if self.payment.status == 'waiting':
- self.payment.change_status('input')
- form = PaymentForm(data, provider=self, payment=self.payment)
- if form.is_valid():
- raise RedirectNeeded(self.payment.get_success_url())
- return form
-
- def get_product_data(self, extra_data):
- data = self.get_transactions_data()
- year = extra_data['expiration'].year
- month = extra_data['expiration'].month
- credit_card = {'number': extra_data['number'],
- 'type': extra_data['type'],
- 'expire_month': month,
- 'expire_year': year}
- if 'cvv2' in extra_data and extra_data['cvv2']:
- credit_card['cvv2'] = extra_data['cvv2']
- data['payer'] = {'payment_method': 'credit_card',
- 'funding_instruments': [{'credit_card': credit_card}]}
- return data
-
- def process_data(self, request):
- return HttpResponseForbidden('FAILED')
diff --git a/payments/paypal/__init__.py b/payments/paypal/__init__.py
index 2c51471..27d2afb 100644
--- a/payments/paypal/__init__.py
+++ b/payments/paypal/__init__.py
@@ -8,9 +8,7 @@ from django.shortcuts import redirect
from django.utils import simplejson, timezone
from .forms import PaymentForm
-from .. import BasicProvider, RedirectNeeded, get_payment_model
-
-Payment = get_payment_model()
+from .. import BasicProvider, RedirectNeeded
class UnauthorizedRequest(Exception):
@@ -83,15 +81,16 @@ class PaypalProvider(BasicProvider):
def get_transactions_data(self):
items = list(self.payment.get_purchased_items())
sub_total = self.payment.total - self.payment.delivery
- data = {'intent': 'sale',
- 'transactions': [{
+ data = {
+ 'intent': 'sale',
+ 'transactions': [{
'amount': {
- 'total': self.payment.total,
+ 'total': str(self.payment.total),
'currency': self.payment.currency,
'details': {
- 'subtotal': sub_total,
- 'tax': self.payment.tax,
- 'shipping': self.payment.delivery}},
+ 'subtotal': str(sub_total),
+ 'tax': str(self.payment.tax),
+ 'shipping': str(self.payment.delivery)}},
'item_list': {'items': items},
'description': self.payment.description}]}
return data
diff --git a/payments/paypal/tests.py b/payments/paypal/tests.py
new file mode 100644
index 0000000..c6f4e0d
--- /dev/null
+++ b/payments/paypal/tests.py
@@ -0,0 +1,43 @@
+from decimal import Decimal
+from unittest import TestCase
+
+from django.utils import simplejson
+from mock import MagicMock
+
+from . import PaypalProvider
+
+
+CLIENT_ID = 'abc123'
+PAYMENT_TOKEN = '5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6'
+SECRET = '123abc'
+VARIANT = 'wallet'
+
+
+class Payment(MagicMock):
+
+ id = 1
+ description = 'payment'
+ currency = 'USD'
+ delivery = Decimal(10)
+ status = 'waiting'
+ tax = Decimal(10)
+ token = PAYMENT_TOKEN
+ total = Decimal(100)
+ variant = VARIANT
+
+ def change_status(self, status):
+ self.status = status
+
+ def get_failure_url(self):
+ return 'http://cancel.com'
+
+ def get_success_url(self):
+ return 'http://success.com'
+
+
+class TestPaypalProvider(TestCase):
+
+ def test_payload_serializable(self):
+ payment = Payment()
+ provider = PaypalProvider(payment, secret=SECRET, client_id=CLIENT_ID)
+ simplejson.dumps(provider.get_product_data())
diff --git a/payments/tests.py b/payments/tests.py
index 41be8e4..79ca32f 100644
--- a/payments/tests.py
+++ b/payments/tests.py
@@ -1,4 +1,7 @@
from .dotpay.tests import TestDotpayProvider
+from .paypal.tests import TestPaypalProvider
from .wallet.tests import TestGoogleWalletProvider
-__all__ = ['TestDotpayProvider', 'TestGoogleWalletProvider']
+
+__all__ = ['TestDotpayProvider', 'TestGoogleWalletProvider',
+ 'TestPaypalProvider']
diff --git a/payments/wallet/__init__.py b/payments/wallet/__init__.py
index a401e8a..93d412f 100644
--- a/payments/wallet/__init__.py
+++ b/payments/wallet/__init__.py
@@ -5,9 +5,7 @@ from django.http import HttpResponseForbidden, HttpResponse
import jwt
from .forms import PaymentForm, ProcessPaymentForm
-from .. import get_payment_model, BasicProvider
-
-Payment = get_payment_model()
+from .. import BasicProvider
class GoogleWalletProvider(BasicProvider):
@@ -32,9 +30,9 @@ class GoogleWalletProvider(BasicProvider):
'iat': current_time,
'exp': exp_time,
'request': {
- "currencyCode": self.payment.currency,
- "price": str(self.payment.total),
- 'name': self.payment.description or "Total payment",
+ 'currencyCode': self.payment.currency,
+ 'price': str(self.payment.total),
+ 'name': self.payment.description or 'Total payment',
'sellerData': self.payment.token}}
return jwt.encode(jwt_info, self.seller_secret)
diff --git a/payments/wallet/forms.py b/payments/wallet/forms.py
index c6f5904..9d11487 100644
--- a/payments/wallet/forms.py
+++ b/payments/wallet/forms.py
@@ -23,10 +23,9 @@ class ProcessPaymentForm(forms.Form):
self.payment = payment
def clean_jwt(self):
- cleaned_jwt = super(ProcessPaymentForm, self).clean().get('jwt')
-
+ payload = super(ProcessPaymentForm, self).clean().get('jwt')
try:
- jwt_data = jwt.decode(str(cleaned_jwt),
+ jwt_data = jwt.decode(payload.encode('utf-8'),
self.provider.seller_secret)
except jwt.DecodeError:
raise forms.ValidationError('Incorrect response')
@@ -41,7 +40,7 @@ class ProcessPaymentForm(forms.Form):
raise forms.ValidationError('Incorrect payment token')
self.order_id = jwt_data['response']['orderId']
- return cleaned_jwt
+ return payload
def save(self):
self.payment.transaction_id = self.order_id
diff --git a/payments/wallet/tests.py b/payments/wallet/tests.py
index 42c0af0..51af2ee 100644
--- a/payments/wallet/tests.py
+++ b/payments/wallet/tests.py
@@ -1,44 +1,42 @@
-from mock import MagicMock
+from decimal import Decimal
+from unittest import TestCase
from django.http import HttpResponse, HttpResponseForbidden
-from django.test import TestCase
import jwt
+from mock import MagicMock
from . import GoogleWalletProvider
-VARIANT = 'wallet'
-
-PAYMENT_TOKEN = "5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6"
-
+PAYMENT_TOKEN = '5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6'
SELLER_ID = 'abc123'
SELLER_SECRET = '123abc'
+VARIANT = 'wallet'
+
JWT_DATA = {
- "iss": "Google",
- "aud": SELLER_ID,
- "typ": "google/payments/inapp/item/v1/postback/buy",
- "iat": "1309988959",
- "exp": "1409988959",
- "request": {
- "name": "Test Order #12",
- "price": "22.50",
- "currencyCode": "USD",
- "sellerData": PAYMENT_TOKEN
- },
- "response": {
- "orderId": "1234567890"
- }
-}
+ 'iss': 'Google',
+ 'aud': SELLER_ID,
+ 'typ': 'google/payments/inapp/item/v1/postback/buy',
+ 'iat': '1309988959',
+ 'exp': '1409988959',
+ 'request': {
+ 'name': 'Test Order #12',
+ 'price': '22.50',
+ 'currencyCode': 'USD',
+ 'sellerData': PAYMENT_TOKEN},
+ 'response': {
+ 'orderId': '1234567890'}}
class Payment(MagicMock):
id = 1
- variant = VARIANT
currency = 'USD'
- total = 100
- token = PAYMENT_TOKEN
+ description = 'payment'
status = 'waiting'
+ token = PAYMENT_TOKEN
+ total = Decimal(100)
+ variant = VARIANT
def change_status(self, status):
self.status = status
@@ -52,42 +50,53 @@ class Payment(MagicMock):
class TestGoogleWalletProvider(TestCase):
- def setUp(self):
- self.payment = Payment()
- self.request = MagicMock()
- self.request.POST = {'jwt': jwt.encode(JWT_DATA, SELLER_SECRET)}
-
def test_process_data(self):
"""
GoogleWalletProvider.process_data() returns a correct HTTP response
"""
- provider = GoogleWalletProvider(self.payment, seller_id=SELLER_ID,
+ payment = Payment()
+ request = MagicMock()
+ request.POST = {'jwt': jwt.encode(JWT_DATA, SELLER_SECRET)}
+ provider = GoogleWalletProvider(payment, seller_id=SELLER_ID,
seller_secret=SELLER_SECRET)
- response = provider.process_data(self.request)
+ response = provider.process_data(request)
self.assertEqual(type(response), HttpResponse)
- self.assertEqual(self.payment.status, 'confirmed')
+ self.assertEqual(payment.status, 'confirmed')
def test_incorrect_process_data(self):
"""
GoogleWalletProvider.process_data() checks POST data
"""
- data = JWT_DATA
- data['aud'] = 'wrong seller id'
- self.request.POST = {'jwt': jwt.encode(data, SELLER_SECRET)}
- provider = GoogleWalletProvider(self.payment, seller_id=SELLER_ID,
+ data = dict(JWT_DATA, aud='wrong seller id')
+ payment = Payment()
+ request = MagicMock()
+ payload = jwt.encode(data, SELLER_SECRET)
+ request.POST = {'jwt': payload}
+ provider = GoogleWalletProvider(payment, seller_id=SELLER_ID,
seller_secret=SELLER_SECRET)
- response = provider.process_data(self.request)
+ response = provider.process_data(request)
self.assertEqual(type(response), HttpResponseForbidden)
def test_provider_request_payment_token(self):
+ request = MagicMock()
+ request.POST = {'jwt': jwt.encode(JWT_DATA, SELLER_SECRET)}
provider = GoogleWalletProvider(payment=None, seller_id=SELLER_ID,
seller_secret=SELLER_SECRET)
- token = provider.get_token_from_request(self.request)
+ token = provider.get_token_from_request(request)
self.assertEqual(token, PAYMENT_TOKEN)
def test_provider_invalid_request(self):
- self.request.POST = {'jwt': 'wrong jwt data'}
+ request = MagicMock()
+ request.POST = {'jwt': 'wrong jwt data'}
provider = GoogleWalletProvider(payment=None, seller_id=SELLER_ID,
seller_secret=SELLER_SECRET)
- token = provider.get_token_from_request(self.request)
+ token = provider.get_token_from_request(request)
self.assertFalse(token)
+
+ def test_jwt_encoder(self):
+ payment = Payment()
+ provider = GoogleWalletProvider(payment, seller_id=SELLER_ID,
+ seller_secret=SELLER_SECRET)
+ payload = provider.get_jwt_data()
+ data = jwt.decode(payload, SELLER_SECRET)
+ self.assertEqual(data['request']['price'], '100')
diff --git a/setup.py b/setup.py
index f4573cc..e2ccd07 100644..100755
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,15 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
+import os
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_settings')
setup(
name='django-payments',
author='Mirumee Software',
author_email='hello@mirumee.com',
description='Universal payment handling for Django',
- version='0.3.4.4',
+ version='0.3.5',
url='http://github.com/mirumee/django-payments',
packages=find_packages(),
classifiers=[
@@ -22,6 +25,7 @@ setup(
'Framework :: Django',
'Topic :: Software Development :: Libraries :: Application Frameworks',
'Topic :: Software Development :: Libraries :: Python Modules'],
- install_requires=['requests>=1.2.0', 'pycrypto', 'PyJWT'],
+ install_requires=['Django>=1.5', 'requests>=1.2.0', 'pycrypto', 'PyJWT'],
include_package_data=True,
+ test_suite='payments.tests',
zip_safe=False)
diff --git a/test_settings.py b/test_settings.py
new file mode 100644
index 0000000..362a3c0
--- /dev/null
+++ b/test_settings.py
@@ -0,0 +1,2 @@
+SECRET_KEY = 'NOTREALLY'
+PAYMENT_BASE_URL = 'http://example.com/'