Commit 0c9d682d by David Baumgold

Merge pull request #3196 from mtyaka/enrollment-emails-http

Don't hardcode https protocol in enrollment emails.
parents aeaddef3 b7558636
...@@ -223,7 +223,7 @@ def _reset_module_attempts(studentmodule): ...@@ -223,7 +223,7 @@ def _reset_module_attempts(studentmodule):
studentmodule.save() studentmodule.save()
def get_email_params(course, auto_enroll): def get_email_params(course, auto_enroll, secure=True):
""" """
Generate parameters used when parsing email templates. Generate parameters used when parsing email templates.
...@@ -231,27 +231,32 @@ def get_email_params(course, auto_enroll): ...@@ -231,27 +231,32 @@ def get_email_params(course, auto_enroll):
Returns a dict of parameters Returns a dict of parameters
""" """
protocol = 'https' if secure else 'http'
stripped_site_name = microsite.get_value( stripped_site_name = microsite.get_value(
'SITE_NAME', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
# TODO: Use request.build_absolute_uri rather than 'https://{}{}'.format # TODO: Use request.build_absolute_uri rather than '{proto}://{site}{path}'.format
# and check with the Services team that this works well with microsites # and check with the Services team that this works well with microsites
registration_url = u'https://{}{}'.format( registration_url = u'{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('student.views.register_user') site=stripped_site_name,
path=reverse('student.views.register_user')
) )
course_url = u'https://{}{}'.format( course_url = u'{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('course_root', kwargs={'course_id': course.id.to_deprecated_string()}) site=stripped_site_name,
path=reverse('course_root', kwargs={'course_id': course.id.to_deprecated_string()})
) )
# We can't get the url to the course's About page if the marketing site is enabled. # We can't get the url to the course's About page if the marketing site is enabled.
course_about_url = None course_about_url = None
if not settings.FEATURES.get('ENABLE_MKTG_SITE', False): if not settings.FEATURES.get('ENABLE_MKTG_SITE', False):
course_about_url = u'https://{}{}'.format( course_about_url = u'{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('about_course', kwargs={'course_id': course.id.to_deprecated_string()}) site=stripped_site_name,
path=reverse('about_course', kwargs={'course_id': course.id.to_deprecated_string()})
) )
is_shib_course = uses_shib(course) is_shib_course = uses_shib(course)
......
...@@ -7,6 +7,7 @@ import unittest ...@@ -7,6 +7,7 @@ import unittest
import json import json
import requests import requests
import datetime import datetime
import ddt
from urllib import quote from urllib import quote
from django.test import TestCase from django.test import TestCase
from nose.tools import raises from nose.tools import raises
...@@ -252,6 +253,7 @@ class TestInstructorAPIDenyLevels(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -252,6 +253,7 @@ class TestInstructorAPIDenyLevels(ModuleStoreTestCase, LoginEnrollmentTestCase):
) )
@ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" """
...@@ -286,9 +288,8 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -286,9 +288,8 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
'SITE_NAME', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
self.registration_url = 'https://{}/register'.format(self.site_name) self.about_path = '/courses/MITx/999/Robot_Super_Course/about'
self.about_url = 'https://{}/courses/MITx/999/Robot_Super_Course/about'.format(self.site_name) self.course_path = '/courses/MITx/999/Robot_Super_Course/'
self.course_url = 'https://{}/courses/MITx/999/Robot_Super_Course/'.format(self.site_name)
# uncomment to enable enable printing of large diffs # uncomment to enable enable printing of large diffs
# from failed assertions in the event of a test failure. # from failed assertions in the event of a test failure.
...@@ -424,9 +425,13 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -424,9 +425,13 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
# Check the outbox # Check the outbox
self.assertEqual(len(mail.outbox), 0) self.assertEqual(len(mail.outbox), 0)
def test_enroll_with_email(self): @ddt.data('http', 'https')
def test_enroll_with_email(self, protocol):
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notenrolled_student.email, 'action': 'enroll', 'email_students': True}) params = {'identifiers': self.notenrolled_student.email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
print "type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email)) print "type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -472,15 +477,18 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -472,15 +477,18 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
"at edx.org by a member of the course staff. " "at edx.org by a member of the course staff. "
"The course should now appear on your edx.org dashboard.\n\n" "The course should now appear on your edx.org dashboard.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"{course_url}\n\n----\n" "{proto}://{site}{course_path}\n\n----\n"
"This email was automatically sent from edx.org to NotEnrolled Student".format( "This email was automatically sent from edx.org to NotEnrolled Student".format(
course_url=self.course_url proto=protocol, site=self.site_name, course_path=self.course_path
) )
) )
def test_enroll_with_email_not_registered(self): @ddt.data('http', 'https')
def test_enroll_with_email_not_registered(self, protocol):
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}) params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# Check the outbox # Check the outbox
...@@ -492,34 +500,41 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -492,34 +500,41 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n" "Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
"To finish your registration, please visit {registration_url} and fill out the registration form " "To finish your registration, please visit {proto}://{site}/register and fill out the "
"making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n" "registration form making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
"Once you have registered and activated your account, " "Once you have registered and activated your account, "
"visit {about_url} to join the course.\n\n----\n" "visit {proto}://{site}{about_path} to join the course.\n\n----\n"
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format( "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
registration_url=self.registration_url, about_url=self.about_url proto=protocol, site=self.site_name, about_path=self.about_path
) )
) )
@ddt.data('http', 'https')
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True}) @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_enroll_email_not_registered_mktgsite(self): def test_enroll_email_not_registered_mktgsite(self, protocol):
# Try with marketing site enabled
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}) params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n" "Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
"To finish your registration, please visit https://edx.org/register and fill out the registration form " "To finish your registration, please visit {proto}://{site}/register and fill out the registration form "
"making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n" "making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
"You can then enroll in Robot Super Course.\n\n----\n" "You can then enroll in Robot Super Course.\n\n----\n"
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org" "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
proto=protocol, site=self.site_name
)
) )
def test_enroll_with_email_not_registered_autoenroll(self): @ddt.data('http', 'https')
def test_enroll_with_email_not_registered_autoenroll(self, protocol):
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True, 'auto_enroll': True}) params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True, 'auto_enroll': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
print "type(self.notregistered_email): {}".format(type(self.notregistered_email)) print "type(self.notregistered_email): {}".format(type(self.notregistered_email))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -532,11 +547,11 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -532,11 +547,11 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n" "Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
"To finish your registration, please visit {registration_url} and fill out the registration form " "To finish your registration, please visit {proto}://{site}/register and fill out the registration form "
"making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n" "making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
"Once you have registered and activated your account, you will see Robot Super Course listed on your dashboard.\n\n----\n" "Once you have registered and activated your account, you will see Robot Super Course listed on your dashboard.\n\n----\n"
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format( "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
registration_url=self.registration_url proto=protocol, site=self.site_name
) )
) )
...@@ -675,12 +690,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -675,12 +690,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
"This email was automatically sent from edx.org to robot-allowed@robot.org" "This email was automatically sent from edx.org to robot-allowed@robot.org"
) )
@ddt.data('http', 'https')
@patch('instructor.enrollment.uses_shib') @patch('instructor.enrollment.uses_shib')
def test_enroll_with_email_not_registered_with_shib(self, mock_uses_shib): def test_enroll_with_email_not_registered_with_shib(self, protocol, mock_uses_shib):
mock_uses_shib.return_value = True mock_uses_shib.return_value = True
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}) params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# Check the outbox # Check the outbox
...@@ -693,9 +711,9 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -693,9 +711,9 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n" "Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
"To access the course visit {about_url} and register for the course.\n\n----\n" "To access the course visit {proto}://{site}{about_path} and register for the course.\n\n----\n"
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format( "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
about_url=self.about_url proto=protocol, site=self.site_name, about_path=self.about_path
) )
) )
...@@ -717,13 +735,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -717,13 +735,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org" "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org"
) )
@ddt.data('http', 'https')
@patch('instructor.enrollment.uses_shib') @patch('instructor.enrollment.uses_shib')
def test_enroll_with_email_not_registered_with_shib_autoenroll(self, mock_uses_shib): def test_enroll_with_email_not_registered_with_shib_autoenroll(self, protocol, mock_uses_shib):
mock_uses_shib.return_value = True mock_uses_shib.return_value = True
url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('students_update_enrollment', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True, 'auto_enroll': True}) params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True, 'auto_enroll': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
print "type(self.notregistered_email): {}".format(type(self.notregistered_email)) print "type(self.notregistered_email): {}".format(type(self.notregistered_email))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -737,13 +757,14 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -737,13 +757,14 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n" "Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
"To access the course visit {course_url} and login.\n\n----\n" "To access the course visit {proto}://{site}{course_path} and login.\n\n----\n"
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format( "This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
course_url=self.course_url proto=protocol, site=self.site_name, course_path=self.course_path
) )
) )
@ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase): class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" """
...@@ -773,7 +794,8 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe ...@@ -773,7 +794,8 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
'SITE_NAME', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
self.about_url = 'https://{}/courses/MITx/999/Robot_Super_Course/about'.format(self.site_name) self.about_path = '/courses/MITx/999/Robot_Super_Course/about'
self.course_path = '/courses/MITx/999/Robot_Super_Course/'
# uncomment to enable enable printing of large diffs # uncomment to enable enable printing of large diffs
# from failed assertions in the event of a test failure. # from failed assertions in the event of a test failure.
...@@ -848,9 +870,12 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe ...@@ -848,9 +870,12 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
self.add_notenrolled(response, self.notenrolled_student.username) self.add_notenrolled(response, self.notenrolled_student.username)
self.assertTrue(CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id))
def test_add_notenrolled_with_email(self): @ddt.data('http', 'https')
def test_add_notenrolled_with_email(self, protocol):
url = reverse('bulk_beta_modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('bulk_beta_modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get(url, {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True}) params = {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.get(url, params, **environ)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTrue(CourseBetaTesterRole(self.course.id).has_user(self.notenrolled_student)) self.assertTrue(CourseBetaTesterRole(self.course.id).has_user(self.notenrolled_student))
...@@ -877,23 +902,25 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe ...@@ -877,23 +902,25 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
u"Dear {0}\n\nYou have been invited to be a beta tester " u"Dear {student_name}\n\nYou have been invited to be a beta tester "
"for Robot Super Course at edx.org by a member of the course staff.\n\n" "for Robot Super Course at edx.org by a member of the course staff.\n\n"
"Visit {1} to join " "Visit {proto}://{site}{about_path} to join "
"the course and begin the beta test.\n\n----\n" "the course and begin the beta test.\n\n----\n"
"This email was automatically sent from edx.org to {2}".format( "This email was automatically sent from edx.org to {student_email}".format(
self.notenrolled_student.profile.name, student_name=self.notenrolled_student.profile.name,
self.about_url, student_email=self.notenrolled_student.email,
self.notenrolled_student.email proto=protocol,
site=self.site_name,
about_path=self.about_path
) )
) )
def test_add_notenrolled_with_email_autoenroll(self): @ddt.data('http', 'https')
def test_add_notenrolled_with_email_autoenroll(self, protocol):
url = reverse('bulk_beta_modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()}) url = reverse('bulk_beta_modify_access', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.get( params = {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True, 'auto_enroll': True}
url, environ = {'wsgi.url_scheme': protocol}
{'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True, 'auto_enroll': True} response = self.client.get(url, params, **environ)
)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTrue(CourseBetaTesterRole(self.course.id).has_user(self.notenrolled_student)) self.assertTrue(CourseBetaTesterRole(self.course.id).has_user(self.notenrolled_student))
...@@ -920,13 +947,16 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe ...@@ -920,13 +947,16 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
u"Dear {0}\n\nYou have been invited to be a beta tester " u"Dear {student_name}\n\nYou have been invited to be a beta tester "
"for Robot Super Course at edx.org by a member of the course staff.\n\n" "for Robot Super Course at edx.org by a member of the course staff.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"https://edx.org/courses/MITx/999/Robot_Super_Course/\n\n----\n" "{proto}://{site}{course_path}\n\n----\n"
"This email was automatically sent from edx.org to {1}".format( "This email was automatically sent from edx.org to {student_email}".format(
self.notenrolled_student.profile.name, student_name=self.notenrolled_student.profile.name,
self.notenrolled_student.email student_email=self.notenrolled_student.email,
proto=protocol,
site=self.site_name,
course_path=self.course_path
) )
) )
...@@ -944,7 +974,7 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe ...@@ -944,7 +974,7 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
"Visit edx.org to enroll in the course and begin the beta test.\n\n----\n" "Visit edx.org to enroll in the course and begin the beta test.\n\n----\n"
"This email was automatically sent from edx.org to {1}".format( "This email was automatically sent from edx.org to {1}".format(
self.notenrolled_student.profile.name, self.notenrolled_student.profile.name,
self.notenrolled_student.email self.notenrolled_student.email,
) )
) )
......
...@@ -3,6 +3,7 @@ Unit tests for enrollment methods in views.py ...@@ -3,6 +3,7 @@ Unit tests for enrollment methods in views.py
""" """
import ddt
from mock import patch from mock import patch
from django.test.utils import override_settings from django.test.utils import override_settings
...@@ -20,6 +21,7 @@ from django.core import mail ...@@ -20,6 +21,7 @@ from django.core import mail
USER_COUNT = 4 USER_COUNT = 4
@ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase): class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" """
...@@ -189,7 +191,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -189,7 +191,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
cleaned_string, cleaned_string_lc = get_and_clean_student_list(string) cleaned_string, cleaned_string_lc = get_and_clean_student_list(string)
self.assertEqual(cleaned_string, ['abc@test.com', 'def@test.com', 'ghi@test.com', 'jkl@test.com', 'mno@test.com']) self.assertEqual(cleaned_string, ['abc@test.com', 'def@test.com', 'ghi@test.com', 'jkl@test.com', 'mno@test.com'])
def test_enrollment_email_on(self): @ddt.data('http', 'https')
def test_enrollment_email_on(self, protocol):
""" """
Do email on enroll test Do email on enroll test
""" """
...@@ -200,7 +203,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -200,7 +203,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
UserFactory.create(username="student3_0", email="student3_0@test.com", first_name='Autoenrolled') UserFactory.create(username="student3_0", email="student3_0@test.com", first_name='Autoenrolled')
url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()}) url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
response = self.client.post(url, {'action': 'Enroll multiple students', 'multiple_students': 'student3_0@test.com, student3_1@test.com, student3_2@test.com', 'auto_enroll': 'on', 'email_students': 'on'}) params = {'action': 'Enroll multiple students', 'multiple_students': 'student3_0@test.com, student3_1@test.com, student3_2@test.com', 'auto_enroll': 'on', 'email_students': 'on'}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
# Check the page output # Check the page output
self.assertContains(response, '<td>student3_0@test.com</td>') self.assertContains(response, '<td>student3_0@test.com</td>')
...@@ -221,8 +226,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -221,8 +226,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
"at edx.org by a member of the course staff. " "at edx.org by a member of the course staff. "
"The course should now appear on your edx.org dashboard.\n\n" "The course should now appear on your edx.org dashboard.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"https://edx.org/courses/MITx/999/Robot_Super_Course/\n\n" "{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n"
"----\nThis email was automatically sent from edx.org to Autoenrolled Test" "----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(protocol)
) )
self.assertEqual( self.assertEqual(
...@@ -235,12 +240,12 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -235,12 +240,12 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
"Robot Super Course at edx.org by a member of the " "Robot Super Course at edx.org by a member of the "
"course staff.\n\n" "course staff.\n\n"
"To finish your registration, please visit " "To finish your registration, please visit "
"https://edx.org/register and fill out the registration form " "{}://edx.org/register and fill out the registration form "
"making sure to use student3_1@test.com in the E-mail field.\n" "making sure to use student3_1@test.com in the E-mail field.\n"
"Once you have registered and activated your account, you will " "Once you have registered and activated your account, you will "
"see Robot Super Course listed on your dashboard.\n\n" "see Robot Super Course listed on your dashboard.\n\n"
"----\nThis email was automatically sent from edx.org to " "----\nThis email was automatically sent from edx.org to "
"student3_1@test.com" "student3_1@test.com".format(protocol)
) )
def test_unenrollment_email_on(self): def test_unenrollment_email_on(self):
...@@ -291,8 +296,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -291,8 +296,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
send_mail_ret = send_mail_to_student('student0@test.com', d) send_mail_ret = send_mail_to_student('student0@test.com', d)
self.assertFalse(send_mail_ret) self.assertFalse(send_mail_ret)
@ddt.data('http', 'https')
@patch('instructor.views.legacy.uses_shib') @patch('instructor.views.legacy.uses_shib')
def test_enrollment_email_on_shib_on(self, mock_uses_shib): def test_enrollment_email_on_shib_on(self, protocol, mock_uses_shib):
# Do email on enroll, shibboleth on test # Do email on enroll, shibboleth on test
course = self.course course = self.course
...@@ -302,7 +308,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -302,7 +308,9 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
UserFactory.create(username="student5_0", email="student5_0@test.com", first_name="ShibTest", last_name="Enrolled") UserFactory.create(username="student5_0", email="student5_0@test.com", first_name="ShibTest", last_name="Enrolled")
url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()}) url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
response = self.client.post(url, {'action': 'Enroll multiple students', 'multiple_students': 'student5_0@test.com, student5_1@test.com', 'auto_enroll': 'on', 'email_students': 'on'}) params = {'action': 'Enroll multiple students', 'multiple_students': 'student5_0@test.com, student5_1@test.com', 'auto_enroll': 'on', 'email_students': 'on'}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
# Check the page output # Check the page output
self.assertContains(response, '<td>student5_0@test.com</td>') self.assertContains(response, '<td>student5_0@test.com</td>')
...@@ -322,8 +330,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -322,8 +330,8 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
"at edx.org by a member of the course staff. " "at edx.org by a member of the course staff. "
"The course should now appear on your edx.org dashboard.\n\n" "The course should now appear on your edx.org dashboard.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"https://edx.org/courses/MITx/999/Robot_Super_Course/\n\n" "{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n"
"----\nThis email was automatically sent from edx.org to ShibTest Enrolled" "----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(protocol)
) )
self.assertEqual( self.assertEqual(
...@@ -335,7 +343,7 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -335,7 +343,7 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
"Dear student,\n\nYou have been invited to join " "Dear student,\n\nYou have been invited to join "
"Robot Super Course at edx.org by a member of the " "Robot Super Course at edx.org by a member of the "
"course staff.\n\n" "course staff.\n\n"
"To access the course visit https://edx.org/courses/MITx/999/Robot_Super_Course/ and login.\n\n" "To access the course visit {}://edx.org/courses/MITx/999/Robot_Super_Course/ and login.\n\n"
"----\nThis email was automatically sent from edx.org to " "----\nThis email was automatically sent from edx.org to "
"student5_1@test.com" "student5_1@test.com".format(protocol)
) )
...@@ -257,7 +257,7 @@ def students_update_enrollment(request, course_id): ...@@ -257,7 +257,7 @@ def students_update_enrollment(request, course_id):
email_params = {} email_params = {}
if email_students: if email_students:
course = get_course_by_id(course_id) course = get_course_by_id(course_id)
email_params = get_email_params(course, auto_enroll) email_params = get_email_params(course, auto_enroll, secure=request.is_secure())
results = [] results = []
for identifier in identifiers: for identifier in identifiers:
...@@ -348,7 +348,8 @@ def bulk_beta_modify_access(request, course_id): ...@@ -348,7 +348,8 @@ def bulk_beta_modify_access(request, course_id):
email_params = {} email_params = {}
if email_students: if email_students:
email_params = get_email_params(course, auto_enroll=auto_enroll) secure = request.is_secure()
email_params = get_email_params(course, auto_enroll=auto_enroll, secure=secure)
for identifier in identifiers: for identifier in identifiers:
try: try:
......
...@@ -813,7 +813,8 @@ def instructor_dashboard(request, course_id): ...@@ -813,7 +813,8 @@ def instructor_dashboard(request, course_id):
students = request.POST.get('multiple_students', '') students = request.POST.get('multiple_students', '')
auto_enroll = bool(request.POST.get('auto_enroll')) auto_enroll = bool(request.POST.get('auto_enroll'))
email_students = bool(request.POST.get('email_students')) email_students = bool(request.POST.get('email_students'))
ret = _do_enroll_students(course, course_key, students, auto_enroll=auto_enroll, email_students=email_students, is_shib_course=is_shib_course) secure = request.is_secure()
ret = _do_enroll_students(course, course_key, students, secure=secure, auto_enroll=auto_enroll, email_students=email_students, is_shib_course=is_shib_course)
datatable = ret['datatable'] datatable = ret['datatable']
elif action == 'Unenroll multiple students': elif action == 'Unenroll multiple students':
...@@ -839,7 +840,8 @@ def instructor_dashboard(request, course_id): ...@@ -839,7 +840,8 @@ def instructor_dashboard(request, course_id):
if not 'List' in action: if not 'List' in action:
students = ','.join([x['email'] for x in datatable['retdata']]) students = ','.join([x['email'] for x in datatable['retdata']])
overload = 'Overload' in action overload = 'Overload' in action
ret = _do_enroll_students(course, course_key, students, overload=overload) secure = request.is_secure()
ret = _do_enroll_students(course, course_key, students, secure=secure, overload=overload)
datatable = ret['datatable'] datatable = ret['datatable']
#---------------------------------------- #----------------------------------------
...@@ -1439,7 +1441,7 @@ def grade_summary(request, course_key): ...@@ -1439,7 +1441,7 @@ def grade_summary(request, course_key):
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# enrollment # enrollment
def _do_enroll_students(course, course_key, students, overload=False, auto_enroll=False, email_students=False, is_shib_course=False): def _do_enroll_students(course, course_key, students, secure=False, overload=False, auto_enroll=False, email_students=False, is_shib_course=False):
""" """
Do the actual work of enrolling multiple students, presented as a string Do the actual work of enrolling multiple students, presented as a string
of emails separated by commas or returns of emails separated by commas or returns
...@@ -1468,26 +1470,30 @@ def _do_enroll_students(course, course_key, students, overload=False, auto_enrol ...@@ -1468,26 +1470,30 @@ def _do_enroll_students(course, course_key, students, overload=False, auto_enrol
ceaset.delete() ceaset.delete()
if email_students: if email_students:
protocol = 'https' if secure else 'http'
stripped_site_name = microsite.get_value( stripped_site_name = microsite.get_value(
'SITE_NAME', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
# TODO: Use request.build_absolute_uri rather than 'https://{}{}'.format # TODO: Use request.build_absolute_uri rather than '{proto}://{site}{path}'.format
# and check with the Services team that this works well with microsites # and check with the Services team that this works well with microsites
registration_url = 'https://{}{}'.format( registration_url = '{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('student.views.register_user') site=stripped_site_name,
path=reverse('student.views.register_user')
) )
course_url = 'https://{}{}'.format( course_url = '{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('course_root', kwargs={'course_id': course_key.to_deprecated_string()}) site=stripped_site_name,
path=reverse('course_root', kwargs={'course_id': course_key.to_deprecated_string()})
) )
# We can't get the url to the course's About page if the marketing site is enabled. # We can't get the url to the course's About page if the marketing site is enabled.
course_about_url = None course_about_url = None
if not settings.FEATURES.get('ENABLE_MKTG_SITE', False): if not settings.FEATURES.get('ENABLE_MKTG_SITE', False):
course_about_url = u'https://{}{}'.format( course_about_url = u'{proto}://{site}{path}'.format(
stripped_site_name, proto=protocol,
reverse('about_course', kwargs={'course_id': course_key.to_deprecated_string()}) site=stripped_site_name,
path=reverse('about_course', kwargs={'course_id': course_key.to_deprecated_string()})
) )
# Composition of email # Composition of email
......
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