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
09b00df7
Commit
09b00df7
authored
May 22, 2015
by
Greg Price
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8154 from edx/gprice/discussion-api-comment-list-refs
Add comment list URLs to discussion api threads
parents
c48dccce
c83f5615
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
80 additions
and
7 deletions
+80
-7
lms/djangoapps/discussion_api/api.py
+2
-2
lms/djangoapps/discussion_api/serializers.py
+36
-1
lms/djangoapps/discussion_api/tests/test_api.py
+13
-1
lms/djangoapps/discussion_api/tests/test_serializers.py
+26
-3
lms/djangoapps/discussion_api/tests/test_views.py
+3
-0
No files found.
lms/djangoapps/discussion_api/api.py
View file @
09b00df7
...
...
@@ -107,7 +107,7 @@ def get_thread_list(request, course_key, page, page_size):
discussion_api.views.ThreadViewSet for more detail.
"""
course
=
_get_course_or_404
(
course_key
,
request
.
user
)
context
=
get_context
(
course
,
request
.
user
)
context
=
get_context
(
course
,
request
)
threads
,
result_page
,
num_pages
,
_
=
Thread
.
search
({
"course_id"
:
unicode
(
course
.
id
),
"group_id"
:
(
...
...
@@ -169,7 +169,7 @@ def get_comment_list(request, thread_id, endorsed, page, page_size):
course_key
=
CourseLocator
.
from_string
(
cc_thread
[
"course_id"
])
course
=
_get_course_or_404
(
course_key
,
request
.
user
)
context
=
get_context
(
course
,
request
.
user
,
cc_thread
)
context
=
get_context
(
course
,
request
,
cc_thread
)
# Ensure user has access to the thread
if
not
context
[
"is_requester_privileged"
]
and
cc_thread
[
"group_id"
]:
...
...
lms/djangoapps/discussion_api/serializers.py
View file @
09b00df7
"""
Discussion API serializers
"""
from
urllib
import
urlencode
from
urlparse
import
urlunparse
from
django.contrib.auth.models
import
User
as
DjangoUser
from
django.core.urlresolvers
import
reverse
from
rest_framework
import
serializers
...
...
@@ -15,7 +19,7 @@ from lms.lib.comment_client.user import User as CommentClientUser
from
openedx.core.djangoapps.course_groups.cohorts
import
get_cohort_names
def
get_context
(
course
,
request
er
,
thread
=
None
):
def
get_context
(
course
,
request
,
thread
=
None
):
"""
Returns a context appropriate for use with ThreadSerializer or
(if thread is provided) CommentSerializer.
...
...
@@ -34,8 +38,10 @@ def get_context(course, requester, thread=None):
for
role
in
Role
.
objects
.
filter
(
name
=
FORUM_ROLE_COMMUNITY_TA
,
course_id
=
course
.
id
)
for
user
in
role
.
users
.
all
()
}
requester
=
request
.
user
return
{
# For now, the only groups are cohorts
"request"
:
request
,
"group_ids_to_names"
:
get_cohort_names
(
course
),
"is_requester_privileged"
:
requester
.
id
in
staff_user_ids
or
requester
.
id
in
ta_user_ids
,
"staff_user_ids"
:
staff_user_ids
,
...
...
@@ -137,6 +143,9 @@ class ThreadSerializer(_ContentSerializer):
following
=
serializers
.
SerializerMethodField
(
"get_following"
)
comment_count
=
serializers
.
IntegerField
(
source
=
"comments_count"
)
unread_comment_count
=
serializers
.
IntegerField
(
source
=
"unread_comments_count"
)
comment_list_url
=
serializers
.
SerializerMethodField
(
"get_comment_list_url"
)
endorsed_comment_list_url
=
serializers
.
SerializerMethodField
(
"get_endorsed_comment_list_url"
)
non_endorsed_comment_list_url
=
serializers
.
SerializerMethodField
(
"get_non_endorsed_comment_list_url"
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ThreadSerializer
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -155,6 +164,32 @@ class ThreadSerializer(_ContentSerializer):
"""
return
obj
[
"id"
]
in
self
.
context
[
"cc_requester"
][
"subscribed_thread_ids"
]
def
get_comment_list_url
(
self
,
obj
,
endorsed
=
None
):
"""
Returns the URL to retrieve the thread's comments, optionally including
the endorsed query parameter.
"""
if
(
(
obj
[
"thread_type"
]
==
"question"
and
endorsed
is
None
)
or
(
obj
[
"thread_type"
]
==
"discussion"
and
endorsed
is
not
None
)
):
return
None
path
=
reverse
(
"comment-list"
)
query_dict
=
{
"thread_id"
:
obj
[
"id"
]}
if
endorsed
is
not
None
:
query_dict
[
"endorsed"
]
=
endorsed
return
self
.
context
[
"request"
]
.
build_absolute_uri
(
urlunparse
((
""
,
""
,
path
,
""
,
urlencode
(
query_dict
),
""
))
)
def
get_endorsed_comment_list_url
(
self
,
obj
):
"""Returns the URL to retrieve the thread's endorsed comments."""
return
self
.
get_comment_list_url
(
obj
,
endorsed
=
True
)
def
get_non_endorsed_comment_list_url
(
self
,
obj
):
"""Returns the URL to retrieve the thread's non-endorsed comments."""
return
self
.
get_comment_list_url
(
obj
,
endorsed
=
False
)
class
CommentSerializer
(
_ContentSerializer
):
"""
...
...
lms/djangoapps/discussion_api/tests/test_api.py
View file @
09b00df7
...
...
@@ -32,6 +32,7 @@ from django_comment_common.models import (
from
openedx.core.djangoapps.course_groups.models
import
CourseUserGroupPartitionGroup
from
openedx.core.djangoapps.course_groups.tests.helpers
import
CohortFactory
from
student.tests.factories
import
CourseEnrollmentFactory
,
UserFactory
from
util.testing
import
UrlResetMixin
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
...
...
@@ -356,8 +357,9 @@ class GetCourseTopicsTest(ModuleStoreTestCase):
@ddt.ddt
class
GetThreadListTest
(
CommentsServiceMockMixin
,
ModuleStoreTestCase
):
class
GetThreadListTest
(
CommentsServiceMockMixin
,
UrlResetMixin
,
ModuleStoreTestCase
):
"""Test for get_thread_list"""
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUp
(
self
):
super
(
GetThreadListTest
,
self
)
.
setUp
()
httpretty
.
reset
()
...
...
@@ -485,6 +487,9 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"vote_count"
:
4
,
"comment_count"
:
5
,
"unread_comment_count"
:
3
,
"comment_list_url"
:
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread_id_0"
,
"endorsed_comment_list_url"
:
None
,
"non_endorsed_comment_list_url"
:
None
,
},
{
"id"
:
"test_thread_id_1"
,
...
...
@@ -507,6 +512,13 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"vote_count"
:
9
,
"comment_count"
:
18
,
"unread_comment_count"
:
0
,
"comment_list_url"
:
None
,
"endorsed_comment_list_url"
:
(
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread_id_1&endorsed=True"
),
"non_endorsed_comment_list_url"
:
(
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread_id_1&endorsed=False"
),
},
]
self
.
assertEqual
(
...
...
lms/djangoapps/discussion_api/tests/test_serializers.py
View file @
09b00df7
...
...
@@ -5,6 +5,9 @@ import itertools
import
ddt
import
httpretty
import
mock
from
django.test.client
import
RequestFactory
from
discussion_api.serializers
import
CommentSerializer
,
ThreadSerializer
,
get_context
from
discussion_api.tests.utils
import
(
...
...
@@ -20,13 +23,15 @@ from django_comment_common.models import (
Role
,
)
from
student.tests.factories
import
UserFactory
from
util.testing
import
UrlResetMixin
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
openedx.core.djangoapps.course_groups.tests.helpers
import
CohortFactory
@ddt.ddt
class
SerializerTestMixin
(
CommentsServiceMockMixin
):
class
SerializerTestMixin
(
CommentsServiceMockMixin
,
UrlResetMixin
):
@mock.patch.dict
(
"django.conf.settings.FEATURES"
,
{
"ENABLE_DISCUSSION_SERVICE"
:
True
})
def
setUp
(
self
):
super
(
SerializerTestMixin
,
self
)
.
setUp
()
httpretty
.
reset
()
...
...
@@ -35,6 +40,8 @@ class SerializerTestMixin(CommentsServiceMockMixin):
self
.
maxDiff
=
None
# pylint: disable=invalid-name
self
.
user
=
UserFactory
.
create
()
self
.
register_get_user_response
(
self
.
user
)
self
.
request
=
RequestFactory
()
.
get
(
"/dummy"
)
self
.
request
.
user
=
self
.
user
self
.
course
=
CourseFactory
.
create
()
self
.
author
=
UserFactory
.
create
()
...
...
@@ -137,7 +144,7 @@ class ThreadSerializerTest(SerializerTestMixin, ModuleStoreTestCase):
Create a serializer with an appropriate context and use it to serialize
the given thread, returning the result.
"""
return
ThreadSerializer
(
thread
,
context
=
get_context
(
self
.
course
,
self
.
user
))
.
data
return
ThreadSerializer
(
thread
,
context
=
get_context
(
self
.
course
,
self
.
request
))
.
data
def
test_basic
(
self
):
thread
=
{
...
...
@@ -182,9 +189,25 @@ class ThreadSerializerTest(SerializerTestMixin, ModuleStoreTestCase):
"vote_count"
:
4
,
"comment_count"
:
5
,
"unread_comment_count"
:
3
,
"comment_list_url"
:
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread"
,
"endorsed_comment_list_url"
:
None
,
"non_endorsed_comment_list_url"
:
None
,
}
self
.
assertEqual
(
self
.
serialize
(
thread
),
expected
)
thread
[
"thread_type"
]
=
"question"
expected
.
update
({
"type"
:
"question"
,
"comment_list_url"
:
None
,
"endorsed_comment_list_url"
:
(
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread&endorsed=True"
),
"non_endorsed_comment_list_url"
:
(
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread&endorsed=False"
),
})
self
.
assertEqual
(
self
.
serialize
(
thread
),
expected
)
def
test_group
(
self
):
cohort
=
CohortFactory
.
create
(
course_id
=
self
.
course
.
id
)
serialized
=
self
.
serialize
(
self
.
make_cs_content
({
"group_id"
:
cohort
.
id
}))
...
...
@@ -227,7 +250,7 @@ class CommentSerializerTest(SerializerTestMixin, ModuleStoreTestCase):
Create a serializer with an appropriate context and use it to serialize
the given comment, returning the result.
"""
context
=
get_context
(
self
.
course
,
self
.
user
,
make_minimal_cs_thread
(
thread_data
))
context
=
get_context
(
self
.
course
,
self
.
request
,
make_minimal_cs_thread
(
thread_data
))
return
CommentSerializer
(
comment
,
context
=
context
)
.
data
def
test_basic
(
self
):
...
...
lms/djangoapps/discussion_api/tests/test_views.py
View file @
09b00df7
...
...
@@ -158,6 +158,9 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"vote_count"
:
4
,
"comment_count"
:
5
,
"unread_comment_count"
:
3
,
"comment_list_url"
:
"http://testserver/api/discussion/v1/comments/?thread_id=test_thread"
,
"endorsed_comment_list_url"
:
None
,
"non_endorsed_comment_list_url"
:
None
,
}]
self
.
register_get_threads_response
(
source_threads
,
page
=
1
,
num_pages
=
2
)
response
=
self
.
client
.
get
(
self
.
url
,
{
"course_id"
:
unicode
(
self
.
course
.
id
)})
...
...
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