Commit 127d83b6 by Clinton Blackburn

Merge pull request #170 from edx/django-1.8

Upgrade to Django 1.8
parents 55ceb2fd 3d324249
...@@ -33,7 +33,7 @@ class HealthTests(TestCase): ...@@ -33,7 +33,7 @@ class HealthTests(TestCase):
self._assert_health(status.HTTP_200_OK, Status.OK, Status.OK, Status.OK) self._assert_health(status.HTTP_200_OK, Status.OK, Status.OK, Status.OK)
@mock.patch('django.db.backends.BaseDatabaseWrapper.cursor', mock.Mock(side_effect=DatabaseError)) @mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.cursor', mock.Mock(side_effect=DatabaseError))
def test_database_outage(self, mock_lms_request): def test_database_outage(self, mock_lms_request):
"""Test that the endpoint reports when the database is unavailable.""" """Test that the endpoint reports when the database is unavailable."""
self.fake_lms_response.status_code = status.HTTP_200_OK self.fake_lms_response.status_code = status.HTTP_200_OK
...@@ -115,7 +115,7 @@ class AutoAuthTests(TestCase): ...@@ -115,7 +115,7 @@ class AutoAuthTests(TestCase):
user = User.objects.latest() user = User.objects.latest()
# Verify that the user is logged in and that their username has the expected prefix # Verify that the user is logged in and that their username has the expected prefix
self.assertEqual(self.client.session['_auth_user_id'], user.pk) self.assertEqual(int(self.client.session['_auth_user_id']), user.pk)
self.assertTrue(user.username.startswith(settings.AUTO_AUTH_USERNAME_PREFIX)) self.assertTrue(user.username.startswith(settings.AUTO_AUTH_USERNAME_PREFIX))
# Verify that the user has superuser permissions # Verify that the user has superuser permissions
......
from django.conf.urls import patterns, url from django.conf.urls import url
from django.contrib import admin from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin from simple_history.admin import SimpleHistoryAdmin
...@@ -17,13 +17,12 @@ class CourseAdmin(SimpleHistoryAdmin): ...@@ -17,13 +17,12 @@ class CourseAdmin(SimpleHistoryAdmin):
info = opts.app_label, opts.model_name info = opts.app_label, opts.model_name
except AttributeError: # Django < 1.7 except AttributeError: # Django < 1.7
info = opts.app_label, opts.module_name info = opts.app_label, opts.module_name
history_urls = patterns( history_urls = [
"",
# Note: We use a custom URL pattern to match against course IDs. # Note: We use a custom URL pattern to match against course IDs.
url("^(.+)/history/([^/]+)/$", url("^(.+)/history/([^/]+)/$",
admin_site.admin_view(self.history_form_view), admin_site.admin_view(self.history_form_view),
name='%s_%s_simple_history' % info), name='%s_%s_simple_history' % info),
) ]
return history_urls + urls return history_urls + urls
......
from django.conf.urls import patterns, url from django.conf.urls import url
from ecommerce.courses import views from ecommerce.courses import views
urlpatterns = patterns( urlpatterns = [
'',
url(r'^migrate/$', views.CourseMigrationView.as_view(), name='migrate'), url(r'^migrate/$', views.CourseMigrationView.as_view(), name='migrate'),
# Declare all paths above this line to avoid dropping into the Course Admin Tool (which does its own routing) # Declare all paths above this line to avoid dropping into the Course Admin Tool (which does its own routing)
url(r'^(.*)$', views.CourseAppView.as_view(), name='app'), url(r'^(.*)$', views.CourseAppView.as_view(), name='app'),
) ]
from django.conf.urls import patterns, url from django.conf.urls import url
from ecommerce.core.constants import COURSE_ID_PATTERN from ecommerce.core.constants import COURSE_ID_PATTERN
from ecommerce.credit.views import Checkout from ecommerce.credit.views import Checkout
urlpatterns = [
urlpatterns = patterns(
'',
url(r'^checkout/{course}/$'.format(course=COURSE_ID_PATTERN), url(r'^checkout/{course}/$'.format(course=COURSE_ID_PATTERN),
Checkout.as_view(), name='checkout'), Checkout.as_view(), name='checkout'),
) ]
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
from datetime import datetime from datetime import datetime
import json import json
import httpretty
from django.conf import settings from django.conf import settings
from django.conf.urls import patterns
from django.http import HttpResponse from django.http import HttpResponse
from django.conf.urls import url
from django.test import TestCase, override_settings, RequestFactory from django.test import TestCase, override_settings, RequestFactory
import httpretty
from oscar.test import factories from oscar.test import factories
from rest_framework import permissions from rest_framework import permissions
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
...@@ -26,10 +26,10 @@ class MockView(APIView): ...@@ -26,10 +26,10 @@ class MockView(APIView):
def get(self, request): # pylint: disable=unused-variable, unused-argument def get(self, request): # pylint: disable=unused-variable, unused-argument
return HttpResponse() return HttpResponse()
urlpatterns = patterns(
'', urlpatterns = [
(r'^jwt/$', MockView.as_view(authentication_classes=[JwtAuthentication])) url(r'^jwt/$', MockView.as_view(authentication_classes=[JwtAuthentication]))
) ]
class AccessTokenMixin(object): class AccessTokenMixin(object):
...@@ -123,9 +123,8 @@ class BearerAuthenticationTests(AccessTokenMixin, TestCase): ...@@ -123,9 +123,8 @@ class BearerAuthenticationTests(AccessTokenMixin, TestCase):
self.assertEqual(self.auth.authenticate(request), (user, self.DEFAULT_TOKEN)) self.assertEqual(self.auth.authenticate(request), (user, self.DEFAULT_TOKEN))
@override_settings(ROOT_URLCONF='ecommerce.extensions.api.tests.test_authentication')
class JwtAuthenticationTests(JwtMixin, UserMixin, TestCase): class JwtAuthenticationTests(JwtMixin, UserMixin, TestCase):
urls = 'ecommerce.extensions.api.tests.test_authentication'
def setUp(self): def setUp(self):
api_settings.JWT_ISSUER = 'http://example.com/oauth' api_settings.JWT_ISSUER = 'http://example.com/oauth'
api_settings.JWT_VERIFY_EXPIRATION = True api_settings.JWT_VERIFY_EXPIRATION = True
......
from django.conf.urls import patterns, url, include from django.conf.urls import url, include
urlpatterns = [
urlpatterns = patterns(
'',
url(r'^v2/', include('ecommerce.extensions.api.v2.urls', namespace='v2')), url(r'^v2/', include('ecommerce.extensions.api.v2.urls', namespace='v2')),
) ]
from django.conf.urls import patterns, url, include from django.conf.urls import url, include
from django.views.decorators.cache import cache_page from django.views.decorators.cache import cache_page
from rest_framework_extensions.routers import ExtendedSimpleRouter from rest_framework_extensions.routers import ExtendedSimpleRouter
from ecommerce.core.constants import COURSE_ID_PATTERN from ecommerce.core.constants import COURSE_ID_PATTERN
from ecommerce.extensions.api.v2 import views from ecommerce.extensions.api.v2 import views
ORDER_NUMBER_PATTERN = r'(?P<number>[-\w]+)' ORDER_NUMBER_PATTERN = r'(?P<number>[-\w]+)'
BASKET_ID_PATTERN = r'(?P<basket_id>[\w]+)' BASKET_ID_PATTERN = r'(?P<basket_id>[\w]+)'
BASKET_URLS = [
BASKET_URLS = patterns(
'',
url(r'^$', views.BasketCreateView.as_view(), name='create'), url(r'^$', views.BasketCreateView.as_view(), name='create'),
url( url(
r'^{basket_id}/order/$'.format(basket_id=BASKET_ID_PATTERN), r'^{basket_id}/order/$'.format(basket_id=BASKET_ID_PATTERN),
views.OrderByBasketRetrieveView.as_view(), views.OrderByBasketRetrieveView.as_view(),
name='retrieve_order' name='retrieve_order'
), ),
) ]
ORDER_URLS = patterns( ORDER_URLS = [
'',
url(r'^$', views.OrderListView.as_view(), name='list'), url(r'^$', views.OrderListView.as_view(), name='list'),
url( url(
r'^{number}/$'.format(number=ORDER_NUMBER_PATTERN), r'^{number}/$'.format(number=ORDER_NUMBER_PATTERN),
...@@ -33,40 +29,36 @@ ORDER_URLS = patterns( ...@@ -33,40 +29,36 @@ ORDER_URLS = patterns(
views.OrderFulfillView.as_view(), views.OrderFulfillView.as_view(),
name='fulfill' name='fulfill'
), ),
) ]
PAYMENT_URLS = patterns( PAYMENT_URLS = [
'',
url(r'^processors/$', cache_page(60 * 30)(views.PaymentProcessorListView.as_view()), name='list_processors'), url(r'^processors/$', cache_page(60 * 30)(views.PaymentProcessorListView.as_view()), name='list_processors'),
) ]
REFUND_URLS = patterns( REFUND_URLS = [
'',
url(r'^$', views.RefundCreateView.as_view(), name='create'), url(r'^$', views.RefundCreateView.as_view(), name='create'),
url(r'^(?P<pk>[\d]+)/process/$', views.RefundProcessView.as_view(), name='process'), url(r'^(?P<pk>[\d]+)/process/$', views.RefundProcessView.as_view(), name='process'),
) ]
ATOMIC_PUBLICATION_URLS = patterns( ATOMIC_PUBLICATION_URLS = [
'',
url(r'^$', views.AtomicPublicationView.as_view(), name='create'), url(r'^$', views.AtomicPublicationView.as_view(), name='create'),
url( url(
r'^{course_id}$'.format(course_id=COURSE_ID_PATTERN), r'^{course_id}$'.format(course_id=COURSE_ID_PATTERN),
views.AtomicPublicationView.as_view(), views.AtomicPublicationView.as_view(),
name='update' name='update'
), ),
) ]
urlpatterns = patterns( urlpatterns = [
'',
url(r'^baskets/', include(BASKET_URLS, namespace='baskets')), url(r'^baskets/', include(BASKET_URLS, namespace='baskets')),
url(r'^orders/', include(ORDER_URLS, namespace='orders')), url(r'^orders/', include(ORDER_URLS, namespace='orders')),
url(r'^payment/', include(PAYMENT_URLS, namespace='payment')), url(r'^payment/', include(PAYMENT_URLS, namespace='payment')),
url(r'^refunds/', include(REFUND_URLS, namespace='refunds')), url(r'^refunds/', include(REFUND_URLS, namespace='refunds')),
url(r'^publication/', include(ATOMIC_PUBLICATION_URLS, namespace='publication')), url(r'^publication/', include(ATOMIC_PUBLICATION_URLS, namespace='publication')),
) ]
router = ExtendedSimpleRouter() router = ExtendedSimpleRouter()
router.register(r'courses', views.CourseViewSet)\ router.register(r'courses', views.CourseViewSet) \
.register(r'products', views.ProductViewSet, base_name='course-product', parents_query_lookups=['course_id']) .register(r'products', views.ProductViewSet, base_name='course-product', parents_query_lookups=['course_id'])
router.register(r'products', views.ProductViewSet) router.register(r'products', views.ProductViewSet)
......
...@@ -80,7 +80,7 @@ class Cybersource(BasePaymentProcessor): ...@@ -80,7 +80,7 @@ class Cybersource(BasePaymentProcessor):
u'transaction_uuid': uuid.uuid4().hex, u'transaction_uuid': uuid.uuid4().hex,
u'signed_field_names': u'', u'signed_field_names': u'',
u'unsigned_field_names': u'', u'unsigned_field_names': u'',
u'signed_date_time': datetime.datetime.utcnow().strftime(ISO_8601_FORMAT), u'signed_date_time': self.utcnow().strftime(ISO_8601_FORMAT),
u'locale': self.language_code, u'locale': self.language_code,
u'transaction_type': u'sale', u'transaction_type': u'sale',
u'reference_number': basket.order_number, u'reference_number': basket.order_number,
...@@ -110,6 +110,15 @@ class Cybersource(BasePaymentProcessor): ...@@ -110,6 +110,15 @@ class Cybersource(BasePaymentProcessor):
return parameters return parameters
@staticmethod @staticmethod
def utcnow():
"""
Returns the current datetime in UTC.
This is primarily here as a test helper, since we cannot mock datetime.datetime.
"""
return datetime.datetime.utcnow()
@staticmethod
def get_single_seat(basket): def get_single_seat(basket):
""" """
Return the first product encountered in the basket with the product Return the first product encountered in the basket with the product
......
...@@ -23,7 +23,6 @@ from paypalrestsdk.resource import Resource ...@@ -23,7 +23,6 @@ from paypalrestsdk.resource import Resource
from ecommerce.core.constants import ISO_8601_FORMAT from ecommerce.core.constants import ISO_8601_FORMAT
from ecommerce.courses.models import Course from ecommerce.courses.models import Course
from ecommerce.extensions.catalogue.tests.mixins import CourseCatalogTestMixin from ecommerce.extensions.catalogue.tests.mixins import CourseCatalogTestMixin
from ecommerce.extensions.payment import processors
from ecommerce.extensions.payment.exceptions import (InvalidSignatureError, InvalidCybersourceDecision, from ecommerce.extensions.payment.exceptions import (InvalidSignatureError, InvalidCybersourceDecision,
PartialAuthorizationError) PartialAuthorizationError)
from ecommerce.extensions.payment.models import PaypalWebProfile from ecommerce.extensions.payment.models import PaypalWebProfile
...@@ -101,9 +100,7 @@ class CybersourceTests(CybersourceMixin, PaymentProcessorTestCaseMixin, TestCase ...@@ -101,9 +100,7 @@ class CybersourceTests(CybersourceMixin, PaymentProcessorTestCaseMixin, TestCase
""" Verify the processor returns the appropriate parameters required to complete a transaction. """ """ Verify the processor returns the appropriate parameters required to complete a transaction. """
# Patch the datetime object so that we can validate the signed_date_time field # Patch the datetime object so that we can validate the signed_date_time field
with mock.patch.object(processors.cybersource.datetime, u'datetime', with mock.patch.object(Cybersource, u'utcnow', return_value=self.PI_DAY):
mock.Mock(wraps=datetime.datetime)) as mocked_datetime:
mocked_datetime.utcnow.return_value = self.PI_DAY
actual = self.processor.get_transaction_parameters(self.basket) actual = self.processor.get_transaction_parameters(self.basket)
configuration = settings.PAYMENT_PROCESSOR_CONFIG[self.processor_name] configuration = settings.PAYMENT_PROCESSOR_CONFIG[self.processor_name]
......
""" Payment-related URLs """ """ Payment-related URLs """
from django.conf.urls import patterns, url from django.conf.urls import url
from ecommerce.extensions.payment import views from ecommerce.extensions.payment import views
urlpatterns = patterns( urlpatterns = [
'',
url(r'^cybersource/notify/$', views.CybersourceNotifyView.as_view(), name='cybersource_notify'), url(r'^cybersource/notify/$', views.CybersourceNotifyView.as_view(), name='cybersource_notify'),
url(r'^paypal/execute/$', views.PaypalPaymentExecutionView.as_view(), name='paypal_execute'), url(r'^paypal/execute/$', views.PaypalPaymentExecutionView.as_view(), name='paypal_execute'),
url(r'^paypal/profiles/$', views.PaypalProfileAdminView.as_view(), name='paypal_profiles'), url(r'^paypal/profiles/$', views.PaypalProfileAdminView.as_view(), name='paypal_profiles'),
) ]
from django.conf.urls import patterns, url, include from django.conf.urls import url, include
from ecommerce.extensions.app import application from ecommerce.extensions.app import application
from ecommerce.extensions.payment.app import application as payment from ecommerce.extensions.payment.app import application as payment
urlpatterns = [
urlpatterns = patterns(
'',
url(r'^api/', include('ecommerce.extensions.api.urls', namespace='api')), url(r'^api/', include('ecommerce.extensions.api.urls', namespace='api')),
url(r'^payment/', include(payment.urls)), url(r'^payment/', include(payment.urls)),
url(r'', include(application.urls)), url(r'', include(application.urls)),
) ]
import os import os
from django.conf import settings from django.conf import settings
from django.conf.urls import patterns, url, include from django.conf.urls import url, include
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.views import logout from django.contrib.auth.views import logout
...@@ -37,8 +37,7 @@ js_info_dict = { ...@@ -37,8 +37,7 @@ js_info_dict = {
'packages': ('courses',), 'packages': ('courses',),
} }
urlpatterns = patterns( urlpatterns = [
'',
url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
...@@ -58,7 +57,7 @@ urlpatterns = patterns( ...@@ -58,7 +57,7 @@ urlpatterns = patterns(
url('', include('social.apps.django_app.urls', namespace='social')), url('', include('social.apps.django_app.urls', namespace='social')),
url(r'^courses/', include('ecommerce.courses.urls', namespace='courses')), url(r'^courses/', include('ecommerce.courses.urls', namespace='courses')),
url(r'^credit/', include('ecommerce.credit.urls', namespace='credit')), url(r'^credit/', include('ecommerce.credit.urls', namespace='credit')),
) ]
# Install Oscar extension URLs # Install Oscar extension URLs
urlpatterns += extensions_patterns urlpatterns += extensions_patterns
...@@ -70,20 +69,17 @@ if settings.DEBUG and settings.MEDIA_ROOT: # pragma: no cover ...@@ -70,20 +69,17 @@ if settings.DEBUG and settings.MEDIA_ROOT: # pragma: no cover
) )
if settings.DEBUG: # pragma: no cover if settings.DEBUG: # pragma: no cover
# Allow error pages to be tested urlpatterns += [
urlpatterns += patterns(
'',
url(r'^403/$', handler403, name='403'), url(r'^403/$', handler403, name='403'),
url(r'^404/$', 'django.views.defaults.page_not_found', name='404'), url(r'^404/$', 'django.views.defaults.page_not_found', name='404'),
url(r'^500/$', 'django.views.defaults.server_error', name='500'), url(r'^500/$', 'django.views.defaults.server_error', name='500'),
url(r'^bootstrap/$', TemplateView.as_view(template_name='bootstrap-demo.html')), url(r'^bootstrap/$', TemplateView.as_view(template_name='bootstrap-demo.html')),
]
) # Allow error pages to be tested
if os.environ.get('ENABLE_DJANGO_TOOLBAR', False): if os.environ.get('ENABLE_DJANGO_TOOLBAR', False):
import debug_toolbar # pylint: disable=import-error import debug_toolbar # pylint: disable=import-error
urlpatterns += patterns( urlpatterns += [
'', url(r'^__debug__/', include(debug_toolbar.urls))
url(r'^__debug__/', include(debug_toolbar.urls)), ]
)
analytics-python==1.0.3 analytics-python==1.0.3
Django==1.7.10 Django==1.8.4
django-appconf==0.6 django-appconf==0.6
django-compressor==1.5 django-compressor==1.5
django_extensions==1.5.5 django_extensions==1.5.5
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment