Commit da8103d2 by Will Daly

Expose course start/end date in the enrollment API

parent 04ca163f
...@@ -36,7 +36,10 @@ def get_enrollments(user_id): ...@@ -36,7 +36,10 @@ def get_enrollments(user_id):
"user": "Bob", "user": "Bob",
"course": { "course": {
"course_id": "edX/DemoX/2014T2", "course_id": "edX/DemoX/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -49,7 +52,6 @@ def get_enrollments(user_id): ...@@ -49,7 +52,6 @@ def get_enrollments(user_id):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": False "invite_only": False
} }
}, },
...@@ -60,7 +62,10 @@ def get_enrollments(user_id): ...@@ -60,7 +62,10 @@ def get_enrollments(user_id):
"user": "Bob", "user": "Bob",
"course": { "course": {
"course_id": "edX/edX-Insider/2014T2", "course_id": "edX/edX-Insider/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -73,7 +78,6 @@ def get_enrollments(user_id): ...@@ -73,7 +78,6 @@ def get_enrollments(user_id):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": True "invite_only": True
} }
} }
...@@ -104,7 +108,10 @@ def get_enrollment(user_id, course_id): ...@@ -104,7 +108,10 @@ def get_enrollment(user_id, course_id):
"user": "Bob", "user": "Bob",
"course": { "course": {
"course_id": "edX/DemoX/2014T2", "course_id": "edX/DemoX/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -117,7 +124,6 @@ def get_enrollment(user_id, course_id): ...@@ -117,7 +124,6 @@ def get_enrollment(user_id, course_id):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": False "invite_only": False
} }
} }
...@@ -151,7 +157,10 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True): ...@@ -151,7 +157,10 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
"user": "Bob", "user": "Bob",
"course": { "course": {
"course_id": "edX/DemoX/2014T2", "course_id": "edX/DemoX/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -164,7 +173,6 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True): ...@@ -164,7 +173,6 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": False "invite_only": False
} }
} }
...@@ -196,7 +204,10 @@ def update_enrollment(user_id, course_id, mode=None, is_active=None): ...@@ -196,7 +204,10 @@ def update_enrollment(user_id, course_id, mode=None, is_active=None):
"user": "Bob", "user": "Bob",
"course": { "course": {
"course_id": "edX/DemoX/2014T2", "course_id": "edX/DemoX/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -209,7 +220,6 @@ def update_enrollment(user_id, course_id, mode=None, is_active=None): ...@@ -209,7 +220,6 @@ def update_enrollment(user_id, course_id, mode=None, is_active=None):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": False "invite_only": False
} }
} }
...@@ -239,7 +249,10 @@ def get_course_enrollment_details(course_id): ...@@ -239,7 +249,10 @@ def get_course_enrollment_details(course_id):
>>> get_course_enrollment_details("edX/DemoX/2014T2") >>> get_course_enrollment_details("edX/DemoX/2014T2")
{ {
"course_id": "edX/DemoX/2014T2", "course_id": "edX/DemoX/2014T2",
"enrollment_end": 2014-12-20T20:18:00Z, "enrollment_end": "2014-12-20T20:18:00Z",
"enrollment_start": "2014-10-15T20:18:00Z",
"course_start": "2015-02-03T00:00:00Z",
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "honor",
...@@ -252,7 +265,6 @@ def get_course_enrollment_details(course_id): ...@@ -252,7 +265,6 @@ def get_course_enrollment_details(course_id):
"sku": null "sku": null
} }
], ],
"enrollment_start": 2014-10-15T20:18:00Z,
"invite_only": False "invite_only": False
} }
......
...@@ -46,6 +46,8 @@ class CourseField(serializers.RelatedField): ...@@ -46,6 +46,8 @@ class CourseField(serializers.RelatedField):
"course_id": course_id, "course_id": course_id,
"enrollment_start": course.enrollment_start, "enrollment_start": course.enrollment_start,
"enrollment_end": course.enrollment_end, "enrollment_end": course.enrollment_end,
"course_start": course.start,
"course_end": course.end,
"invite_only": course.invitation_only, "invite_only": course.invitation_only,
"course_modes": course_modes, "course_modes": course_modes,
} }
......
...@@ -4,6 +4,7 @@ Tests for user enrollment. ...@@ -4,6 +4,7 @@ Tests for user enrollment.
import ddt import ddt
import json import json
import unittest import unittest
import datetime
from mock import patch from mock import patch
from django.test import Client from django.test import Client
...@@ -253,6 +254,46 @@ class EnrollmentTest(ModuleStoreTestCase, APITestCase): ...@@ -253,6 +254,46 @@ class EnrollmentTest(ModuleStoreTestCase, APITestCase):
self.assertEqual(mode['sku'], '123') self.assertEqual(mode['sku'], '123')
self.assertEqual(mode['name'], CourseMode.HONOR) self.assertEqual(mode['name'], CourseMode.HONOR)
@ddt.data(
# NOTE: Studio requires a start date, but this is not
# enforced at the data layer, so we need to handle the case
# in which no dates are specified.
(None, None, None, None),
(datetime.datetime(2015, 1, 2, 3, 4, 5), None, "2015-01-02T03:04:05Z", None),
(None, datetime.datetime(2015, 1, 2, 3, 4, 5), None, "2015-01-02T03:04:05Z"),
(datetime.datetime(2014, 6, 7, 8, 9, 10), datetime.datetime(2015, 1, 2, 3, 4, 5), "2014-06-07T08:09:10Z", "2015-01-02T03:04:05Z"),
)
@ddt.unpack
def test_get_course_details_course_dates(self, start_datetime, end_datetime, expected_start, expected_end):
course = CourseFactory.create(start=start_datetime, end=end_datetime)
self._create_enrollment(course_id=unicode(course.id))
# Check course details
url = reverse('courseenrollmentdetails', kwargs={"course_id": unicode(course.id)})
resp = self.client.get(url)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
data = json.loads(resp.content)
self.assertEqual(data['course_start'], expected_start)
self.assertEqual(data['course_end'], expected_end)
# Check enrollment course details
url = reverse('courseenrollment', kwargs={"course_id": unicode(course.id)})
resp = self.client.get(url)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
data = json.loads(resp.content)
self.assertEqual(data['course_details']['course_start'], expected_start)
self.assertEqual(data['course_details']['course_end'], expected_end)
# Check enrollment list course details
resp = self.client.get(reverse('courseenrollments'))
self.assertEqual(resp.status_code, status.HTTP_200_OK)
data = json.loads(resp.content)
self.assertEqual(data[0]['course_details']['course_start'], expected_start)
self.assertEqual(data[0]['course_details']['course_end'], expected_end)
def test_with_invalid_course_id(self): def test_with_invalid_course_id(self):
self._create_enrollment(course_id='entirely/fake/course', expected_status=status.HTTP_400_BAD_REQUEST) self._create_enrollment(course_id='entirely/fake/course', expected_status=status.HTTP_400_BAD_REQUEST)
......
...@@ -81,7 +81,13 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn): ...@@ -81,7 +81,13 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
* course_id: The unique identifier for the course. * course_id: The unique identifier for the course.
* enrollment_end: The date and time after which users cannot enroll for the course. * enrollment_start: The date and time that users can begin enrolling in the course. If null, enrollment opens immediately when the course is created.
* enrollment_end: The date and time after which users cannot enroll for the course. If null, the enrollment period never ends.
* course_start: The date and time at which the course opens. If null, the course opens immediately when created.
* course_end: The date and time at which the course closes. If null, the course never ends.
* course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes: * course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes:
...@@ -93,8 +99,6 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn): ...@@ -93,8 +99,6 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
* expiration_datetime: The date and time after which users cannot enroll in the course in this mode. * expiration_datetime: The date and time after which users cannot enroll in the course in this mode.
* description: A description of this mode. * description: A description of this mode.
* enrollment_start: The date and time that users can begin enrolling in the course.
* invite_only: Whether students must be invited to enroll in the course; true or false. * invite_only: Whether students must be invited to enroll in the course; true or false.
* user: The ID of the user. * user: The ID of the user.
...@@ -164,7 +168,13 @@ class EnrollmentCourseDetailView(APIView): ...@@ -164,7 +168,13 @@ class EnrollmentCourseDetailView(APIView):
* course_id: The unique identifier of the course. * course_id: The unique identifier of the course.
* enrollment_end: The date and time after which users cannot enroll for the course. * enrollment_start: The date and time that users can begin enrolling in the course. If null, enrollment opens immediately when the course is created.
* enrollment_end: The date and time after which users cannot enroll for the course. If null, the enrollment period never ends.
* course_start: The date and time at which the course opens. If null, the course opens immediately when created.
* course_end: The date and time at which the course closes. If null, the course never ends.
* course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes: * course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes:
...@@ -176,8 +186,6 @@ class EnrollmentCourseDetailView(APIView): ...@@ -176,8 +186,6 @@ class EnrollmentCourseDetailView(APIView):
* expiration_datetime: The date and time after which users cannot enroll in the course in this mode. * expiration_datetime: The date and time after which users cannot enroll in the course in this mode.
* description: A description of this mode. * description: A description of this mode.
* enrollment_start: The date and time that users can begin enrolling in the course.
* invite_only: Whether students must be invited to enroll in the course; true or false. * invite_only: Whether students must be invited to enroll in the course; true or false.
""" """
...@@ -264,7 +272,13 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -264,7 +272,13 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
* course_id: The unique identifier for the course. * course_id: The unique identifier for the course.
* enrollment_end: The date and time after which users cannot enroll for the course. * enrollment_start: The date and time that users can begin enrolling in the course. If null, enrollment opens immediately when the course is created.
* enrollment_end: The date and time after which users cannot enroll for the course. If null, the enrollment period never ends.
* course_start: The date and time at which the course opens. If null, the course opens immediately when created.
* course_end: The date and time at which the course closes. If null, the course never ends.
* course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes: * course_modes: An array of data about the enrollment modes supported for the course. Each enrollment mode collection includes:
...@@ -276,7 +290,6 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -276,7 +290,6 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
* expiration_datetime: The date and time after which users cannot enroll in the course in this mode. * expiration_datetime: The date and time after which users cannot enroll in the course in this mode.
* description: A description of this mode. * description: A description of this mode.
* enrollment_start: The date and time that users can begin enrolling in the course.
* invite_only: Whether students must be invited to enroll in the course; true or false. * invite_only: Whether students must be invited to enroll in the course; true or false.
......
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