diff options
author | Adam Bogdał <adam@bogdal.pl> | 2015-10-21 21:50:12 +0200 |
---|---|---|
committer | Adam Bogdał <adam@bogdal.pl> | 2015-10-21 21:50:12 +0200 |
commit | 2afa08e1f7142c8c5c3c09806e75a6cf9513ab82 (patch) | |
tree | c6b7ac89f86109d931a88e40510e293822f63c0e | |
parent | 62256b3ac37d74b120e9f3b7a8a7006b6447350a (diff) | |
download | django-payments-taler-2afa08e1f7142c8c5c3c09806e75a6cf9513ab82.tar.gz django-payments-taler-2afa08e1f7142c8c5c3c09806e75a6cf9513ab82.tar.bz2 django-payments-taler-2afa08e1f7142c8c5c3c09806e75a6cf9513ab82.zip |
Make the package compatible with various django versions
31 files changed, 229 insertions, 193 deletions
diff --git a/.travis.yml b/.travis.yml index 4e308b9..e8d72b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,31 @@ language: python -python: - - 2.7 - - 3.3 - - 3.4 +sudo: false install: - - python setup.py install - - pip install coverage - - pip install codecov + - pip install tox codecov script: - - coverage run setup.py test + - tox +env: + - TOXENV=py27-django14 + - TOXENV=py27-django18 + - TOXENV=py27-django19 + - TOXENV=py27-django_master + - TOXENV=py34-django14 + - TOXENV=py34-django18 + - TOXENV=py34-django19 + - TOXENV=py34-django_master + - TOXENV=py35-django18 + - TOXENV=py35-django19 + - TOXENV=py35-django_master +matrix: + allow_failures: + - env: TOXENV=py27-django_master + - env: TOXENV=py34-django_master + - env: TOXENV=py35-django_master after_success: - codecov +addons: + apt: + sources: + - deadsnakes + packages: + - python3.5
\ No newline at end of file diff --git a/payments/__init__.py b/payments/__init__.py index 9cd55b1..2aeae27 100644 --- a/payments/__init__.py +++ b/payments/__init__.py @@ -1,41 +1,9 @@ -from __future__ import unicode_literals from collections import namedtuple -import re -try: - from urllib.parse import urljoin, urlencode -except ImportError: - from urllib import urlencode - from urlparse import urljoin - -from django.conf import settings -from django.contrib.sites.models import Site -from django.core.exceptions import ImproperlyConfigured -from django.db.models import get_model - -PAYMENT_VARIANTS = { - 'default': ('payments.dummy.DummyProvider', {})} - -PAYMENT_HOST = getattr(settings, 'PAYMENT_HOST', None) -PAYMENT_USES_SSL = getattr(settings, 'PAYMENT_USES_SSL', False) - -if not PAYMENT_HOST: - if not 'django.contrib.sites' in settings.INSTALLED_APPS: - raise ImproperlyConfigured('The PAYMENT_HOST setting without ' - 'the sites app must not be empty.') PurchasedItem = namedtuple('PurchasedItem', 'name, quantity, price, currency, sku') -def get_base_url(): - protocol = 'https' if PAYMENT_USES_SSL else 'http' - if not PAYMENT_HOST: - current_site = Site.objects.get_current() - domain = current_site.domain - return '%s://%s' % (protocol, domain) - return '%s://%s' % (protocol, PAYMENT_HOST) - - class RedirectNeeded(Exception): pass @@ -46,120 +14,3 @@ class PaymentError(Exception): class ExternalPostNeeded(Exception): pass - - -class BasicProvider(object): - ''' - This class defines the provider API. It should not be instantiated - directly. Use factory instead. - ''' - _method = 'post' - - def get_action(self, payment): - return self.get_return_url(payment) - - def __init__(self, capture=True): - self._capture = capture - - def get_hidden_fields(self, payment): - ''' - Converts a payment into a dict containing transaction data. Use - get_form instead to get a form suitable for templates. - - When implementing a new payment provider, overload this method to - transfer provider-specific data. - ''' - raise NotImplementedError() - - def get_form(self, payment, data=None): - ''' - Converts *payment* into a form suitable for Django templates. - ''' - from .forms import PaymentForm - return PaymentForm(self.get_hidden_fields(payment), - self.get_action(payment), self._method) - - def process_data(self, payment, request): - ''' - Process callback request from a payment provider. - ''' - raise NotImplementedError() - - def get_token_from_request(self, payment, request): - ''' - Return payment token from provider request. - ''' - raise NotImplementedError() - - def get_return_url(self, payment, extra_data=None): - payment_link = payment.get_process_url() - url = urljoin(get_base_url(), payment_link) - if extra_data: - qs = urlencode(extra_data) - return url + '?' + qs - return url - - def capture(self, payment, amount=None): - raise NotImplementedError() - - def release(self, payment): - raise NotImplementedError() - - def refund(self, payment, amount=None): - raise NotImplementedError() - - -PROVIDER_CACHE = {} - - -def provider_factory(variant): - ''' - Return the provider instance based on variant - ''' - variants = getattr(settings, 'PAYMENT_VARIANTS', PAYMENT_VARIANTS) - handler, config = variants.get(variant, (None, None)) - if not handler: - raise ValueError('Payment variant does not exist: %s' % - (variant,)) - if variant not in PROVIDER_CACHE: - module_path, class_name = handler.rsplit('.', 1) - module = __import__( - str(module_path), globals(), locals(), [str(class_name)]) - class_ = getattr(module, class_name) - PROVIDER_CACHE[variant] = class_(**config) - return PROVIDER_CACHE[variant] - - -def get_payment_model(): - ''' - Return the Payment model that is active in this project - ''' - try: - app_label, model_name = settings.PAYMENT_MODEL.split('.') - except (ValueError, AttributeError): - raise ImproperlyConfigured('PAYMENT_MODEL must be of the form ' - '"app_label.model_name"') - payment_model = get_model(app_label, model_name) - if payment_model is None: - msg = ( - 'PAYMENT_MODEL refers to model "%s" that has not been installed' % - settings.PAYMENT_MODEL) - raise ImproperlyConfigured(msg) - return payment_model - - -CARD_TYPES = [ - (r'^4[0-9]{12}(?:[0-9]{3})?$', 'visa', 'VISA'), - (r'^5[1-5][0-9]{14}$', 'mastercard', 'MasterCard'), - (r'^6(?:011|5[0-9]{2})[0-9]{12}$', 'discover', 'Discover'), - (r'^3[47][0-9]{13}$', 'amex', 'American Express'), - (r'^(?:(?:2131|1800|35\d{3})\d{11})$', 'jcb', 'JCB'), - (r'^(?:3(?:0[0-5]|[68][0-9])[0-9]{11})$', 'diners', 'Diners Club'), - (r'^(?:5[0678]\d\d|6304|6390|67\d\d)\d{8,15}$', 'maestro', 'Maestro')] - - -def get_credit_card_issuer(number): - for regexp, card_type, name in CARD_TYPES: - if re.match(regexp, number): - return card_type, name - return None, None diff --git a/payments/authorizenet/__init__.py b/payments/authorizenet/__init__.py index 6a92a14..c910157 100644 --- a/payments/authorizenet/__init__.py +++ b/payments/authorizenet/__init__.py @@ -5,7 +5,8 @@ from django.http import HttpResponseForbidden import requests from .forms import PaymentForm -from .. import BasicProvider, RedirectNeeded +from .. import RedirectNeeded +from ..core import BasicProvider class AuthorizeNetProvider(BasicProvider): diff --git a/payments/braintree/__init__.py b/payments/braintree/__init__.py index 8552330..4d95cb2 100644 --- a/payments/braintree/__init__.py +++ b/payments/braintree/__init__.py @@ -4,7 +4,8 @@ import braintree from django.core.exceptions import ImproperlyConfigured from .forms import BraintreePaymentForm -from .. import BasicProvider, RedirectNeeded +from .. import RedirectNeeded +from ..core import BasicProvider class BraintreeProvider(BasicProvider): diff --git a/payments/coinbase/__init__.py b/payments/coinbase/__init__.py index 5348132..fea8b0a 100644 --- a/payments/coinbase/__init__.py +++ b/payments/coinbase/__init__.py @@ -10,7 +10,7 @@ from django.core.exceptions import ImproperlyConfigured from django.http import HttpResponse, HttpResponseForbidden import requests -from .. import BasicProvider +from ..core import BasicProvider class CoinbaseProvider(BasicProvider): diff --git a/payments/coinbase/test_coinbase.py b/payments/coinbase/test_coinbase.py index e329581..40dcb30 100644 --- a/payments/coinbase/test_coinbase.py +++ b/payments/coinbase/test_coinbase.py @@ -9,7 +9,6 @@ from django.http import HttpResponse, HttpResponseForbidden from mock import MagicMock, patch from . import CoinbaseProvider -from payments import RedirectNeeded PAYMENT_TOKEN = '5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6' KEY = 'abc123' diff --git a/payments/core.py b/payments/core.py new file mode 100644 index 0000000..649fbae --- /dev/null +++ b/payments/core.py @@ -0,0 +1,152 @@ +from __future__ import unicode_literals +import re +try: + from urllib.parse import urljoin, urlencode +except ImportError: + from urllib import urlencode + from urlparse import urljoin +try: + from django.db.models import get_model +except ImportError: + from django.apps import apps + get_model = apps.get_model +from django.conf import settings +from django.contrib.sites.models import Site +from django.core.exceptions import ImproperlyConfigured + +PAYMENT_VARIANTS = { + 'default': ('payments.dummy.DummyProvider', {})} + +PAYMENT_HOST = getattr(settings, 'PAYMENT_HOST', None) +PAYMENT_USES_SSL = getattr(settings, 'PAYMENT_USES_SSL', False) + +if not PAYMENT_HOST: + if not 'django.contrib.sites' in settings.INSTALLED_APPS: + raise ImproperlyConfigured('The PAYMENT_HOST setting without ' + 'the sites app must not be empty.') + + +def get_base_url(): + protocol = 'https' if PAYMENT_USES_SSL else 'http' + if not PAYMENT_HOST: + current_site = Site.objects.get_current() + domain = current_site.domain + return '%s://%s' % (protocol, domain) + return '%s://%s' % (protocol, PAYMENT_HOST) + + +class BasicProvider(object): + ''' + This class defines the provider API. It should not be instantiated + directly. Use factory instead. + ''' + _method = 'post' + + def get_action(self, payment): + return self.get_return_url(payment) + + def __init__(self, capture=True): + self._capture = capture + + def get_hidden_fields(self, payment): + ''' + Converts a payment into a dict containing transaction data. Use + get_form instead to get a form suitable for templates. + + When implementing a new payment provider, overload this method to + transfer provider-specific data. + ''' + raise NotImplementedError() + + def get_form(self, payment, data=None): + ''' + Converts *payment* into a form suitable for Django templates. + ''' + from .forms import PaymentForm + return PaymentForm(self.get_hidden_fields(payment), + self.get_action(payment), self._method) + + def process_data(self, payment, request): + ''' + Process callback request from a payment provider. + ''' + raise NotImplementedError() + + def get_token_from_request(self, payment, request): + ''' + Return payment token from provider request. + ''' + raise NotImplementedError() + + def get_return_url(self, payment, extra_data=None): + payment_link = payment.get_process_url() + url = urljoin(get_base_url(), payment_link) + if extra_data: + qs = urlencode(extra_data) + return url + '?' + qs + return url + + def capture(self, payment, amount=None): + raise NotImplementedError() + + def release(self, payment): + raise NotImplementedError() + + def refund(self, payment, amount=None): + raise NotImplementedError() + + +PROVIDER_CACHE = {} + + +def provider_factory(variant): + ''' + Return the provider instance based on variant + ''' + variants = getattr(settings, 'PAYMENT_VARIANTS', PAYMENT_VARIANTS) + handler, config = variants.get(variant, (None, None)) + if not handler: + raise ValueError('Payment variant does not exist: %s' % + (variant,)) + if variant not in PROVIDER_CACHE: + module_path, class_name = handler.rsplit('.', 1) + module = __import__( + str(module_path), globals(), locals(), [str(class_name)]) + class_ = getattr(module, class_name) + PROVIDER_CACHE[variant] = class_(**config) + return PROVIDER_CACHE[variant] + + +def get_payment_model(): + ''' + Return the Payment model that is active in this project + ''' + try: + app_label, model_name = settings.PAYMENT_MODEL.split('.') + except (ValueError, AttributeError): + raise ImproperlyConfigured('PAYMENT_MODEL must be of the form ' + '"app_label.model_name"') + payment_model = get_model(app_label, model_name) + if payment_model is None: + msg = ( + 'PAYMENT_MODEL refers to model "%s" that has not been installed' % + settings.PAYMENT_MODEL) + raise ImproperlyConfigured(msg) + return payment_model + + +CARD_TYPES = [ + (r'^4[0-9]{12}(?:[0-9]{3})?$', 'visa', 'VISA'), + (r'^5[1-5][0-9]{14}$', 'mastercard', 'MasterCard'), + (r'^6(?:011|5[0-9]{2})[0-9]{12}$', 'discover', 'Discover'), + (r'^3[47][0-9]{13}$', 'amex', 'American Express'), + (r'^(?:(?:2131|1800|35\d{3})\d{11})$', 'jcb', 'JCB'), + (r'^(?:3(?:0[0-5]|[68][0-9])[0-9]{11})$', 'diners', 'Diners Club'), + (r'^(?:5[0678]\d\d|6304|6390|67\d\d)\d{8,15}$', 'maestro', 'Maestro')] + + +def get_credit_card_issuer(number): + for regexp, card_type, name in CARD_TYPES: + if re.match(regexp, number): + return card_type, name + return None, None diff --git a/payments/cybersource/__init__.py b/payments/cybersource/__init__.py index a0ddf96..cad98a7 100644 --- a/payments/cybersource/__init__.py +++ b/payments/cybersource/__init__.py @@ -11,9 +11,8 @@ from suds.sudsobject import Object import suds.wsse from .forms import PaymentForm -from .. import ( - BasicProvider, ExternalPostNeeded, get_credit_card_issuer, PaymentError, - RedirectNeeded) +from .. import ExternalPostNeeded, PaymentError, RedirectNeeded +from ..core import BasicProvider, get_credit_card_issuer from ..forms import PaymentForm as BaseForm diff --git a/payments/cybersource/test_cybersource.py b/payments/cybersource/test_cybersource.py index 1d8529f..ac16689 100644 --- a/payments/cybersource/test_cybersource.py +++ b/payments/cybersource/test_cybersource.py @@ -6,7 +6,7 @@ from mock import patch, MagicMock, Mock from . import CyberSourceProvider, AUTHENTICATE_REQUIRED, ACCEPTED, \ TRANSACTION_SETTLED -from payments import RedirectNeeded, ExternalPostNeeded, PurchasedItem +from .. import RedirectNeeded, PurchasedItem MERCHANT_ID = 'abcd1234' PASSWORD = '1234abdd1234abcd' diff --git a/payments/dotpay/__init__.py b/payments/dotpay/__init__.py index fc3fd6d..6057db4 100644 --- a/payments/dotpay/__init__.py +++ b/payments/dotpay/__init__.py @@ -4,7 +4,7 @@ from django.core.exceptions import ImproperlyConfigured from django.http import HttpResponse, HttpResponseForbidden from .forms import ProcessPaymentForm -from .. import BasicProvider +from ..core import BasicProvider CENTS = Decimal('0.01') diff --git a/payments/dummy/__init__.py b/payments/dummy/__init__.py index 99bab76..7774b27 100644 --- a/payments/dummy/__init__.py +++ b/payments/dummy/__init__.py @@ -10,7 +10,8 @@ except ImportError: from django.http import HttpResponseRedirect from .forms import DummyForm -from .. import BasicProvider, RedirectNeeded, PaymentError +from .. import RedirectNeeded, PaymentError +from ..core import BasicProvider class DummyProvider(BasicProvider): diff --git a/payments/dummy/test_dummy.py b/payments/dummy/test_dummy.py index d2bcbe8..a2733d0 100644 --- a/payments/dummy/test_dummy.py +++ b/payments/dummy/test_dummy.py @@ -10,10 +10,8 @@ try: except ImportError: from mock import MagicMock -from payments import RedirectNeeded, PaymentError - from . import DummyProvider - +from .. import RedirectNeeded, PaymentError VARIANT = 'dummy-3ds' diff --git a/payments/fields.py b/payments/fields.py index 9b5954e..55eb7b3 100644 --- a/payments/fields.py +++ b/payments/fields.py @@ -7,7 +7,7 @@ from django import forms from django.core import validators from django.utils.translation import ugettext_lazy as _ -from . import get_credit_card_issuer +from .core import get_credit_card_issuer from .widgets import CreditCardExpiryWidget, CreditCardNumberWidget diff --git a/payments/models.py b/payments/models.py index a20ea36..4d9e95a 100644 --- a/payments/models.py +++ b/payments/models.py @@ -7,7 +7,7 @@ from django.core.urlresolvers import reverse from django.db import models from django.utils.translation import ugettext_lazy as _ -from . import provider_factory +from .core import provider_factory DEFAULT_PAYMENT_STATUS_CHOICES = ( ('waiting', _('Waiting for confirmation')), diff --git a/payments/paypal/__init__.py b/payments/paypal/__init__.py index f2f955c..8a0da22 100644 --- a/payments/paypal/__init__.py +++ b/payments/paypal/__init__.py @@ -16,8 +16,8 @@ import requests from requests.exceptions import HTTPError from .forms import PaymentForm -from .. import ( - BasicProvider, get_credit_card_issuer, PaymentError, RedirectNeeded) +from .. import PaymentError, RedirectNeeded +from ..core import BasicProvider, get_credit_card_issuer # Get an instance of a logger logger = logging.getLogger(__name__) diff --git a/payments/paypal/forms.py b/payments/paypal/forms.py index 5821528..8cda756 100644 --- a/payments/paypal/forms.py +++ b/payments/paypal/forms.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from requests.exceptions import HTTPError from ..forms import CreditCardPaymentFormWithName -from .. import get_credit_card_issuer +from ..core import get_credit_card_issuer class PaymentForm(CreditCardPaymentFormWithName): diff --git a/payments/paypal/test_paypal.py b/payments/paypal/test_paypal.py index 8db6aca..20221f7 100644 --- a/payments/paypal/test_paypal.py +++ b/payments/paypal/test_paypal.py @@ -5,10 +5,10 @@ from unittest import TestCase from mock import patch, MagicMock, Mock from django.utils import timezone +from requests import HTTPError from . import PaypalProvider, PaypalCardProvider from .. import PurchasedItem, RedirectNeeded, PaymentError -from requests import HTTPError CLIENT_ID = 'abc123' PAYMENT_TOKEN = '5a4dae68-2715-4b1e-8bb2-2c2dbe9255f6' diff --git a/payments/sagepay/__init__.py b/payments/sagepay/__init__.py index dfde2a4..9ec8fcb 100644 --- a/payments/sagepay/__init__.py +++ b/payments/sagepay/__init__.py @@ -5,7 +5,7 @@ from Crypto.Cipher import AES from django.core.exceptions import ImproperlyConfigured from django.shortcuts import redirect -from .. import BasicProvider +from ..core import BasicProvider class SagepayProvider(BasicProvider): diff --git a/payments/sofort/__init__.py b/payments/sofort/__init__.py index 2a74c27..efde541 100644 --- a/payments/sofort/__init__.py +++ b/payments/sofort/__init__.py @@ -7,7 +7,8 @@ from django.utils.translation import get_language import requests import xmltodict -from .. import BasicProvider, RedirectNeeded, PaymentError +from .. import RedirectNeeded, PaymentError +from ..core import BasicProvider class SofortProvider(BasicProvider): diff --git a/payments/sofort/test_sofort.py b/payments/sofort/test_sofort.py index 996c79c..028b7f2 100644 --- a/payments/sofort/test_sofort.py +++ b/payments/sofort/test_sofort.py @@ -4,7 +4,7 @@ from mock import patch, MagicMock, Mock import json from . import SofortProvider -from payments import RedirectNeeded +from .. import RedirectNeeded SECRET = 'abcd1234' CLIENT_ID = '1234' diff --git a/payments/stripe/__init__.py b/payments/stripe/__init__.py index d6ebdf1..6a60f06 100644 --- a/payments/stripe/__init__.py +++ b/payments/stripe/__init__.py @@ -2,8 +2,10 @@ from __future__ import unicode_literals from django.core.exceptions import ImproperlyConfigured -from .. import BasicProvider, RedirectNeeded + from .forms import PaymentForm +from .. import RedirectNeeded +from ..core import BasicProvider class StripeProvider(BasicProvider): diff --git a/payments/stripe/forms.py b/payments/stripe/forms.py index c19b5f1..5f4ea42 100644 --- a/payments/stripe/forms.py +++ b/payments/stripe/forms.py @@ -4,10 +4,10 @@ from django import forms from django.utils.translation import ugettext as _ import stripe +from .widgets import StripeWidget +from .. import RedirectNeeded from ..forms import PaymentForm as BasePaymentForm from ..models import FRAUD_CHOICES -from .widgets import StripeWidget -from . import RedirectNeeded class PaymentForm(BasePaymentForm): diff --git a/payments/stripe/test_stripe.py b/payments/stripe/test_stripe.py index 05bb47c..966d500 100644 --- a/payments/stripe/test_stripe.py +++ b/payments/stripe/test_stripe.py @@ -6,9 +6,8 @@ from mock import patch, Mock from unittest import TestCase import stripe -from payments.stripe import StripeProvider - -from payments import RedirectNeeded +from . import StripeProvider +from .. import RedirectNeeded SECRET_KEY = '1234abcd' diff --git a/payments/stripe/widgets.py b/payments/stripe/widgets.py index e8774a2..e7d5071 100644 --- a/payments/stripe/widgets.py +++ b/payments/stripe/widgets.py @@ -1,6 +1,9 @@ from __future__ import unicode_literals -from django.forms.util import flatatt +try: + from django.forms.utils import flatatt +except ImportError: + from django.forms.util import flatatt from django.forms.widgets import Input from django.utils.html import format_html from django.utils.encoding import force_text diff --git a/payments/templates/payments/sofort/new_transaction.xml b/payments/templates/payments/sofort/new_transaction.xml index d6b023e..5344715 100644 --- a/payments/templates/payments/sofort/new_transaction.xml +++ b/payments/templates/payments/sofort/new_transaction.xml @@ -1,4 +1,4 @@ -{% load l10n i18n %}{% load url from future %}{% localize off %}<?xml version="1.0" encoding="UTF-8"?> +{% load l10n i18n %}{% localize off %}<?xml version="1.0" encoding="UTF-8"?> <multipay> <project_id>{{ project_id }}</project_id> <language_code>{{ language_code }}</language_code> diff --git a/payments/templates/payments/sofort/refund_transaction.xml b/payments/templates/payments/sofort/refund_transaction.xml index e621d6e..fa75a7c 100644 --- a/payments/templates/payments/sofort/refund_transaction.xml +++ b/payments/templates/payments/sofort/refund_transaction.xml @@ -1,4 +1,4 @@ -{% load l10n i18n %}{% load url from future %}{% localize off %}<?xml version="1.0" encoding="UTF-8" ?> +{% load l10n i18n %}{% localize off %}<?xml version="1.0" encoding="UTF-8" ?> <refunds version="3"> <sender> <holder>{{holder}}</holder> diff --git a/payments/test_core.py b/payments/test_core.py index 47f34dd..88c91dd 100644 --- a/payments/test_core.py +++ b/payments/test_core.py @@ -3,7 +3,7 @@ from decimal import Decimal from unittest import TestCase from mock import patch -from . import provider_factory +from .core import provider_factory from .forms import CreditCardPaymentFormWithName, PaymentForm from .models import BasePayment diff --git a/payments/urls.py b/payments/urls.py index 69e7200..a002222 100644 --- a/payments/urls.py +++ b/payments/urls.py @@ -14,7 +14,7 @@ except ImportError: def atomic(func): return func -from . import get_payment_model, provider_factory +from .core import get_payment_model, provider_factory @csrf_exempt diff --git a/payments/wallet/__init__.py b/payments/wallet/__init__.py index 35cd181..8b4ddaf 100644 --- a/payments/wallet/__init__.py +++ b/payments/wallet/__init__.py @@ -6,7 +6,7 @@ from django.http import HttpResponseForbidden, HttpResponse import jwt from .forms import PaymentForm, ProcessPaymentForm -from .. import BasicProvider +from ..core import BasicProvider class GoogleWalletProvider(BasicProvider): diff --git a/test_settings.py b/test_settings.py index 78f8258..b0e38e2 100644 --- a/test_settings.py +++ b/test_settings.py @@ -1,6 +1,13 @@ from __future__ import unicode_literals +import os + +PROJECT_ROOT = os.path.normpath( + os.path.join(os.path.dirname(__file__), 'payments')) +TEMPLATES = [{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(PROJECT_ROOT, 'templates')]}] SECRET_KEY = 'NOTREALLY' PAYMENT_HOST = 'example.com' -INSTALLED_APPS = ['payments'] +INSTALLED_APPS = ['payments', 'django.contrib.sites'] @@ -1,9 +1,13 @@ [tox] -envlist = py27,py33,py34 +envlist = py{27,34,35}-django{18,19,_master},py{27,34}-django14 [testenv] usedevelop=True deps= + django14: django>=1.4,<1.5a0 + django18: django>=1.8,<1.9a0 + django19: django>=1.9a1,<1.10a0 + django_master: https://github.com/django/django/archive/master.tar.gz mock pytest pytest-django |