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
6844575e
Commit
6844575e
authored
May 23, 2014
by
Steven Burch
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3676 from edx/f/forum-flag-digest
Add 'roles' endpoint to user_api
parents
a49cf537
e4df2c2c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
137 additions
and
0 deletions
+137
-0
AUTHORS
+1
-0
common/djangoapps/user_api/tests/test_views.py
+103
-0
common/djangoapps/user_api/urls.py
+4
-0
common/djangoapps/user_api/views.py
+29
-0
No files found.
AUTHORS
View file @
6844575e
...
...
@@ -148,3 +148,4 @@ Sébastien Hinderer <Sebastien.Hinderer@inria.fr>
Kristin Stephens <ksteph@cs.berkeley.edu>
Ben Patterson <bpatterson@edx.org>
Luis Duarte <lduarte1991@gmail.com>
Steven Burch <stv@stanford.edu>
common/djangoapps/user_api/tests/test_views.py
View file @
6844575e
...
...
@@ -8,11 +8,14 @@ from student.tests.factories import UserFactory
from
unittest
import
SkipTest
from
user_api.models
import
UserPreference
from
user_api.tests.factories
import
UserPreferenceFactory
from
django_comment_common
import
models
from
xmodule.modulestore.locations
import
SlashSeparatedCourseKey
TEST_API_KEY
=
"test_api_key"
USER_LIST_URI
=
"/user_api/v1/users/"
USER_PREFERENCE_LIST_URI
=
"/user_api/v1/user_prefs/"
ROLE_LIST_URI
=
"/user_api/v1/forum_roles/Moderator/users/"
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
...
...
@@ -104,6 +107,20 @@ class EmptyUserTestCase(ApiTestCase):
self
.
assertEqual
(
result
[
"results"
],
[])
class
EmptyRoleTestCase
(
ApiTestCase
):
"""Test that the endpoint supports empty result sets"""
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
"org/course/run"
)
LIST_URI
=
ROLE_LIST_URI
+
"?course_id="
+
course_id
.
to_deprecated_string
()
def
test_get_list_empty
(
self
):
"""Test that the endpoint properly returns empty result sets"""
result
=
self
.
get_json
(
self
.
LIST_URI
)
self
.
assertEqual
(
result
[
"count"
],
0
)
self
.
assertIsNone
(
result
[
"next"
])
self
.
assertIsNone
(
result
[
"previous"
])
self
.
assertEqual
(
result
[
"results"
],
[])
class
UserApiTestCase
(
ApiTestCase
):
def
setUp
(
self
):
super
(
UserApiTestCase
,
self
)
.
setUp
()
...
...
@@ -121,6 +138,92 @@ class UserApiTestCase(ApiTestCase):
]
class
RoleTestCase
(
UserApiTestCase
):
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
"org/course/run"
)
LIST_URI
=
ROLE_LIST_URI
+
"?course_id="
+
course_id
.
to_deprecated_string
()
def
setUp
(
self
):
super
(
RoleTestCase
,
self
)
.
setUp
()
(
role
,
_
)
=
models
.
Role
.
objects
.
get_or_create
(
name
=
models
.
FORUM_ROLE_MODERATOR
,
course_id
=
self
.
course_id
)
for
user
in
self
.
users
:
user
.
roles
.
add
(
role
)
def
test_options_list
(
self
):
self
.
assertAllowedMethods
(
self
.
LIST_URI
,
[
"OPTIONS"
,
"GET"
,
"HEAD"
])
def
test_post_list_not_allowed
(
self
):
self
.
assertHttpMethodNotAllowed
(
self
.
request_with_auth
(
"post"
,
self
.
LIST_URI
))
def
test_put_list_not_allowed
(
self
):
self
.
assertHttpMethodNotAllowed
(
self
.
request_with_auth
(
"put"
,
self
.
LIST_URI
))
def
test_patch_list_not_allowed
(
self
):
raise
SkipTest
(
"Django 1.4's test client does not support patch"
)
def
test_delete_list_not_allowed
(
self
):
self
.
assertHttpMethodNotAllowed
(
self
.
request_with_auth
(
"delete"
,
self
.
LIST_URI
))
def
test_list_unauthorized
(
self
):
self
.
assertHttpForbidden
(
self
.
client
.
get
(
self
.
LIST_URI
))
@override_settings
(
DEBUG
=
True
)
@override_settings
(
EDX_API_KEY
=
None
)
def
test_debug_auth
(
self
):
self
.
assertHttpOK
(
self
.
client
.
get
(
self
.
LIST_URI
))
@override_settings
(
DEBUG
=
False
)
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
def
test_basic_auth
(
self
):
# ensure that having basic auth headers in the mix does not break anything
self
.
assertHttpOK
(
self
.
request_with_auth
(
"get"
,
self
.
LIST_URI
,
**
self
.
basic_auth
(
"someuser"
,
"somepass"
)))
self
.
assertHttpForbidden
(
self
.
client
.
get
(
self
.
LIST_URI
,
**
self
.
basic_auth
(
"someuser"
,
"somepass"
)))
def
test_get_list_nonempty
(
self
):
result
=
self
.
get_json
(
self
.
LIST_URI
)
users
=
result
[
"results"
]
self
.
assertEqual
(
result
[
"count"
],
len
(
self
.
users
))
self
.
assertEqual
(
len
(
users
),
len
(
self
.
users
))
self
.
assertIsNone
(
result
[
"next"
])
self
.
assertIsNone
(
result
[
"previous"
])
for
user
in
users
:
self
.
assertUserIsValid
(
user
)
def
test_required_parameter
(
self
):
response
=
self
.
request_with_auth
(
"get"
,
ROLE_LIST_URI
)
self
.
assertHttpBadRequest
(
response
)
def
test_get_list_pagination
(
self
):
first_page
=
self
.
get_json
(
self
.
LIST_URI
,
data
=
{
"page_size"
:
3
,
"course_id"
:
self
.
course_id
.
to_deprecated_string
(),
})
self
.
assertEqual
(
first_page
[
"count"
],
5
)
first_page_next_uri
=
first_page
[
"next"
]
self
.
assertIsNone
(
first_page
[
"previous"
])
first_page_users
=
first_page
[
"results"
]
self
.
assertEqual
(
len
(
first_page_users
),
3
)
second_page
=
self
.
get_json
(
first_page_next_uri
)
self
.
assertEqual
(
second_page
[
"count"
],
5
)
self
.
assertIsNone
(
second_page
[
"next"
])
second_page_prev_uri
=
second_page
[
"previous"
]
second_page_users
=
second_page
[
"results"
]
self
.
assertEqual
(
len
(
second_page_users
),
2
)
self
.
assertEqual
(
self
.
get_json
(
second_page_prev_uri
),
first_page
)
for
user
in
first_page_users
+
second_page_users
:
self
.
assertUserIsValid
(
user
)
all_user_uris
=
[
user
[
"url"
]
for
user
in
first_page_users
+
second_page_users
]
self
.
assertEqual
(
len
(
set
(
all_user_uris
)),
5
)
class
UserViewSetTest
(
UserApiTestCase
):
LIST_URI
=
USER_LIST_URI
...
...
common/djangoapps/user_api/urls.py
View file @
6844575e
...
...
@@ -14,4 +14,8 @@ urlpatterns = patterns(
r'^v1/preferences/(?P<pref_key>{})/users/$'
.
format
(
UserPreference
.
KEY_REGEX
),
user_api_views
.
PreferenceUsersListView
.
as_view
()
),
url
(
r'^v1/forum_roles/(?P<name>[a-zA-Z]+)/users/$'
,
user_api_views
.
ForumRoleUsersListView
.
as_view
()
),
)
common/djangoapps/user_api/views.py
View file @
6844575e
...
...
@@ -4,9 +4,14 @@ from rest_framework import authentication
from
rest_framework
import
filters
from
rest_framework
import
generics
from
rest_framework
import
permissions
from
rest_framework
import
status
from
rest_framework
import
viewsets
from
rest_framework.exceptions
import
ParseError
from
rest_framework.response
import
Response
from
user_api.serializers
import
UserSerializer
,
UserPreferenceSerializer
from
user_api.models
import
UserPreference
from
django_comment_common.models
import
Role
from
xmodule.modulestore.locations
import
SlashSeparatedCourseKey
class
ApiKeyHeaderPermission
(
permissions
.
BasePermission
):
...
...
@@ -35,6 +40,30 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
paginate_by_param
=
"page_size"
class
ForumRoleUsersListView
(
generics
.
ListAPIView
):
"""
Forum roles are represented by a list of user dicts
"""
authentication_classes
=
(
authentication
.
SessionAuthentication
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
serializer_class
=
UserSerializer
paginate_by
=
10
paginate_by_param
=
"page_size"
def
get_queryset
(
self
):
"""
Return a list of users with the specified role/course pair
"""
name
=
self
.
kwargs
[
'name'
]
course_id_string
=
self
.
request
.
QUERY_PARAMS
.
get
(
'course_id'
)
if
not
course_id_string
:
raise
ParseError
(
'course_id must be specified'
)
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id_string
)
role
=
Role
.
objects
.
get_or_create
(
course_id
=
course_id
,
name
=
name
)[
0
]
users
=
role
.
users
.
all
()
return
users
class
UserPreferenceViewSet
(
viewsets
.
ReadOnlyModelViewSet
):
authentication_classes
=
(
authentication
.
SessionAuthentication
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
...
...
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