Commit b96a8bf6 by Peter Fogg

Allow searching enrollments by email as well as username.

This brings the enrollment support tool's UI in line with the other
support tools.
parent bd1052cb
......@@ -6,7 +6,7 @@
type="text"
name="query"
value="<%- user %>"
placeholder="<%- gettext('Username') %>">
placeholder="<%- gettext('Username or email address') %>">
</input>
<input type="submit" value="<%- gettext('Search') %>" class="btn-disable-on-submit"></input>
</form>
......
......@@ -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,
......
......@@ -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<username>[\w.@+-]+)?$', views.EnrollmentSupportListView.as_view(), name="enrollment_list"),
url(
r'^enrollment/(?P<username_or_email>[\w.@+-]+)?$',
views.EnrollmentSupportListView.as_view(),
name="enrollment_list"
),
)
......@@ -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,
......
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