EDUCATOR-4361 Add PUT api endpoint to the edx-plaform program course enrollment view

This commit is contained in:
Simon Chen
2019-06-24 15:40:06 -04:00
parent de20d7414c
commit a86e8d4f19
2 changed files with 83 additions and 17 deletions

View File

@@ -574,16 +574,17 @@ class CourseEnrollmentPostTests(BaseCourseEnrollmentTestsMixin, APITestCase):
@ddt.ddt
class CourseEnrollmentPatchTests(BaseCourseEnrollmentTestsMixin, APITestCase):
""" Tests for course enrollment PATCH """
def request(self, path, data):
return self.client.patch(path, data, format='json')
class CourseEnrollmentModificationTestBase(BaseCourseEnrollmentTestsMixin):
"""
Base class for both the PATCH and PUT endpoints for Course Enrollment API
Children needs to implement assert_user_not_enrolled_test_result and
setup_change_test_data
"""
def test_207_multistatus(self):
self.create_program_and_course_enrollments('learner-1')
post_data = [self.learner_enrollment("learner-1"), self.learner_enrollment("learner-2")]
response = self.request(self.default_url, post_data)
mod_data = [self.learner_enrollment("learner-1"), self.learner_enrollment("learner-2")]
response = self.request(self.default_url, mod_data)
self.assertEqual(207, response.status_code)
self.assertDictEqual(
{'learner-1': CourseStatuses.ACTIVE, 'learner-2': CourseStatuses.NOT_IN_PROGRAM},
@@ -594,8 +595,13 @@ class CourseEnrollmentPatchTests(BaseCourseEnrollmentTestsMixin, APITestCase):
self.create_program_enrollment('learner-1')
patch_data = [self.learner_enrollment('learner-1')]
response = self.request(self.default_url, patch_data)
self.assertEqual(422, response.status_code)
self.assertDictEqual({'learner-1': CourseStatuses.NOT_FOUND}, response.data)
self.assert_user_not_enrolled_test_result(response)
def assert_user_not_enrolled_test_result(self, response):
pass
def setup_change_test_data(self, initial_statuses):
pass
@ddt.data(
('active', 'inactive', 'active', 'inactive'),
@@ -604,17 +610,14 @@ class CourseEnrollmentPatchTests(BaseCourseEnrollmentTestsMixin, APITestCase):
('inactive', 'inactive', 'inactive', 'inactive'),
)
def test_change_status(self, initial_statuses):
self.create_program_and_course_enrollments('learner-1', course_status=initial_statuses[0])
self.create_program_and_course_enrollments('learner-2', course_status=initial_statuses[1])
self.create_program_and_course_enrollments('learner-3', course_status=initial_statuses[2], user=None)
self.create_program_and_course_enrollments('learner-4', course_status=initial_statuses[3], user=None)
patch_data = [
self.setup_change_test_data(initial_statuses)
mod_data = [
self.learner_enrollment('learner-1', 'inactive'),
self.learner_enrollment('learner-2', 'active'),
self.learner_enrollment('learner-3', 'inactive'),
self.learner_enrollment('learner-4', 'active'),
]
response = self.request(self.default_url, patch_data)
response = self.request(self.default_url, mod_data)
self.assertEqual(200, response.status_code)
self.assertDictEqual(
{
@@ -631,6 +634,40 @@ class CourseEnrollmentPatchTests(BaseCourseEnrollmentTestsMixin, APITestCase):
self.assert_program_course_enrollment('learner-4', 'active', False)
class CourseEnrollmentPatchTests(CourseEnrollmentModificationTestBase, APITestCase):
""" Tests for course enrollment PATCH """
def request(self, path, data):
return self.client.patch(path, data, format='json')
def assert_user_not_enrolled_test_result(self, response):
self.assertEqual(422, response.status_code)
self.assertDictEqual({'learner-1': CourseStatuses.NOT_FOUND}, response.data)
def setup_change_test_data(self, initial_statuses):
self.create_program_and_course_enrollments('learner-1', course_status=initial_statuses[0])
self.create_program_and_course_enrollments('learner-2', course_status=initial_statuses[1])
self.create_program_and_course_enrollments('learner-3', course_status=initial_statuses[2], user=None)
self.create_program_and_course_enrollments('learner-4', course_status=initial_statuses[3], user=None)
class CourseEnrollmentPutTests(CourseEnrollmentModificationTestBase, APITestCase):
""" Tests for course enrollment PUT """
def request(self, path, data):
return self.client.put(path, data, format='json')
def assert_user_not_enrolled_test_result(self, response):
self.assertEqual(200, response.status_code)
self.assertDictEqual({'learner-1': CourseStatuses.ACTIVE}, response.data)
def setup_change_test_data(self, initial_statuses):
self.create_program_and_course_enrollments('learner-1', course_status=initial_statuses[0])
self.create_program_enrollment('learner-2')
self.create_program_enrollment('learner-3', user=None)
self.create_program_and_course_enrollments('learner-4', course_status=initial_statuses[3], user=None)
class ProgramCourseEnrollmentListTest(ListViewTestMixin, APITestCase):
"""
Tests for GET calls to the Program Course Enrollments API.

View File

@@ -588,13 +588,13 @@ class ProgramCourseEnrollmentsView(DeveloperErrorViewMixin, ProgramCourseRunSpec
Path: ``/api/program_enrollments/v1/programs/{program_uuid}/courses/{course_id}/enrollments/``
Accepts: [GET, POST]
Accepts: [GET, POST, PATCH, PUT]
For GET requests, the path can contain an optional `page_size?=N` query parameter.
The default page size is 100.
------------------------------------------------------------------------------------
POST
POST, PATCH, PUT
------------------------------------------------------------------------------------
**Returns**
@@ -702,6 +702,19 @@ class ProgramCourseEnrollmentsView(DeveloperErrorViewMixin, ProgramCourseRunSpec
self.modify_learner_enrollment_status
)
@verify_program_exists
@verify_course_exists_and_in_program
# pylint: disable=unused-argument
def put(self, request, program_uuid=None, course_id=None):
"""
Create or Update the program course enrollments of a list of learners
"""
return self.create_or_modify_enrollments(
request,
program_uuid,
self.create_or_update_learner_enrollment
)
def create_or_modify_enrollments(self, request, program_uuid, operation):
"""
Process a list of program course enrollment request objects
@@ -812,6 +825,22 @@ class ProgramCourseEnrollmentsView(DeveloperErrorViewMixin, ProgramCourseRunSpec
return CourseEnrollmentResponseStatuses.NOT_FOUND
return program_course_enrollment.change_status(enrollment_request['status'])
def create_or_update_learner_enrollment(self, enrollment_request, program_enrollment, program_course_enrollment):
"""
Attempts to create or update the specified user's enrollment in the given course
in the given program
"""
if program_course_enrollment is None:
# create the course enrollment
return ProgramCourseEnrollment.create_program_course_enrollment(
program_enrollment,
self.course_key,
enrollment_request['status']
)
else:
# Update course enrollment
return program_course_enrollment.change_status(enrollment_request['status'])
class ProgramCourseEnrollmentOverviewView(DeveloperErrorViewMixin, ProgramSpecificViewMixin, APIView):
"""