Commit ec887120 by Jason Bau

use context processor instead of middleware

parent 6e543c14
""" """
This is the shoppingcart middleware class. This is the shoppingcart context_processor module.
Currently the only middleware is detects whether request.user has a cart that should be displayed in the Currently the only context_processor detects whether request.user has a cart that should be displayed in the
navigation. We want to do this in the middleware to navigation. We want to do this in the context_processor to
1) keep database accesses out of templates (this led to a transaction bug with user email changes) 1) keep database accesses out of templates (this led to a transaction bug with user email changes)
2) because navigation.html is "called" by being included in other templates, there's no "views.py" to put this. 2) because navigation.html is "called" by being included in other templates, there's no "views.py" to put this.
""" """
...@@ -9,26 +9,18 @@ from django.conf import settings ...@@ -9,26 +9,18 @@ from django.conf import settings
import shoppingcart import shoppingcart
class UserHasCartMiddleware(object): def user_has_cart_context_processor(request):
"""
Detects whether request.user has a cart and sets it as part of the request
***
Because this relies on request.user, it needs to enabled in settings after
django.contrib.auth.middleware.AuthenticationMiddleware (or equivalent)
***
"""
def process_request(self, request):
""" """
Checks if request has an authenticated user. If so, checks if request.user has a cart that should Checks if request has an authenticated user. If so, checks if request.user has a cart that should
be displayed. Anonymous users don't. be displayed. Anonymous users don't.
Adds `display_shopping_cart` to the context
""" """
request.display_shopping_cart = False display_shopping_cart = False
if ( if (
request.user.is_authenticated() and # user exists request.user.is_authenticated() and # user exists
settings.MITX_FEATURES.get('ENABLE_PAID_COURSE_REGISTRATION') and # settings is set settings.MITX_FEATURES.get('ENABLE_PAID_COURSE_REGISTRATION') and # settings is set
settings.MITX_FEATURES.get('ENABLE_SHOPPING_CART') and # setting is set settings.MITX_FEATURES.get('ENABLE_SHOPPING_CART') and # setting is set
shoppingcart.models.Order.user_cart_has_items(request.user) # user's cart is non-empty shoppingcart.models.Order.user_cart_has_items(request.user) # user's cart is non-empty
): ):
request.display_shopping_cart = True display_shopping_cart = True
return None return {'display_shopping_cart': display_shopping_cart}
""" """
Unit tests for shoppingcart middleware Unit tests for shoppingcart context_processor
""" """
from mock import patch, Mock from mock import patch, Mock
from django.conf import settings from django.conf import settings
...@@ -10,31 +10,26 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE ...@@ -10,31 +10,26 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory
from shoppingcart.models import Order, PaidCourseRegistration from shoppingcart.models import Order, PaidCourseRegistration
from shoppingcart.middleware import UserHasCartMiddleware from shoppingcart.context_processor import user_has_cart_context_processor
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class UserCartMiddlewareUnitTest(ModuleStoreTestCase): class UserCartContextProcessorUnitTest(ModuleStoreTestCase):
""" """
Unit test for shoppingcart middleware UserHasCartMiddleware Unit test for shoppingcart context_processor
""" """
def setUp(self): def setUp(self):
self.user = UserFactory.create() self.user = UserFactory.create()
self.request = Mock() self.request = Mock()
self.middleware = UserHasCartMiddleware()
def add_to_cart(self): def add_to_cart(self):
""" """
Adds content to self.user's cart Adds content to self.user's cart
""" """
course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course') course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
course_mode = CourseMode(course_id=course.id, CourseModeFactory(course_id=course.id)
mode_slug="honor",
mode_display_name="honor cert",
min_price=40)
course_mode.save()
cart = Order.get_cart_for_user(self.user) cart = Order.get_cart_for_user(self.user)
PaidCourseRegistration.add_to_order(cart, course.id) PaidCourseRegistration.add_to_order(cart, course.id)
...@@ -45,8 +40,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase): ...@@ -45,8 +40,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase):
""" """
self.add_to_cart() self.add_to_cart()
self.request.user = self.user self.request.user = self.user
self.middleware.process_request(self.request) context = user_has_cart_context_processor(self.request)
self.assertFalse(self.request.display_shopping_cart) self.assertFalse(context['display_shopping_cart'])
@patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': False}) @patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': False})
def test_no_enable_paid_course_registration(self): def test_no_enable_paid_course_registration(self):
...@@ -55,8 +50,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase): ...@@ -55,8 +50,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase):
""" """
self.add_to_cart() self.add_to_cart()
self.request.user = self.user self.request.user = self.user
self.middleware.process_request(self.request) context = user_has_cart_context_processor(self.request)
self.assertFalse(self.request.display_shopping_cart) self.assertFalse(context['display_shopping_cart'])
@patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True}) @patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True})
def test_anonymous_user(self): def test_anonymous_user(self):
...@@ -64,8 +59,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase): ...@@ -64,8 +59,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase):
Tests when request.user is anonymous Tests when request.user is anonymous
""" """
self.request.user = AnonymousUser() self.request.user = AnonymousUser()
self.middleware.process_request(self.request) context = user_has_cart_context_processor(self.request)
self.assertFalse(self.request.display_shopping_cart) self.assertFalse(context['display_shopping_cart'])
@patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True}) @patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True})
def test_no_items_in_cart(self): def test_no_items_in_cart(self):
...@@ -73,8 +68,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase): ...@@ -73,8 +68,8 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase):
Tests when request.user doesn't have a cart with items Tests when request.user doesn't have a cart with items
""" """
self.request.user = self.user self.request.user = self.user
self.middleware.process_request(self.request) context = user_has_cart_context_processor(self.request)
self.assertFalse(self.request.display_shopping_cart) self.assertFalse(context['display_shopping_cart'])
@patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True}) @patch.dict(settings.MITX_FEATURES, {'ENABLE_SHOPPING_CART': True, 'ENABLE_PAID_COURSE_REGISTRATION': True})
def test_items_in_cart(self): def test_items_in_cart(self):
...@@ -83,5 +78,5 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase): ...@@ -83,5 +78,5 @@ class UserCartMiddlewareUnitTest(ModuleStoreTestCase):
""" """
self.add_to_cart() self.add_to_cart()
self.request.user = self.user self.request.user = self.user
self.middleware.process_request(self.request) context = user_has_cart_context_processor(self.request)
self.assertTrue(self.request.display_shopping_cart) self.assertTrue(context['display_shopping_cart'])
...@@ -272,6 +272,9 @@ TEMPLATE_CONTEXT_PROCESSORS = ( ...@@ -272,6 +272,9 @@ TEMPLATE_CONTEXT_PROCESSORS = (
# Hack to get required link URLs to password reset templates # Hack to get required link URLs to password reset templates
'mitxmako.shortcuts.marketing_link_context_processor', 'mitxmako.shortcuts.marketing_link_context_processor',
# Shoppingcart processor (detects if request.user has a cart)
'shoppingcart.context_processor.user_has_cart_context_processor',
) )
# use the ratelimit backend to prevent brute force attacks # use the ratelimit backend to prevent brute force attacks
...@@ -610,9 +613,6 @@ MIDDLEWARE_CLASSES = ( ...@@ -610,9 +613,6 @@ MIDDLEWARE_CLASSES = (
# For A/B testing # For A/B testing
'waffle.middleware.WaffleMiddleware', 'waffle.middleware.WaffleMiddleware',
# Shoppingcart middleware (detects if request.user has a cart)
'shoppingcart.middleware.UserHasCartMiddleware',
) )
############################### Pipeline ####################################### ############################### Pipeline #######################################
......
...@@ -81,7 +81,7 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -81,7 +81,7 @@ site_status_msg = get_site_status_msg(course_id)
</ul> </ul>
</li> </li>
</ol> </ol>
% if getattr(request, 'display_shopping_cart', False): # see shoppingcart.middleware.UserHasCartMiddleware % if display_shopping_cart: # see shoppingcart.context_processor.user_has_cart_context_processor
<ol class="user"> <ol class="user">
<li class="primary"> <li class="primary">
<a class="shopping-cart" href="${reverse('shoppingcart.views.show_cart')}"> <a class="shopping-cart" href="${reverse('shoppingcart.views.show_cart')}">
......
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