diff --git a/lms/djangoapps/support/static/support/templates/enrollment.underscore b/lms/djangoapps/support/static/support/templates/enrollment.underscore
index b2553d1d56..f4baabacca 100644
--- a/lms/djangoapps/support/static/support/templates/enrollment.underscore
+++ b/lms/djangoapps/support/static/support/templates/enrollment.underscore
@@ -6,7 +6,7 @@
type="text"
name="query"
value="<%- user %>"
- placeholder="<%- gettext('Username') %>">
+ placeholder="<%- gettext('Username or email address') %>">
diff --git a/lms/djangoapps/support/tests/test_views.py b/lms/djangoapps/support/tests/test_views.py
index 3114a0b3af..d637821451 100644
--- a/lms/djangoapps/support/tests/test_views.py
+++ b/lms/djangoapps/support/tests/test_views.py
@@ -170,7 +170,7 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
CourseEnrollmentFactory.create(mode=CourseMode.AUDIT, user=self.student, course_id=self.course.id) # pylint: disable=no-member
- self.url = reverse('support:enrollment_list', kwargs={'username': self.student.username})
+ self.url = reverse('support:enrollment_list', kwargs={'username_or_email': self.student.username})
def assert_enrollment(self, mode):
"""
@@ -179,8 +179,13 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
enrollment = CourseEnrollment.get_enrollment(self.student, self.course.id) # pylint: disable=no-member
self.assertEqual(enrollment.mode, mode)
- def test_get_enrollments(self):
- response = self.client.get(self.url)
+ @ddt.data('username', 'email')
+ def test_get_enrollments(self, search_string_type):
+ url = reverse(
+ 'support:enrollment_list',
+ kwargs={'username_or_email': getattr(self.student, search_string_type)}
+ )
+ response = self.client.get(url)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
self.assertEqual(len(data), 1)
@@ -212,9 +217,14 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
'reason': 'Financial Assistance',
}, json.loads(response.content)[0]['manual_enrollment'])
- def test_change_enrollment(self):
+ @ddt.data('username', 'email')
+ def test_change_enrollment(self, search_string_type):
self.assertIsNone(ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email))
- response = self.client.post(self.url, data={
+ url = reverse(
+ 'support:enrollment_list',
+ kwargs={'username_or_email': getattr(self.student, search_string_type)}
+ )
+ response = self.client.post(url, data={
'course_id': unicode(self.course.id), # pylint: disable=no-member
'old_mode': CourseMode.AUDIT,
'new_mode': CourseMode.VERIFIED,
diff --git a/lms/djangoapps/support/urls.py b/lms/djangoapps/support/urls.py
index d972caf0cf..50ebe6021c 100644
--- a/lms/djangoapps/support/urls.py
+++ b/lms/djangoapps/support/urls.py
@@ -11,5 +11,9 @@ urlpatterns = patterns(
url(r'^certificates/?$', views.CertificatesSupportView.as_view(), name="certificates"),
url(r'^refund/?$', views.RefundSupportView.as_view(), name="refund"),
url(r'^enrollment/?$', views.EnrollmentSupportView.as_view(), name="enrollment"),
- url(r'^enrollment/(?P[\w.@+-]+)?$', views.EnrollmentSupportListView.as_view(), name="enrollment_list"),
+ url(
+ r'^enrollment/(?P[\w.@+-]+)?$',
+ views.EnrollmentSupportListView.as_view(),
+ name="enrollment_list"
+ ),
)
diff --git a/lms/djangoapps/support/views/enrollments.py b/lms/djangoapps/support/views/enrollments.py
index 5efc5a4fdc..46420606a1 100644
--- a/lms/djangoapps/support/views/enrollments.py
+++ b/lms/djangoapps/support/views/enrollments.py
@@ -4,6 +4,7 @@ Support tool for changing course enrollments.
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db import transaction
+from django.db.models import Q
from django.http import HttpResponseBadRequest
from django.utils.decorators import method_decorator
from django.views.generic import View
@@ -45,12 +46,17 @@ class EnrollmentSupportListView(GenericAPIView):
"""
@method_decorator(require_support_permission)
- def get(self, request, username):
+ def get(self, request, username_or_email):
"""
Returns a list of enrollments for the given user, along with
information about previous manual enrollment changes.
"""
- enrollments = get_enrollments(username)
+ try:
+ user = User.objects.get(Q(username=username_or_email) | Q(email=username_or_email))
+ except User.DoesNotExist:
+ return JsonResponse([])
+
+ enrollments = get_enrollments(user.username)
for enrollment in enrollments:
# Folds the course_details field up into the main JSON object.
enrollment.update(**enrollment.pop('course_details'))
@@ -62,28 +68,29 @@ class EnrollmentSupportListView(GenericAPIView):
return JsonResponse(enrollments)
@method_decorator(require_support_permission)
- def post(self, request, username):
+ def post(self, request, username_or_email):
"""Allows support staff to alter a user's enrollment."""
try:
+ user = User.objects.get(Q(username=username_or_email) | Q(email=username_or_email))
course_id = request.data['course_id']
course_key = CourseKey.from_string(course_id)
old_mode = request.data['old_mode']
new_mode = request.data['new_mode']
reason = request.data['reason']
- enrollment = CourseEnrollment.objects.get(course_id=course_key, user__username=username)
+ enrollment = CourseEnrollment.objects.get(user=user, course_id=course_key)
if enrollment.mode != old_mode:
return HttpResponseBadRequest(u'User {username} is not enrolled with mode {old_mode}.'.format(
- username=username,
+ username=user.username,
old_mode=old_mode
))
except KeyError as err:
return HttpResponseBadRequest(u'The field {} is required.'.format(err.message))
except InvalidKeyError:
return HttpResponseBadRequest(u'Could not parse course key.')
- except CourseEnrollment.DoesNotExist:
+ except (CourseEnrollment.DoesNotExist, User.DoesNotExist):
return HttpResponseBadRequest(
u'Could not find enrollment for user {username} in course {course}.'.format(
- username=username,
+ username=username_or_email,
course=unicode(course_key)
)
)
@@ -91,7 +98,7 @@ class EnrollmentSupportListView(GenericAPIView):
# Wrapped in a transaction so that we can be sure the
# ManualEnrollmentAudit record is always created correctly.
with transaction.atomic():
- update_enrollment(username, course_id, mode=new_mode)
+ update_enrollment(user.username, course_id, mode=new_mode)
manual_enrollment = ManualEnrollmentAudit.create_manual_enrollment_audit(
request.user,
enrollment.user.email,