Commit 242c4c83 by wajeeha-khalid

Merge pull request #9759 from edx/jia/MA-1212

MA-1212 - Discussion API: add response_count field in GET single thread
parents 8e9e94df 3f453e89
...@@ -341,7 +341,7 @@ def get_thread_list( ...@@ -341,7 +341,7 @@ def get_thread_list(
if result_page != page: if result_page != page:
raise Http404 raise Http404
results = [ThreadSerializer(thread, context=context).data for thread in threads] results = [ThreadSerializer(thread, remove_fields=['response_count'], context=context).data for thread in threads]
ret = get_paginated_data(request, results, page, num_pages) ret = get_paginated_data(request, results, page, num_pages)
ret["text_search_rewrite"] = text_search_rewrite ret["text_search_rewrite"] = text_search_rewrite
return ret return ret
...@@ -555,7 +555,7 @@ def create_thread(request, thread_data): ...@@ -555,7 +555,7 @@ def create_thread(request, thread_data):
): ):
thread_data = thread_data.copy() thread_data = thread_data.copy()
thread_data["group_id"] = get_cohort_id(user, course_key) thread_data["group_id"] = get_cohort_id(user, course_key)
serializer = ThreadSerializer(data=thread_data, context=context) serializer = ThreadSerializer(data=thread_data, remove_fields=['response_count'], context=context)
actions_form = ThreadActionsForm(thread_data) actions_form = ThreadActionsForm(thread_data)
if not (serializer.is_valid() and actions_form.is_valid()): if not (serializer.is_valid() and actions_form.is_valid()):
raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items())) raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
...@@ -642,7 +642,8 @@ def update_thread(request, thread_id, update_data): ...@@ -642,7 +642,8 @@ def update_thread(request, thread_id, update_data):
""" """
cc_thread, context = _get_thread_and_context(request, thread_id) cc_thread, context = _get_thread_and_context(request, thread_id)
_check_editable_fields(cc_thread, update_data, context) _check_editable_fields(cc_thread, update_data, context)
serializer = ThreadSerializer(cc_thread, data=update_data, partial=True, context=context) serializer = ThreadSerializer(cc_thread, remove_fields=['response_count'], data=update_data, partial=True,
context=context)
actions_form = ThreadActionsForm(update_data) actions_form = ThreadActionsForm(update_data)
if not (serializer.is_valid() and actions_form.is_valid()): if not (serializer.is_valid() and actions_form.is_valid()):
raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items())) raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
......
...@@ -187,10 +187,13 @@ class ThreadSerializer(_ContentSerializer): ...@@ -187,10 +187,13 @@ class ThreadSerializer(_ContentSerializer):
non_endorsed_comment_list_url = serializers.SerializerMethodField("get_non_endorsed_comment_list_url") non_endorsed_comment_list_url = serializers.SerializerMethodField("get_non_endorsed_comment_list_url")
read = serializers.BooleanField(read_only=True) read = serializers.BooleanField(read_only=True)
has_endorsed = serializers.BooleanField(read_only=True, source="endorsed") has_endorsed = serializers.BooleanField(read_only=True, source="endorsed")
response_count = serializers.IntegerField(source="resp_total", read_only=True)
non_updatable_fields = NON_UPDATABLE_THREAD_FIELDS non_updatable_fields = NON_UPDATABLE_THREAD_FIELDS
# TODO: https://openedx.atlassian.net/browse/MA-1359
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
remove_fields = kwargs.pop('remove_fields', None)
super(ThreadSerializer, self).__init__(*args, **kwargs) super(ThreadSerializer, self).__init__(*args, **kwargs)
# type is an invalid class attribute name, so we must declare a # type is an invalid class attribute name, so we must declare a
# different name above and modify it here # different name above and modify it here
...@@ -200,6 +203,11 @@ class ThreadSerializer(_ContentSerializer): ...@@ -200,6 +203,11 @@ class ThreadSerializer(_ContentSerializer):
if self.object and self.object.get("pinned") is None: if self.object and self.object.get("pinned") is None:
self.object["pinned"] = False self.object["pinned"] = False
if remove_fields:
# for multiple fields in a list
for field_name in remove_fields:
self.fields.pop(field_name)
def get_group_name(self, obj): def get_group_name(self, obj):
"""Returns the name of the group identified by the thread's group_id.""" """Returns the name of the group identified by the thread's group_id."""
return self.context["group_ids_to_names"].get(obj["group_id"]) return self.context["group_ids_to_names"].get(obj["group_id"])
......
...@@ -2967,7 +2967,9 @@ class RetrieveThreadTest( ...@@ -2967,7 +2967,9 @@ class RetrieveThreadTest(
"title": "Test Title", "title": "Test Title",
"body": "Test body", "body": "Test body",
"created_at": "2015-05-29T00:00:00Z", "created_at": "2015-05-29T00:00:00Z",
"updated_at": "2015-05-29T00:00:00Z" "updated_at": "2015-05-29T00:00:00Z",
"resp_total": 0,
}) })
cs_data.update(overrides or {}) cs_data.update(overrides or {})
self.register_get_thread_response(cs_data) self.register_get_thread_response(cs_data)
...@@ -3000,9 +3002,10 @@ class RetrieveThreadTest( ...@@ -3000,9 +3002,10 @@ class RetrieveThreadTest(
"read": False, "read": False,
"has_endorsed": False, "has_endorsed": False,
"id": "test_thread", "id": "test_thread",
"type": "discussion" "type": "discussion",
"response_count": 2,
} }
self.register_thread() self.register_thread({"resp_total": 2})
self.assertEqual(get_thread(self.request, self.thread_id), expected_response_data) self.assertEqual(get_thread(self.request, self.thread_id), expected_response_data)
self.assertEqual(httpretty.last_request().method, "GET") self.assertEqual(httpretty.last_request().method, "GET")
...@@ -3039,7 +3042,8 @@ class RetrieveThreadTest( ...@@ -3039,7 +3042,8 @@ class RetrieveThreadTest(
"read": False, "read": False,
"has_endorsed": False, "has_endorsed": False,
"id": "test_thread", "id": "test_thread",
"type": "discussion" "type": "discussion",
"response_count": 0,
} }
non_author_user = UserFactory.create() # pylint: disable=attribute-defined-outside-init non_author_user = UserFactory.create() # pylint: disable=attribute-defined-outside-init
self.register_get_user_response(non_author_user) self.register_get_user_response(non_author_user)
......
...@@ -144,7 +144,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe ...@@ -144,7 +144,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
"user_id": str(self.author.id), "user_id": str(self.author.id),
"username": self.author.username, "username": self.author.username,
"read": True, "read": True,
"endorsed": True "endorsed": True,
"resp_total": 0,
} }
merged_overrides.update(overrides) merged_overrides.update(overrides)
return make_minimal_cs_thread(merged_overrides) return make_minimal_cs_thread(merged_overrides)
...@@ -179,7 +180,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe ...@@ -179,7 +180,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
"comments_count": 5, "comments_count": 5,
"unread_comments_count": 3, "unread_comments_count": 3,
"read": False, "read": False,
"endorsed": False "endorsed": False,
"response_count": None,
} }
expected = { expected = {
"id": "test_thread", "id": "test_thread",
...@@ -208,7 +210,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe ...@@ -208,7 +210,8 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
"non_endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None,
"editable_fields": ["abuse_flagged", "following", "voted"], "editable_fields": ["abuse_flagged", "following", "voted"],
"read": False, "read": False,
"has_endorsed": False "has_endorsed": False,
"response_count": None,
} }
self.assertEqual(self.serialize(thread), expected) self.assertEqual(self.serialize(thread), expected)
...@@ -248,6 +251,12 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe ...@@ -248,6 +251,12 @@ class ThreadSerializerSerializationTest(SerializerTestMixin, SharedModuleStoreTe
serialized = self.serialize(self.make_cs_content({"id": thread_id})) serialized = self.serialize(self.make_cs_content({"id": thread_id}))
self.assertEqual(serialized["following"], True) self.assertEqual(serialized["following"], True)
def test_response_count(self):
thread_data = self.make_cs_content({"resp_total": 2})
self.register_get_thread_response(thread_data)
serialized = self.serialize(Thread(id=thread_data["id"]))
self.assertEqual(serialized["response_count"], 2)
@ddt.ddt @ddt.ddt
class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase): class CommentSerializerTest(SerializerTestMixin, SharedModuleStoreTestCase):
......
...@@ -215,7 +215,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): ...@@ -215,7 +215,7 @@ class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"non_endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None,
"editable_fields": ["abuse_flagged", "following", "voted"], "editable_fields": ["abuse_flagged", "following", "voted"],
"read": False, "read": False,
"has_endorsed": False "has_endorsed": False,
}] }]
self.register_get_threads_response(source_threads, page=1, num_pages=2) self.register_get_threads_response(source_threads, page=1, num_pages=2)
response = self.client.get(self.url, {"course_id": unicode(self.course.id)}) response = self.client.get(self.url, {"course_id": unicode(self.course.id)})
...@@ -436,7 +436,7 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): ...@@ -436,7 +436,7 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"non_endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None,
"editable_fields": ["abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted"], "editable_fields": ["abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted"],
"read": False, "read": False,
"has_endorsed": False "has_endorsed": False,
} }
response = self.client.post( response = self.client.post(
self.url, self.url,
...@@ -530,7 +530,7 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest ...@@ -530,7 +530,7 @@ class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTest
"non_endorsed_comment_list_url": None, "non_endorsed_comment_list_url": None,
"editable_fields": ["abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted"], "editable_fields": ["abuse_flagged", "following", "raw_body", "title", "topic_id", "type", "voted"],
"read": False, "read": False,
"has_endorsed": False "has_endorsed": False,
} }
response = self.client.patch( # pylint: disable=no-member response = self.client.patch( # pylint: disable=no-member
self.url, self.url,
...@@ -1001,7 +1001,8 @@ class ThreadViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase) ...@@ -1001,7 +1001,8 @@ class ThreadViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase)
"read": False, "read": False,
"has_endorsed": False, "has_endorsed": False,
"id": "test_thread", "id": "test_thread",
"type": "discussion" "type": "discussion",
"response_count": 0,
} }
self.register_get_thread_response(cs_thread) self.register_get_thread_response(cs_thread)
response = self.client.get(self.url) response = self.client.get(self.url)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment