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
445d0dab
Commit
445d0dab
authored
Jun 04, 2015
by
jsa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Correct deactivation logic in enrollment api and test.
XCOM-396
parent
298ba727
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
3 deletions
+72
-3
common/djangoapps/enrollment/tests/test_views.py
+55
-2
common/djangoapps/enrollment/views.py
+17
-1
No files found.
common/djangoapps/enrollment/tests/test_views.py
View file @
445d0dab
...
...
@@ -2,6 +2,7 @@
Tests for user enrollment.
"""
import
json
import
itertools
import
unittest
import
datetime
...
...
@@ -91,11 +92,11 @@ class EnrollmentTestMixin(object):
return
response
def
assert_enrollment_activation
(
self
,
expected_activation
,
expected_mode
=
CourseMode
.
VERIFIED
):
def
assert_enrollment_activation
(
self
,
expected_activation
,
expected_mode
):
"""Change an enrollment's activation and verify its activation and mode are as expected."""
self
.
assert_enrollment_status
(
as_server
=
True
,
mode
=
Non
e
,
mode
=
expected_mod
e
,
is_active
=
expected_activation
,
expected_status
=
status
.
HTTP_200_OK
)
...
...
@@ -603,6 +604,58 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self
.
assertTrue
(
is_active
)
self
.
assertEqual
(
course_mode
,
CourseMode
.
HONOR
)
@ddt.data
(
*
itertools
.
product
(
(
CourseMode
.
HONOR
,
CourseMode
.
VERIFIED
),
(
CourseMode
.
HONOR
,
CourseMode
.
VERIFIED
),
(
True
,
False
),
(
True
,
False
),
))
@ddt.unpack
def
test_change_mode_from_server
(
self
,
old_mode
,
new_mode
,
old_is_active
,
new_is_active
):
"""
Server-to-server calls should be allowed to change the mode of any
enrollment, as long as the enrollment is not being deactivated during
the same call (this is assumed to be an error on the client's side).
"""
for
mode
in
[
CourseMode
.
HONOR
,
CourseMode
.
VERIFIED
]:
CourseModeFactory
.
create
(
course_id
=
self
.
course
.
id
,
mode_slug
=
mode
,
mode_display_name
=
mode
,
)
# Set up the initial enrollment
self
.
assert_enrollment_status
(
as_server
=
True
,
mode
=
old_mode
,
is_active
=
old_is_active
)
course_mode
,
is_active
=
CourseEnrollment
.
enrollment_mode_for_user
(
self
.
user
,
self
.
course
.
id
)
self
.
assertEqual
(
is_active
,
old_is_active
)
self
.
assertEqual
(
course_mode
,
old_mode
)
expected_status
=
status
.
HTTP_400_BAD_REQUEST
if
(
old_mode
!=
new_mode
and
old_is_active
!=
new_is_active
and
not
new_is_active
)
else
status
.
HTTP_200_OK
# simulate the server-server api call under test
response
=
self
.
assert_enrollment_status
(
as_server
=
True
,
mode
=
new_mode
,
is_active
=
new_is_active
,
expected_status
=
expected_status
,
)
course_mode
,
is_active
=
CourseEnrollment
.
enrollment_mode_for_user
(
self
.
user
,
self
.
course
.
id
)
if
expected_status
==
status
.
HTTP_400_BAD_REQUEST
:
# nothing should have changed
self
.
assertEqual
(
is_active
,
old_is_active
)
self
.
assertEqual
(
course_mode
,
old_mode
)
# error message should contain specific text. Otto checks for this text in the message.
self
.
assertRegexpMatches
(
json
.
loads
(
response
.
content
)[
'message'
],
'Enrollment mode mismatch'
)
else
:
# call should have succeeded
self
.
assertEqual
(
is_active
,
new_is_active
)
self
.
assertEqual
(
course_mode
,
new_mode
)
def
test_change_mode_invalid_user
(
self
):
"""
Attempts to change an enrollment for a non-existent user should result in an HTTP 404 for non-server users,
...
...
common/djangoapps/enrollment/views.py
View file @
445d0dab
...
...
@@ -3,6 +3,8 @@ The Enrollment API Views should be simple, lean HTTP endpoints for API access. T
consist primarily of authentication, request validation, and serialization.
"""
import
logging
from
ipware.ip
import
get_ip
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.utils.decorators
import
method_decorator
...
...
@@ -31,6 +33,9 @@ from enrollment.errors import (
from
student.models
import
User
log
=
logging
.
getLogger
(
__name__
)
class
EnrollmentCrossDomainSessionAuth
(
SessionAuthenticationAllowInactiveUser
,
SessionAuthenticationCrossDomainCsrf
):
"""Session authentication that allows inactive users and cross-domain requests. """
pass
...
...
@@ -421,7 +426,18 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
)
enrollment
=
api
.
get_enrollment
(
username
,
unicode
(
course_id
))
if
has_api_key_permissions
and
enrollment
and
enrollment
[
'mode'
]
!=
mode
:
mode_changed
=
enrollment
and
mode
is
not
None
and
enrollment
[
'mode'
]
!=
mode
active_changed
=
enrollment
and
is_active
is
not
None
and
enrollment
[
'is_active'
]
!=
is_active
if
has_api_key_permissions
and
(
mode_changed
or
active_changed
):
if
mode_changed
and
active_changed
and
not
is_active
:
# if the requester wanted to deactivate but specified the wrong mode, fail
# the request (on the assumption that the requester had outdated information
# about the currently active enrollment).
msg
=
u"Enrollment mode mismatch: active mode={}, requested mode={}. Won't deactivate."
.
format
(
enrollment
[
"mode"
],
mode
)
log
.
warning
(
msg
)
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"message"
:
msg
})
response
=
api
.
update_enrollment
(
username
,
unicode
(
course_id
),
mode
=
mode
,
is_active
=
is_active
)
else
:
# Will reactivate inactive enrollments.
...
...
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