From 1990dc7fd89ef25719e40e9d0a60e7cfba6e9374 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 20 Jul 2017 17:56:56 -0400 Subject: [PATCH] Patch the bulk_enroll request to use a form content type Setting the content type to be form data makes Django Rest Framework v3.6.3 treat all passed JSON data as POST parameters. This is necessary because this request is forwarded on to the student_update_enrollment view, which requires all of the parameters to be passed in via POST parameters. --- .../bulk_enroll/tests/test_views.py | 26 ++++++++++++++----- lms/djangoapps/bulk_enroll/views.py | 6 +++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lms/djangoapps/bulk_enroll/tests/test_views.py b/lms/djangoapps/bulk_enroll/tests/test_views.py index 99eaac5234..f805a73bbc 100644 --- a/lms/djangoapps/bulk_enroll/tests/test_views.py +++ b/lms/djangoapps/bulk_enroll/tests/test_views.py @@ -1,6 +1,7 @@ """ Tests for the Bulk Enrollment views. """ +import ddt import json from django.conf import settings from django.contrib.auth.models import User @@ -25,6 +26,7 @@ from xmodule.modulestore.tests.factories import CourseFactory @override_settings(ENABLE_BULK_ENROLLMENT_VIEW=True) +@ddt.ddt class BulkEnrollmentTest(ModuleStoreTestCase, LoginEnrollmentTestCase, APITestCase): """ Test the bulk enrollment endpoint @@ -67,9 +69,13 @@ class BulkEnrollmentTest(ModuleStoreTestCase, LoginEnrollmentTestCase, APITestCa self.about_path = '/courses/{}/about'.format(self.course.id) self.course_path = '/courses/{}/'.format(self.course.id) - def request_bulk_enroll(self, data=None, **extra): + def request_bulk_enroll(self, data=None, use_json=False, **extra): """ Make an authenticated request to the bulk enrollment API. """ - request = self.request_factory.post(self.url, data=data, **extra) + content_type = None + if use_json: + content_type = 'application/json' + data = json.dumps(data) + request = self.request_factory.post(self.url, data=data, content_type=content_type, **extra) force_authenticate(request, user=self.staff) response = self.view(request) response.render() @@ -221,14 +227,15 @@ class BulkEnrollmentTest(ModuleStoreTestCase, LoginEnrollmentTestCase, APITestCa res_json = json.loads(response.content) self.assertEqual(res_json, expected) - def test_enroll_with_email(self): + @ddt.data(False, True) + def test_enroll_with_email(self, use_json): """ Test enrolling using a username as the identifier. """ response = self.request_bulk_enroll({ 'identifiers': self.notenrolled_student.email, 'action': 'enroll', 'email_students': False, 'courses': self.course_key, - }) + }, use_json=use_json) self.assertEqual(response.status_code, 200) # test that the user is now enrolled @@ -274,10 +281,15 @@ class BulkEnrollmentTest(ModuleStoreTestCase, LoginEnrollmentTestCase, APITestCa # Check the outbox self.assertEqual(len(mail.outbox), 0) - def test_unenroll(self): + @ddt.data(False, True) + def test_unenroll(self, use_json): """ Test unenrolling a user. """ - response = self.request_bulk_enroll({'identifiers': self.enrolled_student.email, 'action': 'unenroll', - 'email_students': False, 'courses': self.course_key, }) + response = self.request_bulk_enroll({ + 'identifiers': self.enrolled_student.email, + 'action': 'unenroll', + 'email_students': False, + 'courses': self.course_key, + }, use_json=use_json) self.assertEqual(response.status_code, 200) # test that the user is now unenrolled diff --git a/lms/djangoapps/bulk_enroll/views.py b/lms/djangoapps/bulk_enroll/views.py index fe768853aa..2a2520cad8 100644 --- a/lms/djangoapps/bulk_enroll/views.py +++ b/lms/djangoapps/bulk_enroll/views.py @@ -60,6 +60,12 @@ class BulkEnrollView(APIView): def post(self, request): serializer = BulkEnrollmentSerializer(data=request.data) if serializer.is_valid(): + # Setting the content type to be form data makes Django Rest Framework v3.6.3 treat all passed JSON data as + # POST parameters. This is necessary because this request is forwarded on to the student_update_enrollment + # view, which requires all of the parameters to be passed in via POST parameters. + metadata = request._request.META # pylint: disable=protected-access + metadata['CONTENT_TYPE'] = 'application/x-www-form-urlencoded' + response_dict = { 'auto_enroll': serializer.data.get('auto_enroll'), 'email_students': serializer.data.get('email_students'),