Add fields to discussion thread list endpoint

This commit adds fields that are related to the requesting user's
interaction with the thread (e.g. following).
This commit is contained in:
Greg Price
2015-05-04 17:13:55 -04:00
parent 603eae65d8
commit fa6e5338c2
4 changed files with 56 additions and 3 deletions

View File

@@ -14,6 +14,7 @@ from django_comment_common.models import (
Role,
)
from lms.lib.comment_client.thread import Thread
from lms.lib.comment_client.user import User
from openedx.core.djangoapps.course_groups.cohorts import get_cohort_id
@@ -76,7 +77,7 @@ def get_course_topics(course, user):
}
def _cc_thread_to_api_thread(thread):
def _cc_thread_to_api_thread(thread, cc_user):
"""
Convert a thread data dict from the comment_client format (which is a direct
representation of the format returned by the comments service) to the format
@@ -98,6 +99,10 @@ def _cc_thread_to_api_thread(thread):
ret.update({
"topic_id": thread["commentable_id"],
"raw_body": thread["body"],
"following": thread["id"] in cc_user["subscribed_thread_ids"],
"abuse_flagged": cc_user["id"] in thread["abuse_flaggers"],
"voted": thread["id"] in cc_user["upvoted_ids"],
"vote_count": thread["votes"]["up_count"],
"comment_count": thread["comments_count"],
"unread_comment_count": thread["unread_comments_count"],
})
@@ -125,6 +130,7 @@ def get_thread_list(request, course_key, page, page_size):
name__in=[FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA],
users=request.user
).exists()
cc_user = User.from_django_user(request.user).retrieve()
threads, result_page, num_pages, _ = Thread.search({
"course_id": unicode(course_key),
"group_id": None if user_is_privileged else get_cohort_id(request.user, course_key),
@@ -139,5 +145,5 @@ def get_thread_list(request, course_key, page, page_size):
if result_page != page:
raise Http404
results = [_cc_thread_to_api_thread(thread) for thread in threads]
results = [_cc_thread_to_api_thread(thread, cc_user) for thread in threads]
return get_paginated_data(request, results, page, num_pages)

View File

@@ -323,13 +323,16 @@ class GetCourseTopicsTest(ModuleStoreTestCase):
@ddt.ddt
@httpretty.activate
class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"""Test for get_thread_list"""
def setUp(self):
super(GetThreadListTest, self).setUp()
httpretty.reset()
httpretty.enable()
self.addCleanup(httpretty.disable)
self.maxDiff = None # pylint: disable=invalid-name
self.user = UserFactory.create()
self.register_get_user_response(self.user)
self.request = RequestFactory().get("/test_path")
self.request.user = self.user
self.course = CourseFactory.create()
@@ -366,6 +369,11 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
})
def test_thread_content(self):
self.register_get_user_response(
self.user,
subscribed_thread_ids=["test_thread_id_0"],
upvoted_ids=["test_thread_id_1"]
)
source_threads = [
{
"id": "test_thread_id_0",
@@ -378,6 +386,8 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"body": "Test body",
"pinned": False,
"closed": False,
"abuse_flaggers": [],
"votes": {"up_count": 4},
"comments_count": 5,
"unread_comments_count": 3,
},
@@ -392,6 +402,8 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"body": "More content",
"pinned": False,
"closed": True,
"abuse_flaggers": [],
"votes": {"up_count": 9},
"comments_count": 18,
"unread_comments_count": 0,
},
@@ -406,6 +418,8 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"body": "Still more content",
"pinned": True,
"closed": False,
"abuse_flaggers": [str(self.user.id)],
"votes": {"up_count": 0},
"comments_count": 0,
"unread_comments_count": 0,
},
@@ -422,6 +436,10 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"raw_body": "Test body",
"pinned": False,
"closed": False,
"following": True,
"abuse_flagged": False,
"voted": False,
"vote_count": 4,
"comment_count": 5,
"unread_comment_count": 3,
},
@@ -436,6 +454,10 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"raw_body": "More content",
"pinned": False,
"closed": True,
"following": False,
"abuse_flagged": False,
"voted": True,
"vote_count": 9,
"comment_count": 18,
"unread_comment_count": 0,
},
@@ -450,6 +472,10 @@ class GetThreadListTest(CommentsServiceMockMixin, ModuleStoreTestCase):
"raw_body": "Still more content",
"pinned": True,
"closed": False,
"following": False,
"abuse_flagged": True,
"voted": False,
"vote_count": 0,
"comment_count": 0,
"unread_comment_count": 0,
},

View File

@@ -141,6 +141,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
)
def test_basic(self):
self.register_get_user_response(self.user, upvoted_ids=["test_thread"])
source_threads = [{
"id": "test_thread",
"course_id": unicode(self.course.id),
@@ -152,6 +153,8 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"body": "Test body",
"pinned": False,
"closed": False,
"abuse_flaggers": [],
"votes": {"up_count": 4},
"comments_count": 5,
"unread_comments_count": 3,
}]
@@ -166,6 +169,10 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"raw_body": "Test body",
"pinned": False,
"closed": False,
"following": False,
"abuse_flagged": False,
"voted": True,
"vote_count": 4,
"comment_count": 5,
"unread_comment_count": 3,
}]
@@ -190,6 +197,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
})
def test_pagination(self):
self.register_get_user_response(self.user)
self.register_get_threads_response([], page=1, num_pages=1)
response = self.client.get(
self.url,

View File

@@ -21,6 +21,19 @@ class CommentsServiceMockMixin(object):
status=200
)
def register_get_user_response(self, user, subscribed_thread_ids=None, upvoted_ids=None):
"""Register a mock response for GET on the CS user instance endpoint"""
httpretty.register_uri(
httpretty.GET,
"http://localhost:4567/api/v1/users/{id}".format(id=user.id),
body=json.dumps({
"id": str(user.id),
"subscribed_thread_ids": subscribed_thread_ids or [],
"upvoted_ids": upvoted_ids or [],
}),
status=200
)
def assert_last_query_params(self, expected_params):
"""
Assert that the last mock request had the expected query parameters