Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
4df2bd33
Commit
4df2bd33
authored
Apr 21, 2015
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7756 from edx/will/ecom-1408-take-two
Expose course start/end date in the enrollment API
parents
72dc5470
e065a9c9
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
91 additions
and
20 deletions
+91
-20
common/djangoapps/enrollment/api.py
+24
-12
common/djangoapps/enrollment/serializers.py
+2
-0
common/djangoapps/enrollment/tests/test_views.py
+41
-0
common/djangoapps/enrollment/views.py
+21
-8
common/test/acceptance/tests/studio/test_studio_split_test.py
+3
-0
No files found.
common/djangoapps/enrollment/api.py
View file @
4df2bd33
...
@@ -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
}
}
...
...
common/djangoapps/enrollment/serializers.py
View file @
4df2bd33
...
@@ -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
,
}
}
...
...
common/djangoapps/enrollment/tests/test_views.py
View file @
4df2bd33
...
@@ -3,6 +3,7 @@ Tests for user enrollment.
...
@@ -3,6 +3,7 @@ Tests for user enrollment.
"""
"""
import
json
import
json
import
unittest
import
unittest
import
datetime
import
ddt
import
ddt
from
django.core.cache
import
cache
from
django.core.cache
import
cache
...
@@ -305,6 +306,46 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
...
@@ -305,6 +306,46 @@ class EnrollmentTest(EnrollmentTestMixin, 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
.
assert_enrollment_status
(
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
.
assert_enrollment_status
(
course_id
=
'entirely/fake/course'
,
expected_status
=
status
.
HTTP_400_BAD_REQUEST
)
self
.
assert_enrollment_status
(
course_id
=
'entirely/fake/course'
,
expected_status
=
status
.
HTTP_400_BAD_REQUEST
)
...
...
common/djangoapps/enrollment/views.py
View file @
4df2bd33
...
@@ -86,7 +86,13 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
...
@@ -86,7 +86,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:
...
@@ -98,8 +104,6 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
...
@@ -98,8 +104,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.
...
@@ -170,7 +174,13 @@ class EnrollmentCourseDetailView(APIView):
...
@@ -170,7 +174,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:
...
@@ -182,8 +192,6 @@ class EnrollmentCourseDetailView(APIView):
...
@@ -182,8 +192,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.
"""
"""
...
@@ -270,7 +278,13 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
...
@@ -270,7 +278,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:
...
@@ -282,7 +296,6 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
...
@@ -282,7 +296,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.
...
...
common/test/acceptance/tests/studio/test_studio_split_test.py
View file @
4df2bd33
...
@@ -8,6 +8,8 @@ from unittest import skip
...
@@ -8,6 +8,8 @@ from unittest import skip
from
nose.plugins.attrib
import
attr
from
nose.plugins.attrib
import
attr
from
selenium.webdriver.support.ui
import
Select
from
selenium.webdriver.support.ui
import
Select
from
flaky
import
flaky
from
xmodule.partitions.partitions
import
Group
from
xmodule.partitions.partitions
import
Group
from
bok_choy.promise
import
Promise
,
EmptyPromise
from
bok_choy.promise
import
Promise
,
EmptyPromise
...
@@ -1044,6 +1046,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin):
...
@@ -1044,6 +1046,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin):
rendered_group_names
=
self
.
get_select_options
(
page
=
courseware_page
,
selector
=
".split-test-select"
)
rendered_group_names
=
self
.
get_select_options
(
page
=
courseware_page
,
selector
=
".split-test-select"
)
self
.
assertListEqual
(
group_names
,
rendered_group_names
)
self
.
assertListEqual
(
group_names
,
rendered_group_names
)
@flaky
# TODO fix this, see TNL-2035
def
test_split_test_LMS_staff_view
(
self
):
def
test_split_test_LMS_staff_view
(
self
):
"""
"""
Scenario: Ensure that split test is correctly rendered in LMS staff mode as it is
Scenario: Ensure that split test is correctly rendered in LMS staff mode as it is
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment