Commit 82d7e25f by Will Daly

Add views to the embargo app to render messages explaining why students are blocked.

parent 19f676a8
......@@ -10,18 +10,31 @@ from collections import namedtuple
BlockedMessage = namedtuple('BlockedMessage', [
# A user-facing description of the message
'description',
# The mako template used to render the message
'template',
])
ENROLL_MESSAGES = {
'default': BlockedMessage(
description='Default',
template='static_templates/enrollment_access_block.html'
),
'embargo': BlockedMessage(
description='Embargo',
template='static_templates/embargo.html'
)
}
ACCESS_MESSAGES = {
COURSEWARE_MESSAGES = {
'default': BlockedMessage(
description='Default',
template='static_templates/courseware_access_block.html'
),
'embargo': BlockedMessage(
description='Embargo',
template='static_templates/embargo.html'
)
}
......@@ -16,6 +16,8 @@ class Migration(DataMigration):
orm.CountryAccessRule.objects.get_or_create(
country=country_model,
rule_type='blacklist',
enroll_msg_key='embargo',
access_msg_key='embargo',
restricted_course=new_course
)
......
......@@ -21,7 +21,7 @@ from django_countries.fields import CountryField
from config_models.models import ConfigurationModel
from xmodule_django.models import CourseKeyField, NoneToEmptyManager
from embargo.messages import ENROLL_MESSAGES, ACCESS_MESSAGES
from embargo.messages import ENROLL_MESSAGES, COURSEWARE_MESSAGES
class EmbargoedCourse(models.Model):
......@@ -99,9 +99,9 @@ class RestrictedCourse(models.Model):
for msg_key, msg in ENROLL_MESSAGES.iteritems()
])
ACCESS_MSG_KEY_CHOICES = tuple([
COURSEWARE_MSG_KEY_CHOICES = tuple([
(msg_key, msg.description)
for msg_key, msg in ACCESS_MESSAGES.iteritems()
for msg_key, msg in COURSEWARE_MESSAGES.iteritems()
])
course_key = CourseKeyField(
......@@ -118,7 +118,7 @@ class RestrictedCourse(models.Model):
access_msg_key = models.CharField(
max_length=255,
choices=ACCESS_MSG_KEY_CHOICES,
choices=COURSEWARE_MSG_KEY_CHOICES,
default='default',
help_text=ugettext_lazy(u"The message to show when a user is blocked from accessing a course.")
)
......
"""Tests for embargo app views. """
import unittest
from mock import patch
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf import settings
import ddt
from util.testing import UrlResetMixin
from embargo import messages
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@ddt.ddt
class CourseAccessMessageViewTest(UrlResetMixin, TestCase):
"""Tests for the courseware access message view.
These end-points serve static content.
While we *could* check the text on each page,
this will require changes to the test every time
the text on the page changes.
Instead, we load each page we expect to be available
(based on the configuration in `embargo.messages`)
and verify that we get the correct status code.
This will catch errors in the message configuration
(for example, moving a template and forgetting to
update the configuration appropriately).
"""
@patch.dict(settings.FEATURES, {'ENABLE_COUNTRY_ACCESS': True})
def setUp(self):
super(CourseAccessMessageViewTest, self).setUp('embargo')
@ddt.data(*messages.ENROLL_MESSAGES.keys())
def test_enrollment_messages(self, msg_key):
self._load_page('enrollment', msg_key)
@ddt.data(*messages.COURSEWARE_MESSAGES.keys())
def test_courseware_messages(self, msg_key):
self._load_page('courseware', msg_key)
@ddt.data('enrollment', 'courseware')
def test_invalid_message_key(self, access_point):
self._load_page(access_point, 'invalid', expected_status=404)
def _load_page(self, access_point, message_key, expected_status=200):
"""Load the message page and check the status code. """
url = reverse('embargo_blocked_message', kwargs={
'access_point': access_point,
'message_key': message_key
})
response = self.client.get(url)
self.assertEqual(
response.status_code, expected_status,
msg=(
u"Unexpected status code when loading '{url}': "
u"expected {expected} but got {actual}"
).format(
url=url,
expected=expected_status,
actual=response.status_code
)
)
"""URLs served by the embargo app. """
from django.conf.urls import patterns, url
from embargo.views import CourseAccessMessageView
urlpatterns = patterns(
'embargo.views',
url(
r'^blocked-message/(?P<access_point>enrollment|courseware)/(?P<message_key>.+)/$',
CourseAccessMessageView.as_view(),
name='embargo_blocked_message',
),
)
"""Views served by the embargo app. """
from django.http import Http404
from django.views.generic.base import View
from edxmako.shortcuts import render_to_response
from embargo import messages
class CourseAccessMessageView(View):
"""Show a message explaining that the user was blocked from a course. """
ENROLLMENT_ACCESS_POINT = 'enrollment'
COURSEWARE_ACCESS_POINT = 'courseware'
def get(self, request, access_point=None, message_key=None):
"""Show a message explaining that the user was blocked.
Arguments:
request (HttpRequest)
Keyword Arguments:
access_point (str): Either 'enrollment' or 'courseware',
indicating how the user is trying to access the restricted
content.
message_key (str): An identifier for which message to show.
See `embargo.messages` for more information.
Returns:
HttpResponse
Raises:
Http404: If no message is configured for the specified message key.
"""
blocked_message = self._message(access_point, message_key)
if blocked_message is None:
raise Http404
return render_to_response(blocked_message.template, {})
def _message(self, access_point, message_key):
"""Retrieve message information.
Arguments:
access_point (str): Either 'enrollment' or 'courseware'
message_key (str): The identifier for which message to show.
Returns:
embargo.messages.BlockedMessage or None
"""
message_dict = dict()
# The access point determines which set of messages to use.
# This allows us to show different messages to students who
# are enrolling in a course than we show to students
# who are enrolled and accessing courseware.
if access_point == self.ENROLLMENT_ACCESS_POINT:
message_dict = messages.ENROLL_MESSAGES
elif access_point == self.COURSEWARE_ACCESS_POINT:
message_dict = messages.COURSEWARE_MESSAGES
# Return the message corresponding to the given key if one is available.
return message_dict.get(message_key)
......@@ -252,6 +252,10 @@ FEATURES = {
# Toggles the embargo site functionality, which enable embargoing for the whole site
'SITE_EMBARGOED': False,
# Toggle whether to replace the current embargo implementation with
# the more flexible "country access" feature.
'ENABLE_COUNTRY_ACCESS': False,
# Whether the Wiki subsystem should be accessible via the direct /wiki/ paths. Setting this to True means
# that people can submit content and modify the Wiki in any arbitrary manner. We're leaving this as True in the
# defaults, so that we maintain current behavior
......
<%! from django.utils.translation import ugettext as _ %>
<%inherit file="../main.html" />
<%block name="pagetitle">${_("This Course Unavailable In Your Country")}</%block>
<section class="outside-app">
<p>
${_("Our system indicates that you are trying to access this {platform_name} "
"course from a country or region in which it is not currently available."
).format(platform_name=settings.PLATFORM_NAME)}
</p>
</section>
<%! from django.utils.translation import ugettext as _ %>
<%inherit file="../main.html" />
<%block name="pagetitle">${_("This Course Unavailable In Your Country")}</%block>
<section class="outside-app">
<p>
${_("Our system indicates that you are trying to enroll in this {platform_name} "
"course from a country or region in which it is not currently available."
).format(platform_name=settings.PLATFORM_NAME)}
</p>
</section>
......@@ -484,6 +484,12 @@ urlpatterns += (
url(r'^shoppingcart/', include('shoppingcart.urls')),
)
# Country access (embargo)
if settings.FEATURES.get('ENABLE_COUNTRY_ACCESS'):
urlpatterns += (
url(r'^embargo/', include('embargo.urls')),
)
# Survey Djangoapp
urlpatterns += (
url(r'^survey/', include('survey.urls')),
......
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