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
164d3244
Commit
164d3244
authored
Oct 13, 2016
by
Amir Qayyum Khan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor tests
parent
25d8085b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
307 additions
and
506 deletions
+307
-506
lms/djangoapps/ccx/api/v0/tests/test_views.py
+307
-506
No files found.
lms/djangoapps/ccx/api/v0/tests/test_views.py
View file @
164d3244
...
...
@@ -54,6 +54,7 @@ from student.tests.factories import AdminFactory
USER_PASSWORD
=
'test'
AUTH_ATTRS
=
(
'auth'
,
'auth_header_oauth2_provider'
)
class
CcxRestApiTest
(
CcxTestCase
,
APITestCase
):
...
...
@@ -183,7 +184,8 @@ class CcxListTest(CcxRestApiTest):
'?master_course_id={0}'
.
format
(
urllib
.
quote_plus
(
self
.
master_course_key_str
))
)
def
test_authorization
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_authorization
(
self
,
auth_attr
):
"""
Test that only the right token is authorized
"""
...
...
@@ -199,12 +201,9 @@ class CcxListTest(CcxRestApiTest):
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_401_UNAUTHORIZED
)
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
def
test_authorization_no_oauth_staff
(
self
):
"""
...
...
@@ -281,7 +280,8 @@ class CcxListTest(CcxRestApiTest):
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
def
test_get_list_wrong_master_course
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_get_list_wrong_master_course
(
self
,
auth_attr
):
"""
Test for various get requests with wrong master course string
"""
...
...
@@ -290,51 +290,31 @@ class CcxListTest(CcxRestApiTest):
with
mock
.
patch
(
mock_class_str
,
autospec
=
True
)
as
mocked_perm_class
:
mocked_perm_class
.
return_value
=
True
# case with no master_course_id provided
resp
=
self
.
client
.
get
(
self
.
list_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
list_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
self
.
list_url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
,
resp
)
base_url
=
urlparse
.
urljoin
(
self
.
list_url
,
'?master_course_id='
)
# case with empty master_course_id
resp
=
self
.
client
.
get
(
base_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
base_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
base_url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
resp
)
# case with invalid master_course_id
url
=
'{0}invalid_master_course_str'
.
format
(
base_url
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
resp
)
# case with inexistent master_course_id
url
=
'{0}course-v1
%3
Aorg_foo.0
%2
Bcourse_bar_0
%2
BRun_0'
.
format
(
base_url
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'course_id_does_not_exist'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'course_id_does_not_exist'
,
resp
)
def
test_get_list
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_get_list
(
self
,
auth_attr
):
"""
Tests the API to get a list of CCX Courses
"""
# there are no CCX courses
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertIn
(
'count'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'count'
],
0
)
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertIn
(
'count'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'count'
],
0
)
# pylint: disable=no-member
...
...
@@ -342,22 +322,15 @@ class CcxListTest(CcxRestApiTest):
num_ccx
=
10
for
_
in
xrange
(
num_ccx
):
self
.
make_ccx
()
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertIn
(
'count'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertIn
(
'results'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
len
(
resp
.
data
[
'results'
]),
num_ccx
)
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertIn
(
'count'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertIn
(
'results'
,
resp
.
data
)
# pylint: disable=no-member
self
.
assertEqual
(
len
(
resp
.
data
[
'results'
]),
num_ccx
)
# pylint: disable=no-member
def
test_get_sorted_list
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_get_sorted_list
(
self
,
auth_attr
):
"""
Tests the API to get a sorted list of CCX Courses
"""
...
...
@@ -376,15 +349,7 @@ class CcxListTest(CcxRestApiTest):
# sort by display name
url
=
'{0}&order_by=display_name'
.
format
(
self
.
list_url_master_course
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
len
(
resp
.
data
[
'results'
]),
num_ccx
)
# pylint: disable=no-member
# the display_name should be sorted as "Title CCX x", "Title CCX y", "Title CCX z"
for
num
,
ccx
in
enumerate
(
resp
.
data
[
'results'
]):
# pylint: disable=no-member
self
.
assertEqual
(
title_str
.
format
(
string
.
ascii_lowercase
[
-
(
num_ccx
-
num
)]),
ccx
[
'display_name'
])
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
len
(
resp
.
data
[
'results'
]),
num_ccx
)
# pylint: disable=no-member
# the display_name should be sorted as "Title CCX x", "Title CCX y", "Title CCX z"
...
...
@@ -393,20 +358,14 @@ class CcxListTest(CcxRestApiTest):
# add sort order desc
url
=
'{0}&order_by=display_name&sort_order=desc'
.
format
(
self
.
list_url_master_course
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
# the only thing I can check is that the display name is in alphabetically reversed order
# in the same way when the field has been updated above, so with the id asc
for
num
,
ccx
in
enumerate
(
resp
.
data
[
'results'
]):
# pylint: disable=no-member
self
.
assertEqual
(
title_str
.
format
(
string
.
ascii_lowercase
[
-
(
num
+
1
)]),
ccx
[
'display_name'
])
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
# the only thing I can check is that the display name is in alphabetically reversed order
# in the same way when the field has been updated above, so with the id asc
for
num
,
ccx
in
enumerate
(
resp
.
data
[
'results'
]):
# pylint: disable=no-member
self
.
assertEqual
(
title_str
.
format
(
string
.
ascii_lowercase
[
-
(
num
+
1
)]),
ccx
[
'display_name'
])
def
test_get_paginated_list
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_get_paginated_list
(
self
,
auth_attr
):
"""
Tests the API to get a paginated list of CCX Courses
"""
...
...
@@ -417,17 +376,7 @@ class CcxListTest(CcxRestApiTest):
page_size
=
settings
.
REST_FRAMEWORK
.
get
(
'PAGE_SIZE'
,
10
)
num_pages
=
int
(
math
.
ceil
(
num_ccx
/
float
(
page_size
)))
# get first page
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'current_page'
],
1
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'start'
],
0
)
# pylint: disable=no-member
self
.
assertIsNotNone
(
resp
.
data
[
'next'
])
# pylint: disable=no-member
self
.
assertIsNone
(
resp
.
data
[
'previous'
])
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
self
.
list_url_master_course
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
...
...
@@ -438,17 +387,7 @@ class CcxListTest(CcxRestApiTest):
# get a page in the middle
url
=
'{0}&page=24'
.
format
(
self
.
list_url_master_course
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'current_page'
],
24
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'start'
],
(
resp
.
data
[
'current_page'
]
-
1
)
*
page_size
)
# pylint: disable=no-member
self
.
assertIsNotNone
(
resp
.
data
[
'next'
])
# pylint: disable=no-member
self
.
assertIsNotNone
(
resp
.
data
[
'previous'
])
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
...
...
@@ -459,17 +398,7 @@ class CcxListTest(CcxRestApiTest):
# get last page
url
=
'{0}&page={1}'
.
format
(
self
.
list_url_master_course
,
num_pages
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'current_page'
],
num_pages
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'start'
],
(
resp
.
data
[
'current_page'
]
-
1
)
*
page_size
)
# pylint: disable=no-member
self
.
assertIsNone
(
resp
.
data
[
'next'
])
# pylint: disable=no-member
self
.
assertIsNotNone
(
resp
.
data
[
'previous'
])
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
[
'count'
],
num_ccx
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
[
'num_pages'
],
num_pages
)
# pylint: disable=no-member
...
...
@@ -480,42 +409,73 @@ class CcxListTest(CcxRestApiTest):
# last page + 1
url
=
'{0}&page={1}'
.
format
(
self
.
list_url_master_course
,
num_pages
+
1
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_404_NOT_FOUND
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_404_NOT_FOUND
)
@ddt.data
(
(
{},
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
'master_course_id_not_provided'
,
'auth_header_oauth2_provider'
),
(
{},
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
,
'auth'
),
(
{
'master_course_id'
:
None
},
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
'master_course_id_not_provided'
,
'auth_header_oauth2_provider'
),
(
{
'master_course_id'
:
None
},
status
.
HTTP_400_BAD_REQUEST
,
'master_course_id_not_provided'
,
'auth'
),
(
{
'master_course_id'
:
''
},
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
'course_id_not_valid'
,
'auth_header_oauth2_provider'
),
(
{
'master_course_id'
:
''
},
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
'auth'
),
(
{
'master_course_id'
:
'invalid_master_course_str'
},
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
,
'auth'
),
(
{
'master_course_id'
:
'invalid_master_course_str'
},
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid'
'course_id_not_valid'
,
'auth_header_oauth2_provider'
),
(
{
'master_course_id'
:
'course-v1:org_foo.0+course_bar_0+Run_0'
},
status
.
HTTP_404_NOT_FOUND
,
'course_id_does_not_exist'
,
'auth'
),
(
{
'master_course_id'
:
'course-v1:org_foo.0+course_bar_0+Run_0'
},
status
.
HTTP_404_NOT_FOUND
,
'course_id_does_not_exist'
'course_id_does_not_exist'
,
'auth_header_oauth2_provider'
),
)
@ddt.unpack
def
test_post_list_wrong_master_course
(
self
,
data
,
expected_http_error
,
expected_error_string
):
def
test_post_list_wrong_master_course
(
self
,
data
,
expected_http_error
,
expected_error_string
,
auth_attr
):
"""
Test for various post requests with wrong master course string
"""
...
...
@@ -524,19 +484,11 @@ class CcxListTest(CcxRestApiTest):
with
mock
.
patch
(
mock_class_str
,
autospec
=
True
)
as
mocked_perm_class
:
mocked_perm_class
.
return_value
=
True
# case with no master_course_id provided
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
expected_http_error
,
expected_error_string
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
expected_http_error
,
expected_error_string
,
resp
)
def
test_post_list_wrong_master_course_special_cases
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_wrong_master_course_special_cases
(
self
,
auth_attr
):
"""
Same as test_post_list_wrong_master_course,
but different ways to test the wrong master_course_id
...
...
@@ -546,7 +498,7 @@ class CcxListTest(CcxRestApiTest):
self
.
mstore
.
update_item
(
self
.
course
,
self
.
coach
.
id
)
data
=
{
'master_course_id'
:
self
.
master_course_key_str
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_403_FORBIDDEN
,
'ccx_not_enabled_for_master_course'
,
resp
)
self
.
course
.
enable_ccx
=
True
self
.
mstore
.
update_item
(
self
.
course
,
self
.
coach
.
id
)
...
...
@@ -554,36 +506,10 @@ class CcxListTest(CcxRestApiTest):
# case with deprecated master_course_id
with
mock
.
patch
(
'courseware.courses.get_course_by_id'
,
autospec
=
True
)
as
mocked
:
mocked
.
return_value
.
id
.
deprecated
=
True
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'deprecated_master_course_id'
,
resp
)
# test for oauth2_provider
self
.
course
.
enable_ccx
=
False
self
.
mstore
.
update_item
(
self
.
course
,
self
.
coach
.
id
)
data
=
{
'master_course_id'
:
self
.
master_course_key_str
}
resp_header_oauth2_provider
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_403_FORBIDDEN
,
'ccx_not_enabled_for_master_course'
,
resp_header_oauth2_provider
)
self
.
course
.
enable_ccx
=
True
self
.
mstore
.
update_item
(
self
.
course
,
self
.
coach
.
id
)
# case with deprecated master_course_id
with
mock
.
patch
(
'courseware.courses.get_course_by_id'
,
autospec
=
True
)
as
mocked
:
mocked
.
return_value
.
id
.
deprecated
=
True
resp_header_oauth2_provider
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'deprecated_master_course_id'
,
resp_header_oauth2_provider
)
@ddt.data
(
(
{},
...
...
@@ -591,7 +517,27 @@ class CcxListTest(CcxRestApiTest):
'max_students_allowed'
:
'missing_field_max_students_allowed'
,
'display_name'
:
'missing_field_display_name'
,
'coach_email'
:
'missing_field_coach_email'
}
},
'auth'
),
(
{},
{
'max_students_allowed'
:
'missing_field_max_students_allowed'
,
'display_name'
:
'missing_field_display_name'
,
'coach_email'
:
'missing_field_coach_email'
},
'auth_header_oauth2_provider'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
'CCX Title'
},
{
'coach_email'
:
'missing_field_coach_email'
},
'auth'
),
(
{
...
...
@@ -600,7 +546,8 @@ class CcxListTest(CcxRestApiTest):
},
{
'coach_email'
:
'missing_field_coach_email'
}
},
'auth_header_oauth2_provider'
),
(
{
...
...
@@ -612,7 +559,30 @@ class CcxListTest(CcxRestApiTest):
'max_students_allowed'
:
'null_field_max_students_allowed'
,
'display_name'
:
'null_field_display_name'
,
'coach_email'
:
'null_field_coach_email'
}
},
'auth'
),
(
{
'max_students_allowed'
:
None
,
'display_name'
:
None
,
'coach_email'
:
None
},
{
'max_students_allowed'
:
'null_field_max_students_allowed'
,
'display_name'
:
'null_field_display_name'
,
'coach_email'
:
'null_field_coach_email'
},
'auth_header_oauth2_provider'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
'CCX Title'
,
'coach_email'
:
'this is not an email@test.com'
},
{
'coach_email'
:
'invalid_coach_email'
},
'auth'
),
(
{
...
...
@@ -620,7 +590,8 @@ class CcxListTest(CcxRestApiTest):
'display_name'
:
'CCX Title'
,
'coach_email'
:
'this is not an email@test.com'
},
{
'coach_email'
:
'invalid_coach_email'
}
{
'coach_email'
:
'invalid_coach_email'
},
'auth_header_oauth2_provider'
),
(
{
...
...
@@ -628,7 +599,17 @@ class CcxListTest(CcxRestApiTest):
'display_name'
:
''
,
'coach_email'
:
'email@test.com'
},
{
'display_name'
:
'invalid_display_name'
}
{
'display_name'
:
'invalid_display_name'
},
'auth'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
''
,
'coach_email'
:
'email@test.com'
},
{
'display_name'
:
'invalid_display_name'
},
'auth_header_oauth2_provider'
),
(
{
...
...
@@ -636,7 +617,27 @@ class CcxListTest(CcxRestApiTest):
'display_name'
:
'CCX Title'
,
'coach_email'
:
'email@test.com'
},
{
'max_students_allowed'
:
'invalid_max_students_allowed'
}
{
'max_students_allowed'
:
'invalid_max_students_allowed'
},
'auth'
),
(
{
'max_students_allowed'
:
'a'
,
'display_name'
:
'CCX Title'
,
'coach_email'
:
'email@test.com'
},
{
'max_students_allowed'
:
'invalid_max_students_allowed'
},
'auth_header_oauth2_provider'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
'CCX Title'
,
'coach_email'
:
'email@test.com'
,
'course_modules'
:
{
'foo'
:
'bar'
}
},
{
'course_modules'
:
'invalid_course_module_list'
},
'auth'
),
(
{
...
...
@@ -645,7 +646,8 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
'email@test.com'
,
'course_modules'
:
{
'foo'
:
'bar'
}
},
{
'course_modules'
:
'invalid_course_module_list'
}
{
'course_modules'
:
'invalid_course_module_list'
},
'auth_header_oauth2_provider'
),
(
{
...
...
@@ -654,7 +656,28 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
'email@test.com'
,
'course_modules'
:
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_1'
},
{
'course_modules'
:
'invalid_course_module_list'
}
{
'course_modules'
:
'invalid_course_module_list'
},
'auth'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
'CCX Title'
,
'coach_email'
:
'email@test.com'
,
'course_modules'
:
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_1'
},
{
'course_modules'
:
'invalid_course_module_list'
},
'auth_header_oauth2_provider'
),
(
{
'max_students_allowed'
:
10
,
'display_name'
:
'CCX Title'
,
'coach_email'
:
'email@test.com'
,
'course_modules'
:
[
'foo'
,
'bar'
]
},
{
'course_modules'
:
'invalid_course_module_keys'
},
'auth'
),
(
{
...
...
@@ -663,29 +686,22 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
'email@test.com'
,
'course_modules'
:
[
'foo'
,
'bar'
]
},
{
'course_modules'
:
'invalid_course_module_keys'
}
{
'course_modules'
:
'invalid_course_module_keys'
},
'auth_header_oauth2_provider'
),
)
@ddt.unpack
def
test_post_list_wrong_input_data
(
self
,
data
,
expected_errors
):
def
test_post_list_wrong_input_data
(
self
,
data
,
expected_errors
,
auth_attr
):
"""
Test for various post requests with wrong input data
"""
# add the master_course_key_str to the request data
data
[
'master_course_id'
]
=
self
.
master_course_key_str
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error_fields
(
expected_errors
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error_fields
(
expected_errors
,
resp
)
def
test_post_list_coach_does_not_exist
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_coach_does_not_exist
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but the coach does not exist.
"""
...
...
@@ -695,19 +711,11 @@ class CcxListTest(CcxRestApiTest):
'display_name'
:
'CCX Title'
,
'coach_email'
:
'inexisting_email@test.com'
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'coach_user_does_not_exist'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'coach_user_does_not_exist'
,
resp
)
def
test_post_list_wrong_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_wrong_modules
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but the
course modules do not belong to the master course
...
...
@@ -722,19 +730,11 @@ class CcxListTest(CcxRestApiTest):
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_bar'
]
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
def
test_post_list_mixed_wrong_and_valid_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_mixed_wrong_and_valid_modules
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but some of
the course modules do not belong to the master course
...
...
@@ -747,19 +747,11 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
self
.
coach
.
email
,
'course_modules'
:
modules
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
def
test_post_list
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list
(
self
,
auth_attr
):
"""
Test the creation of a CCX
"""
...
...
@@ -771,7 +763,7 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
self
.
coach
.
email
,
'course_modules'
:
self
.
master_course_chapters
[
0
:
1
]
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
# check if the response has at least the same data of the request
for
key
,
val
in
data
.
iteritems
():
...
...
@@ -796,38 +788,8 @@ class CcxListTest(CcxRestApiTest):
self
.
assertEqual
(
len
(
outbox
),
1
)
self
.
assertIn
(
self
.
coach
.
email
,
outbox
[
0
]
.
recipients
())
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
# check if the response has at least the same data of the request
for
key
,
val
in
data
.
iteritems
():
self
.
assertEqual
(
resp
.
data
.
get
(
key
),
val
)
# pylint: disable=no-member
self
.
assertIn
(
'ccx_course_id'
,
resp
.
data
)
# pylint: disable=no-member
# check that the new CCX actually exists
course_key
=
CourseKey
.
from_string
(
resp
.
data
.
get
(
'ccx_course_id'
))
# pylint: disable=no-member
ccx_course
=
CustomCourseForEdX
.
objects
.
get
(
pk
=
course_key
.
ccx
)
self
.
assertEqual
(
unicode
(
CCXLocator
.
from_course_locator
(
ccx_course
.
course
.
id
,
ccx_course
.
id
)),
resp
.
data
.
get
(
'ccx_course_id'
)
# pylint: disable=no-member
)
# check that the coach user has coach role on the master course
coach_role_on_master_course
=
CourseCcxCoachRole
(
self
.
master_course_key
)
self
.
assertTrue
(
coach_role_on_master_course
.
has_user
(
self
.
coach
))
# check that the coach has been enrolled in the ccx
ccx_course_object
=
courses
.
get_course_by_id
(
course_key
)
self
.
assertTrue
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
ccx_course_object
.
id
,
user
=
self
.
coach
)
.
exists
()
)
# check that an email has been sent to the coach
self
.
assertEqual
(
len
(
outbox
),
2
)
self
.
assertIn
(
self
.
coach
.
email
,
outbox
[
0
]
.
recipients
())
# pylint: disable=no-member
def
test_post_list_duplicated_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_duplicated_modules
(
self
,
auth_attr
):
"""
Test the creation of a CCX, but with duplicated modules
"""
...
...
@@ -840,21 +802,12 @@ class CcxListTest(CcxRestApiTest):
'coach_email'
:
self
.
coach
.
email
,
'course_modules'
:
duplicated_chapters
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
resp
.
data
.
get
(
'course_modules'
),
chapters
)
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
resp
.
data
.
get
(
'course_modules'
),
chapters
)
# pylint: disable=no-member
def
test_post_list_staff_master_course_in_ccx
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_post_list_staff_master_course_in_ccx
(
self
,
auth_attr
):
"""
Specific test to check that the staff and instructor of the master
course are assigned to the CCX.
...
...
@@ -866,7 +819,7 @@ class CcxListTest(CcxRestApiTest):
'display_name'
:
'CCX Test Title'
,
'coach_email'
:
self
.
coach
.
email
}
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
# check that only one email has been sent and it is to to the coach
self
.
assertEqual
(
len
(
outbox
),
1
)
...
...
@@ -891,32 +844,6 @@ class CcxListTest(CcxRestApiTest):
for
course_user
,
ccx_user
in
izip
(
sorted
(
list_instructor_master_course
),
sorted
(
list_instructor_ccx_course
)):
self
.
assertEqual
(
course_user
,
ccx_user
)
# test for oauth2_provider
resp
=
self
.
client
.
post
(
self
.
list_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_201_CREATED
)
# check that only one email has been sent and it is to to the coach
self
.
assertEqual
(
len
(
outbox
),
2
)
self
.
assertIn
(
self
.
coach
.
email
,
outbox
[
0
]
.
recipients
())
# pylint: disable=no-member
list_staff_master_course
=
list_with_level
(
self
.
course
,
'staff'
)
list_instructor_master_course
=
list_with_level
(
self
.
course
,
'instructor'
)
course_key
=
CourseKey
.
from_string
(
resp
.
data
.
get
(
'ccx_course_id'
))
# pylint: disable=no-member
with
ccx_course_cm
(
course_key
)
as
course_ccx
:
list_staff_ccx_course
=
list_with_level
(
course_ccx
,
'staff'
)
list_instructor_ccx_course
=
list_with_level
(
course_ccx
,
'instructor'
)
self
.
assertEqual
(
len
(
list_staff_master_course
),
len
(
list_staff_ccx_course
))
for
course_user
,
ccx_user
in
izip
(
sorted
(
list_staff_master_course
),
sorted
(
list_staff_ccx_course
)):
self
.
assertEqual
(
course_user
,
ccx_user
)
self
.
assertEqual
(
len
(
list_instructor_master_course
),
len
(
list_instructor_ccx_course
))
for
course_user
,
ccx_user
in
izip
(
sorted
(
list_instructor_master_course
),
sorted
(
list_instructor_ccx_course
)):
self
.
assertEqual
(
course_user
,
ccx_user
)
@attr
(
shard
=
1
)
@ddt.ddt
...
...
@@ -974,7 +901,8 @@ class CcxDetailTest(CcxRestApiTest):
)
return
ccx
def
test_authorization
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_authorization
(
self
,
auth_attr
):
"""
Test that only the right token is authorized
"""
...
...
@@ -990,11 +918,7 @@ class CcxDetailTest(CcxRestApiTest):
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_401_UNAUTHORIZED
)
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
def
test_authorization_no_oauth_staff
(
self
):
...
...
@@ -1084,9 +1008,16 @@ class CcxDetailTest(CcxRestApiTest):
self
.
assertEqual
(
views
.
CCXDetailView
.
__name__
,
resolver
.
func
.
__name__
)
self
.
assertEqual
(
views
.
CCXDetailView
.
__module__
,
resolver
.
func
.
__module__
)
@ddt.data
((
'get'
,),
(
'delete'
,),
(
'patch'
,))
@ddt.data
(
(
'get'
,
AUTH_ATTRS
[
0
]),
(
'get'
,
AUTH_ATTRS
[
1
]),
(
'delete'
,
AUTH_ATTRS
[
0
]),
(
'delete'
,
AUTH_ATTRS
[
1
]),
(
'patch'
,
AUTH_ATTRS
[
0
]),
(
'patch'
,
AUTH_ATTRS
[
1
])
)
@ddt.unpack
def
test_detail_wrong_ccx
(
self
,
http_method
):
def
test_detail_wrong_ccx
(
self
,
http_method
,
auth_attr
):
"""
Test for different methods for detail of a ccx course.
All check the validity of the ccx course id
...
...
@@ -1097,81 +1028,46 @@ class CcxDetailTest(CcxRestApiTest):
url
=
reverse
(
'ccx_api:v0:ccx:detail'
,
kwargs
=
{
'ccx_course_id'
:
self
.
master_course_key_str
})
# the permission class will give a 403 error because will not find the CCX
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# bypassing the permission class we get another kind of error
with
mock
.
patch
(
mock_class_str
,
autospec
=
True
)
as
mocked_perm_class
:
mocked_perm_class
.
return_value
=
True
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid_ccx_id'
,
resp
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_id_not_valid_ccx_id'
,
resp
)
# use an non existing ccx id
url
=
reverse
(
'ccx_api:v0:ccx:detail'
,
kwargs
=
{
'ccx_course_id'
:
'ccx-v1:foo.0+course_bar_0+Run_0+ccx@1'
})
# the permission class will give a 403 error because will not find the CCX
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# bypassing the permission class we get another kind of error
with
mock
.
patch
(
mock_class_str
,
autospec
=
True
)
as
mocked_perm_class
:
mocked_perm_class
.
return_value
=
True
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'ccx_course_id_does_not_exist'
,
resp
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'ccx_course_id_does_not_exist'
,
resp
)
# get a valid ccx key and add few 0s to get a non existing ccx for a valid course
ccx_key_str
=
'{0}000000'
.
format
(
self
.
ccx_key_str
)
url
=
reverse
(
'ccx_api:v0:ccx:detail'
,
kwargs
=
{
'ccx_course_id'
:
ccx_key_str
})
# the permission class will give a 403 error because will not find the CCX
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
# bypassing the permission class we get another kind of error
with
mock
.
patch
(
mock_class_str
,
autospec
=
True
)
as
mocked_perm_class
:
mocked_perm_class
.
return_value
=
True
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'ccx_course_id_does_not_exist'
,
resp
)
# test for oauth2_provider
resp
=
client_request
(
url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'ccx_course_id_does_not_exist'
,
resp
)
def
test_get_detail
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_get_detail
(
self
,
auth_attr
):
"""
Test for getting detail of a ccx course
"""
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
.
get
(
'ccx_course_id'
),
self
.
ccx_key_str
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
.
get
(
'display_name'
),
self
.
ccx
.
display_name
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
.
get
(
'max_students_allowed'
),
# pylint: disable=no-member
self
.
ccx
.
max_student_enrollments_allowed
# pylint: disable=no-member
)
self
.
assertEqual
(
resp
.
data
.
get
(
'coach_email'
),
self
.
ccx
.
coach
.
email
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
.
get
(
'master_course_id'
),
unicode
(
self
.
ccx
.
course_id
))
# pylint: disable=no-member
self
.
assertItemsEqual
(
resp
.
data
.
get
(
'course_modules'
),
self
.
master_course_chapters
)
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
get
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
resp
.
data
.
get
(
'ccx_course_id'
),
self
.
ccx_key_str
)
# pylint: disable=no-member
self
.
assertEqual
(
resp
.
data
.
get
(
'display_name'
),
self
.
ccx
.
display_name
)
# pylint: disable=no-member
...
...
@@ -1183,14 +1079,15 @@ class CcxDetailTest(CcxRestApiTest):
self
.
assertEqual
(
resp
.
data
.
get
(
'master_course_id'
),
unicode
(
self
.
ccx
.
course_id
))
# pylint: disable=no-member
self
.
assertItemsEqual
(
resp
.
data
.
get
(
'course_modules'
),
self
.
master_course_chapters
)
# pylint: disable=no-member
def
test_delete_detail
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_delete_detail
(
self
,
auth_attr
):
"""
Test for deleting a ccx course
"""
# check that there are overrides
self
.
assertGreater
(
CcxFieldOverride
.
objects
.
filter
(
ccx
=
self
.
ccx
)
.
count
(),
0
)
self
.
assertGreater
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
self
.
ccx_key
)
.
count
(),
0
)
resp
=
self
.
client
.
delete
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
delete
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
self
.
assertIsNone
(
resp
.
data
)
# pylint: disable=no-member
# the CCX does not exist any more
...
...
@@ -1200,40 +1097,15 @@ class CcxDetailTest(CcxRestApiTest):
self
.
assertEqual
(
CcxFieldOverride
.
objects
.
filter
(
ccx
=
self
.
ccx
)
.
count
(),
0
)
self
.
assertEqual
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
self
.
ccx_key
)
.
count
(),
0
)
def
test_delete_detail_oauth2_provider
(
self
):
"""
Test for deleting a ccx course with oauth2_provider header
"""
# check that there are overrides
self
.
assertGreater
(
CcxFieldOverride
.
objects
.
filter
(
ccx
=
self
.
ccx
)
.
count
(),
0
)
self
.
assertGreater
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
self
.
ccx_key
)
.
count
(),
0
)
resp
=
self
.
client
.
delete
(
self
.
detail_url
,
{},
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
self
.
assertIsNone
(
resp
.
data
)
# pylint: disable=no-member
# the CCX does not exist any more
with
self
.
assertRaises
(
CustomCourseForEdX
.
DoesNotExist
):
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
# check that there are no overrides
self
.
assertEqual
(
CcxFieldOverride
.
objects
.
filter
(
ccx
=
self
.
ccx
)
.
count
(),
0
)
self
.
assertEqual
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
self
.
ccx_key
)
.
count
(),
0
)
def
test_patch_detail_change_master_course
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail_change_master_course
(
self
,
auth_attr
):
"""
Test to patch a ccx course to change a master course
"""
data
=
{
'master_course_id'
:
'changed_course_id'
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_403_FORBIDDEN
,
'master_course_id_change_not_allowed'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_403_FORBIDDEN
,
'master_course_id_change_not_allowed'
,
resp
)
@ddt.data
(
...
...
@@ -1247,51 +1119,95 @@ class CcxDetailTest(CcxRestApiTest):
'max_students_allowed'
:
'null_field_max_students_allowed'
,
'display_name'
:
'null_field_display_name'
,
'coach_email'
:
'null_field_coach_email'
}
},
AUTH_ATTRS
[
0
]
),
(
{
'max_students_allowed'
:
None
,
'display_name'
:
None
,
'coach_email'
:
None
},
{
'max_students_allowed'
:
'null_field_max_students_allowed'
,
'display_name'
:
'null_field_display_name'
,
'coach_email'
:
'null_field_coach_email'
},
AUTH_ATTRS
[
1
]
),
(
{
'coach_email'
:
'this is not an email@test.com'
},
{
'coach_email'
:
'invalid_coach_email'
},
AUTH_ATTRS
[
0
]
),
(
{
'coach_email'
:
'this is not an email@test.com'
},
{
'coach_email'
:
'invalid_coach_email'
}
{
'coach_email'
:
'invalid_coach_email'
},
AUTH_ATTRS
[
1
]
),
(
{
'display_name'
:
''
},
{
'display_name'
:
'invalid_display_name'
}
{
'display_name'
:
'invalid_display_name'
},
AUTH_ATTRS
[
0
]
),
(
{
'display_name'
:
''
},
{
'display_name'
:
'invalid_display_name'
},
AUTH_ATTRS
[
1
]
),
(
{
'max_students_allowed'
:
'a'
},
{
'max_students_allowed'
:
'invalid_max_students_allowed'
},
AUTH_ATTRS
[
0
]
),
(
{
'max_students_allowed'
:
'a'
},
{
'max_students_allowed'
:
'invalid_max_students_allowed'
}
{
'max_students_allowed'
:
'invalid_max_students_allowed'
},
AUTH_ATTRS
[
1
]
),
(
{
'course_modules'
:
{
'foo'
:
'bar'
}},
{
'course_modules'
:
'invalid_course_module_list'
}
{
'course_modules'
:
'invalid_course_module_list'
},
AUTH_ATTRS
[
0
]
),
(
{
'course_modules'
:
{
'foo'
:
'bar'
}},
{
'course_modules'
:
'invalid_course_module_list'
},
AUTH_ATTRS
[
1
]
),
(
{
'course_modules'
:
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_1'
},
{
'course_modules'
:
'invalid_course_module_list'
},
AUTH_ATTRS
[
0
]
),
(
{
'course_modules'
:
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_1'
},
{
'course_modules'
:
'invalid_course_module_list'
}
{
'course_modules'
:
'invalid_course_module_list'
},
AUTH_ATTRS
[
1
]
),
(
{
'course_modules'
:
[
'foo'
,
'bar'
]},
{
'course_modules'
:
'invalid_course_module_keys'
},
AUTH_ATTRS
[
0
]
),
(
{
'course_modules'
:
[
'foo'
,
'bar'
]},
{
'course_modules'
:
'invalid_course_module_keys'
}
{
'course_modules'
:
'invalid_course_module_keys'
},
AUTH_ATTRS
[
1
]
),
)
@ddt.unpack
def
test_patch_detail_wrong_input_data
(
self
,
data
,
expected_errors
):
def
test_patch_detail_wrong_input_data
(
self
,
data
,
expected_errors
,
auth_attr
):
"""
Test for different wrong inputs for the patch method
"""
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error_fields
(
expected_errors
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error_fields
(
expected_errors
,
resp
)
def
test_empty_patch
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_empty_patch
(
self
,
auth_attr
):
"""
An empty patch does not modify anything
"""
...
...
@@ -1299,7 +1215,7 @@ class CcxDetailTest(CcxRestApiTest):
max_students_allowed
=
self
.
ccx
.
max_student_enrollments_allowed
# pylint: disable=no-member
coach_email
=
self
.
ccx
.
coach
.
email
# pylint: disable=no-member
ccx_structure
=
self
.
ccx
.
structure
# pylint: disable=no-member
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
{},
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
{},
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
display_name
,
ccx
.
display_name
)
...
...
@@ -1307,21 +1223,8 @@ class CcxDetailTest(CcxRestApiTest):
self
.
assertEqual
(
coach_email
,
ccx
.
coach
.
email
)
self
.
assertEqual
(
ccx_structure
,
ccx
.
structure
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
{},
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
display_name
,
ccx
.
display_name
)
self
.
assertEqual
(
max_students_allowed
,
ccx
.
max_student_enrollments_allowed
)
self
.
assertEqual
(
coach_email
,
ccx
.
coach
.
email
)
self
.
assertEqual
(
ccx_structure
,
ccx
.
structure
)
def
test_patch_detail_coach_does_not_exist
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail_coach_does_not_exist
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but the coach does not exist.
"""
...
...
@@ -1330,19 +1233,11 @@ class CcxDetailTest(CcxRestApiTest):
'display_name'
:
'CCX Title'
,
'coach_email'
:
'inexisting_email@test.com'
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'coach_user_does_not_exist'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_404_NOT_FOUND
,
'coach_user_does_not_exist'
,
resp
)
def
test_patch_detail_wrong_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail_wrong_modules
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but the
course modules do not belong to the master course
...
...
@@ -1353,19 +1248,11 @@ class CcxDetailTest(CcxRestApiTest):
'block-v1:org.0+course_0+Run_0+type@chapter+block@chapter_bar'
]
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
def
test_patch_detail_mixed_wrong_and_valid_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail_mixed_wrong_and_valid_modules
(
self
,
auth_attr
):
"""
Specific test for the case when the input data is valid but some of
the course modules do not belong to the master course
...
...
@@ -1374,19 +1261,11 @@ class CcxDetailTest(CcxRestApiTest):
data
=
{
'course_modules'
:
modules
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
expect_error
(
status
.
HTTP_400_BAD_REQUEST
,
'course_module_list_not_belonging_to_master_course'
,
resp
)
def
test_patch_detail
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail
(
self
,
auth_attr
):
"""
Test for successful patch
"""
...
...
@@ -1398,7 +1277,7 @@ class CcxDetailTest(CcxRestApiTest):
'display_name'
:
'CCX Title'
,
'coach_email'
:
new_coach
.
email
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
)
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
ccx_from_db
.
max_student_enrollments_allowed
,
data
[
'max_students_allowed'
])
...
...
@@ -1416,116 +1295,38 @@ class CcxDetailTest(CcxRestApiTest):
self
.
assertEqual
(
len
(
outbox
),
1
)
self
.
assertIn
(
new_coach
.
email
,
outbox
[
0
]
.
recipients
())
# pylint: disable=no-member
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
ccx_from_db
.
max_student_enrollments_allowed
,
data
[
'max_students_allowed'
])
self
.
assertEqual
(
ccx_from_db
.
display_name
,
data
[
'display_name'
])
self
.
assertEqual
(
ccx_from_db
.
coach
.
email
,
data
[
'coach_email'
])
# check that the coach user has coach role on the master course
coach_role_on_master_course
=
CourseCcxCoachRole
(
self
.
master_course_key
)
self
.
assertTrue
(
coach_role_on_master_course
.
has_user
(
new_coach
))
# check that the coach has been enrolled in the ccx
ccx_course_object
=
courses
.
get_course_by_id
(
self
.
ccx_key
)
self
.
assertTrue
(
CourseEnrollment
.
objects
.
filter
(
course_id
=
ccx_course_object
.
id
,
user
=
new_coach
)
.
exists
()
)
# check that an email has been sent to the coach
self
.
assertEqual
(
len
(
outbox
),
1
)
self
.
assertIn
(
new_coach
.
email
,
outbox
[
0
]
.
recipients
())
# pylint: disable=no-member
def
test_patch_detail_modules
(
self
):
@ddt.data
(
*
AUTH_ATTRS
)
def
test_patch_detail_modules
(
self
,
auth_attr
):
"""
Specific test for successful patch of the course modules
"""
data
=
{
'course_modules'
:
self
.
master_course_chapters
[
0
:
1
]}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
data
[
'course_modules'
])
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
data
[
'course_modules'
])
data
=
{
'course_modules'
:
[]}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
[])
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
[])
data
=
{
'course_modules'
:
self
.
master_course_chapters
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
self
.
master_course_chapters
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
self
.
master_course_chapters
)
data
=
{
'course_modules'
:
None
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
ccx_from_db
.
structure
,
None
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertEqual
(
ccx_from_db
.
structure
,
None
)
chapters
=
self
.
master_course_chapters
[
0
:
1
]
data
=
{
'course_modules'
:
chapters
*
3
}
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
chapters
)
# test for oauth2_provider
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
self
.
auth_header_oauth2_provider
)
resp
=
self
.
client
.
patch
(
self
.
detail_url
,
data
,
format
=
'json'
,
HTTP_AUTHORIZATION
=
getattr
(
self
,
auth_attr
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
ccx_from_db
=
CustomCourseForEdX
.
objects
.
get
(
id
=
self
.
ccx
.
id
)
self
.
assertItemsEqual
(
ccx_from_db
.
structure
,
chapters
)
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