Prep marketing iframe and relevant courseware view for email opt-in

Feature flagged. Puts a checkbox in the iframe. The iframe uses an organization_full_name parameter forwarded from Drupal by the courseware views and POSTs an email_opt_in parameter to the student views, preserving it on 403.
This commit is contained in:
Renzo Lucioni
2014-11-24 15:42:46 -05:00
parent eacd52568c
commit f5767a961c
7 changed files with 149 additions and 42 deletions

View File

@@ -3,6 +3,7 @@
Tests courseware views.py
"""
import unittest
import cgi
from datetime import datetime
from mock import MagicMock, patch, create_autospec
@@ -99,6 +100,10 @@ class ViewsTestCase(TestCase):
chapter = 'Overview'
self.chapter_url = '%s/%s/%s' % ('/courses', self.course_key, chapter)
# For marketing email opt-in
self.organization_full_name = u"𝖀𝖒𝖇𝖗𝖊𝖑𝖑𝖆 𝕮𝖔𝖗𝖕𝖔𝖗𝖆𝖙𝖎𝖔𝖓"
self.organization_html = "<p>'+Umbrella/Corporation+'</p>"
@unittest.skipUnless(settings.FEATURES.get('ENABLE_SHOPPING_CART'), "Shopping Cart not enabled in settings")
@patch.dict(settings.FEATURES, {'ENABLE_PAID_COURSE_REGISTRATION': True})
def test_course_about_in_cart(self):
@@ -256,17 +261,26 @@ class ViewsTestCase(TestCase):
# generate/store a real password.
self.assertEqual(chat_settings['password'], "johndoe@%s" % domain)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
def test_course_mktg_about_coming_soon(self):
# we should not be able to find this course
# We should not be able to find this course
url = reverse('mktg_about_course', kwargs={'course_id': 'no/course/here'})
response = self.client.get(url)
response = self.client.get(url, {'organization_full_name': self.organization_full_name})
self.assertIn('Coming Soon', response.content)
# Verify that the checkbox is not displayed
self._email_opt_in_checkbox(response)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
def test_course_mktg_register(self):
response = self._load_mktg_about()
response = self._load_mktg_about(organization_full_name=self.organization_full_name)
self.assertIn('Enroll in', response.content)
self.assertNotIn('and choose your student track', response.content)
# Verify that the checkbox is displayed
self._email_opt_in_checkbox(response, self.organization_full_name)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
def test_course_mktg_register_multiple_modes(self):
CourseMode.objects.get_or_create(
mode_slug='honor',
@@ -279,12 +293,42 @@ class ViewsTestCase(TestCase):
course_id=self.course_key
)
response = self._load_mktg_about()
response = self._load_mktg_about(organization_full_name=self.organization_full_name)
self.assertIn('Enroll in', response.content)
self.assertIn('and choose your student track', response.content)
# Verify that the checkbox is displayed
self._email_opt_in_checkbox(response, self.organization_full_name)
# clean up course modes
CourseMode.objects.all().delete()
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
def test_course_mktg_no_organization_name(self):
# Don't pass an organization name as a GET parameter, even though the email
# opt-in feature is enabled.
response = response = self._load_mktg_about()
# Verify that the checkbox is not displayed
self._email_opt_in_checkbox(response)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': False})
def test_course_mktg_opt_in_disabled(self):
# Pass an organization name as a GET parameter, even though the email
# opt-in feature is disabled.
response = self._load_mktg_about(organization_full_name=self.organization_full_name)
# Verify that the checkbox is not displayed
self._email_opt_in_checkbox(response)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
def test_course_mktg_organization_html(self):
response = self._load_mktg_about(organization_full_name=self.organization_html)
# Verify that the checkbox is displayed with the organization name
# in the label escaped as expected.
self._email_opt_in_checkbox(response, cgi.escape(self.organization_html))
@patch.dict(settings.FEATURES, {'IS_EDX_DOMAIN': True})
def test_mktg_about_language_edx_domain(self):
# Since we're in an edx-controlled domain, and our marketing site
@@ -340,9 +384,8 @@ class ViewsTestCase(TestCase):
response = self.client.get(url)
self.assertFalse('<script>' in response.content)
def _load_mktg_about(self, language=None):
"""
Retrieve the marketing about button (iframed into the marketing site)
def _load_mktg_about(self, language=None, organization_full_name=None):
"""Retrieve the marketing about button (iframed into the marketing site)
and return the HTTP response.
Keyword Args:
@@ -362,7 +405,22 @@ class ViewsTestCase(TestCase):
headers['HTTP_ACCEPT_LANGUAGE'] = language
url = reverse('mktg_about_course', kwargs={'course_id': unicode(self.course_key)})
return self.client.get(url, **headers)
if organization_full_name:
return self.client.get(url, {'organization_full_name': organization_full_name}, **headers)
else:
return self.client.get(url, **headers)
def _email_opt_in_checkbox(self, response, organization_full_name=None):
"""Check if the email opt-in checkbox appears in the response content."""
checkbox_html = '<input id="email-opt-in" type="checkbox" name="opt-in" class="email-opt-in" value="true" checked>'
if organization_full_name:
# Verify that the email opt-in checkbox appears, and that the expected
# organization name is displayed.
self.assertContains(response, checkbox_html, html=True)
self.assertContains(response, organization_full_name)
else:
# Verify that the email opt-in checkbox does not appear
self.assertNotContains(response, checkbox_html, html=True)
# setting TIME_ZONE_DISPLAYED_FOR_DEADLINES explicitly

View File

@@ -5,6 +5,7 @@ Courseware views functions
import logging
import urllib
import json
import cgi
from datetime import datetime
from collections import defaultdict
@@ -93,7 +94,7 @@ def user_groups(user):
@ensure_csrf_cookie
@cache_if_anonymous
@cache_if_anonymous()
def courses(request):
"""
Render "find courses" page. The course selection work is done in courseware.courses.
@@ -713,7 +714,7 @@ def registered_for_course(course, user):
@ensure_csrf_cookie
@cache_if_anonymous
@cache_if_anonymous()
def course_about(request, course_id):
"""
Display the course's about page.
@@ -802,13 +803,10 @@ def course_about(request, course_id):
@ensure_csrf_cookie
@cache_if_anonymous
@cache_if_anonymous('organization_full_name')
@ensure_valid_course_key
def mktg_course_about(request, course_id):
"""
This is the button that gets put into an iframe on the Drupal site
"""
"""This is the button that gets put into an iframe on the Drupal site."""
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
try:
@@ -818,8 +816,7 @@ def mktg_course_about(request, course_id):
)
course = get_course_with_access(request.user, permission_name, course_key)
except (ValueError, Http404):
# if a course does not exist yet, display a coming
# soon button
# If a course does not exist yet, display a "Coming Soon" button
return render_to_response(
'courseware/mktg_coming_soon.html', {'course_id': course_key.to_deprecated_string()}
)
@@ -846,6 +843,12 @@ def mktg_course_about(request, course_id):
'course_modes': course_modes,
}
if settings.FEATURES.get('ENABLE_MKTG_EMAIL_OPT_IN'):
# Drupal will pass the organization's full name as a GET parameter. If no full name
# is provided, the marketing iframe won't show the email opt-in checkbox.
organization_full_name = request.GET.get('organization_full_name')
context['organization_full_name'] = cgi.escape(organization_full_name) if organization_full_name else organization_full_name
# The edx.org marketing site currently displays only in English.
# To avoid displaying a different language in the register / access button,
# we force the language to English.