feat: added post filters in learners tab api (#31191)

Co-authored-by: adeel.tajamul <adeel.tajamul@arbisoft.com>
This commit is contained in:
Muhammad Adeel Tajamul
2022-11-03 16:53:50 +05:00
committed by GitHub
parent 605a0a66e7
commit 1a25a5d3fd
3 changed files with 189 additions and 0 deletions

View File

@@ -1003,9 +1003,15 @@ def get_learner_active_thread_list(request, course_key, query_params):
group_id = query_params.get('group_id', None)
user_id = query_params.get('user_id', None)
count_flagged = query_params.get('count_flagged', None)
if user_id is None:
return Response({'detail': 'Invalid user id'}, status=status.HTTP_400_BAD_REQUEST)
if count_flagged and not context["has_moderation_privilege"]:
raise PermissionDenied("count_flagged can only be set by users with moderation roles.")
if "flagged" in query_params.keys() and not context["has_moderation_privilege"]:
raise PermissionDenied("Flagged filter is only available for moderators")
if group_id is None:
comment_client_user = comment_client.User(id=user_id, course_id=course_key)
else:

View File

@@ -1452,6 +1452,7 @@ class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
assert response.status_code == 404
@ddt.ddt
@httpretty.activate
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class LearnerThreadViewAPITest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@@ -1601,6 +1602,160 @@ class LearnerThreadViewAPITest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
"""
assert True
@ddt.data("None", "discussion", "question")
def test_thread_type_by(self, thread_type):
"""
Tests the thread_type parameter
Arguments:
thread_type (str): Value of thread_type can be 'None',
'discussion' and 'question'
"""
threads = [make_minimal_cs_thread({
"id": "test_thread",
"course_id": str(self.course.id),
"commentable_id": "test_topic",
"user_id": str(self.user.id),
"username": self.user.username,
"created_at": "2015-04-28T00:00:00Z",
"updated_at": "2015-04-28T11:11:11Z",
"title": "Test Title",
"body": "Test body",
"votes": {"up_count": 4},
"comments_count": 5,
"unread_comments_count": 3,
})]
expected_cs_comments_response = {
"collection": threads,
"page": 1,
"num_pages": 1,
}
self.register_get_user_response(self.user)
self.register_user_active_threads(self.user.id, expected_cs_comments_response)
response = self.client.get(
self.url,
{
"course_id": str(self.course.id),
"username": self.user.username,
"thread_type": thread_type,
}
)
assert response.status_code == 200
self.assert_last_query_params({
"user_id": [str(self.user.id)],
"course_id": [str(self.course.id)],
"page": ["1"],
"per_page": ["10"],
"thread_type": [thread_type],
"sort_key": ['activity'],
"count_flagged": ["False"]
})
@ddt.data(
("last_activity_at", "activity"),
("comment_count", "comments"),
("vote_count", "votes")
)
@ddt.unpack
def test_order_by(self, http_query, cc_query):
"""
Tests the order_by parameter for active threads
Arguments:
http_query (str): Query string sent in the http request
cc_query (str): Query string used for the comments client service
"""
threads = [make_minimal_cs_thread({
"id": "test_thread",
"course_id": str(self.course.id),
"commentable_id": "test_topic",
"user_id": str(self.user.id),
"username": self.user.username,
"created_at": "2015-04-28T00:00:00Z",
"updated_at": "2015-04-28T11:11:11Z",
"title": "Test Title",
"body": "Test body",
"votes": {"up_count": 4},
"comments_count": 5,
"unread_comments_count": 3,
})]
expected_cs_comments_response = {
"collection": threads,
"page": 1,
"num_pages": 1,
}
self.register_get_user_response(self.user)
self.register_user_active_threads(self.user.id, expected_cs_comments_response)
response = self.client.get(
self.url,
{
"course_id": str(self.course.id),
"username": self.user.username,
"order_by": http_query,
}
)
assert response.status_code == 200
self.assert_last_query_params({
"user_id": [str(self.user.id)],
"course_id": [str(self.course.id)],
"page": ["1"],
"per_page": ["10"],
"sort_key": [cc_query],
"count_flagged": ["False"]
})
@ddt.data("flagged", "unanswered", "unread", "unresponded")
def test_status_by(self, post_status):
"""
Tests the post_status parameter
Arguments:
post_status (str): Value of post_status can be 'flagged',
'unanswered' and 'unread'
"""
threads = [make_minimal_cs_thread({
"id": "test_thread",
"course_id": str(self.course.id),
"commentable_id": "test_topic",
"user_id": str(self.user.id),
"username": self.user.username,
"created_at": "2015-04-28T00:00:00Z",
"updated_at": "2015-04-28T11:11:11Z",
"title": "Test Title",
"body": "Test body",
"votes": {"up_count": 4},
"comments_count": 5,
"unread_comments_count": 3,
})]
expected_cs_comments_response = {
"collection": threads,
"page": 1,
"num_pages": 1,
}
self.register_get_user_response(self.user)
self.register_user_active_threads(self.user.id, expected_cs_comments_response)
response = self.client.get(
self.url,
{
"course_id": str(self.course.id),
"username": self.user.username,
"status": post_status,
}
)
if post_status == "flagged":
assert response.status_code == 403
else:
assert response.status_code == 200
self.assert_last_query_params({
"user_id": [str(self.user.id)],
"course_id": [str(self.course.id)],
"page": ["1"],
"per_page": ["10"],
post_status: ['True'],
"sort_key": ['activity'],
"count_flagged": ["False"]
})
@ddt.ddt
@httpretty.activate

View File

@@ -574,6 +574,15 @@ class LearnerThreadView(APIView):
* count_flagged: If True, return the count of flagged comments for each thread.
(can only be used by moderators or above)
* thread_type: The type of thread to filter None, "discussion" or "question".
* order_by: Sort order for threads "last_activity_at", "comment_count" or
"vote_count".
* status: Filter for threads "flagged", "unanswered", "unread".
* group_id: Filter threads w.r.t cohorts (Cohort ID).
"""
authentication_classes = (
@@ -594,6 +603,15 @@ class LearnerThreadView(APIView):
page_num = request.GET.get('page', 1)
threads_per_page = request.GET.get('page_size', 10)
count_flagged = request.GET.get('count_flagged', False)
thread_type = request.GET.get('thread_type')
order_by = request.GET.get('order_by')
order_by_mapping = {
"last_activity_at": "activity",
"comment_count": "comments",
"vote_count": "votes"
}
order_by = order_by_mapping.get(order_by, 'activity')
post_status = request.GET.get('status', None)
discussion_id = None
username = request.GET.get('username', None)
user = get_object_or_404(User, username=username)
@@ -610,7 +628,17 @@ class LearnerThreadView(APIView):
"user_id": user.id,
"group_id": group_id,
"count_flagged": count_flagged,
"thread_type": thread_type,
"sort_key": order_by,
}
if post_status:
if post_status not in ['flagged', 'unanswered', 'unread', 'unresponded']:
raise ValidationError({
"status": [
f"Invalid value. '{post_status}' must be 'flagged', 'unanswered', 'unread' or 'unresponded"
]
})
query_params[post_status] = True
return get_learner_active_thread_list(request, course_key, query_params)