Commit 7a9fea02 by wajeeha-khalid

Merge pull request #11450 from edx/jia/MA-1985

MA-1985 add analytics event to thread/comment vote
parents 1a66726a 72aeb2c8
...@@ -25,7 +25,11 @@ from discussion_api.permissions import ( ...@@ -25,7 +25,11 @@ from discussion_api.permissions import (
get_initializable_thread_fields, get_initializable_thread_fields,
) )
from discussion_api.serializers import CommentSerializer, ThreadSerializer, get_context from discussion_api.serializers import CommentSerializer, ThreadSerializer, get_context
from django_comment_client.base.views import track_comment_created_event, track_thread_created_event from django_comment_client.base.views import (
track_comment_created_event,
track_thread_created_event,
track_voted_event,
)
from django_comment_common.signals import ( from django_comment_common.signals import (
thread_created, thread_created,
thread_edited, thread_edited,
...@@ -496,7 +500,7 @@ def _check_editable_fields(cc_content, data, context): ...@@ -496,7 +500,7 @@ def _check_editable_fields(cc_content, data, context):
) )
def _do_extra_actions(api_content, cc_content, request_fields, actions_form, context): def _do_extra_actions(api_content, cc_content, request_fields, actions_form, context, request):
""" """
Perform any necessary additional actions related to content creation or Perform any necessary additional actions related to content creation or
update that require a separate comments service request. update that require a separate comments service request.
...@@ -505,25 +509,44 @@ def _do_extra_actions(api_content, cc_content, request_fields, actions_form, con ...@@ -505,25 +509,44 @@ def _do_extra_actions(api_content, cc_content, request_fields, actions_form, con
if field in request_fields and form_value != api_content[field]: if field in request_fields and form_value != api_content[field]:
api_content[field] = form_value api_content[field] = form_value
if field == "following": if field == "following":
if form_value: _handle_following_field(form_value, context["cc_requester"], cc_content)
context["cc_requester"].follow(cc_content)
else:
context["cc_requester"].unfollow(cc_content)
elif field == "abuse_flagged": elif field == "abuse_flagged":
if form_value: _handle_abuse_flagged_field(form_value, context["cc_requester"], cc_content)
cc_content.flagAbuse(context["cc_requester"], cc_content) elif field == "voted":
else: _handle_voted_field(form_value, cc_content, api_content, request, context)
cc_content.unFlagAbuse(context["cc_requester"], cc_content, removeAll=False)
else: else:
assert field == "voted" raise ValidationError({field: ["Invalid Key"]})
signal = thread_voted if cc_content.type == 'thread' else comment_voted
signal.send(sender=None, user=context["request"].user, post=cc_content)
if form_value: def _handle_following_field(form_value, user, cc_content):
context["cc_requester"].vote(cc_content, "up") """follow/unfollow thread for the user"""
api_content["vote_count"] += 1 if form_value:
else: user.follow(cc_content)
context["cc_requester"].unvote(cc_content) else:
api_content["vote_count"] -= 1 user.unfollow(cc_content)
def _handle_abuse_flagged_field(form_value, user, cc_content):
"""mark or unmark thread/comment as abused"""
if form_value:
cc_content.flagAbuse(user, cc_content)
else:
cc_content.unFlagAbuse(user, cc_content, removeAll=False)
def _handle_voted_field(form_value, cc_content, api_content, request, context):
"""vote or undo vote on thread/comment"""
signal = thread_voted if cc_content.type == 'thread' else comment_voted
signal.send(sender=None, user=context["request"].user, post=cc_content)
if form_value:
context["cc_requester"].vote(cc_content, "up")
api_content["vote_count"] += 1
else:
context["cc_requester"].unvote(cc_content)
api_content["vote_count"] -= 1
track_voted_event(
request, context["course"], cc_content, vote_value="up", undo_vote=False if form_value else True
)
def create_thread(request, thread_data): def create_thread(request, thread_data):
...@@ -568,7 +591,7 @@ def create_thread(request, thread_data): ...@@ -568,7 +591,7 @@ def create_thread(request, thread_data):
cc_thread = serializer.instance cc_thread = serializer.instance
thread_created.send(sender=None, user=user, post=cc_thread) thread_created.send(sender=None, user=user, post=cc_thread)
api_thread = serializer.data api_thread = serializer.data
_do_extra_actions(api_thread, cc_thread, thread_data.keys(), actions_form, context) _do_extra_actions(api_thread, cc_thread, thread_data.keys(), actions_form, context, request)
track_thread_created_event(request, course, cc_thread, actions_form.cleaned_data["following"]) track_thread_created_event(request, course, cc_thread, actions_form.cleaned_data["following"])
...@@ -609,7 +632,7 @@ def create_comment(request, comment_data): ...@@ -609,7 +632,7 @@ def create_comment(request, comment_data):
cc_comment = serializer.instance cc_comment = serializer.instance
comment_created.send(sender=None, user=request.user, post=cc_comment) comment_created.send(sender=None, user=request.user, post=cc_comment)
api_comment = serializer.data api_comment = serializer.data
_do_extra_actions(api_comment, cc_comment, comment_data.keys(), actions_form, context) _do_extra_actions(api_comment, cc_comment, comment_data.keys(), actions_form, context, request)
track_comment_created_event(request, context["course"], cc_comment, cc_thread["commentable_id"], followed=False) track_comment_created_event(request, context["course"], cc_comment, cc_thread["commentable_id"], followed=False)
...@@ -646,7 +669,7 @@ def update_thread(request, thread_id, update_data): ...@@ -646,7 +669,7 @@ def update_thread(request, thread_id, update_data):
# signal to update Teams when a user edits a thread # signal to update Teams when a user edits a thread
thread_edited.send(sender=None, user=request.user, post=cc_thread) thread_edited.send(sender=None, user=request.user, post=cc_thread)
api_thread = serializer.data api_thread = serializer.data
_do_extra_actions(api_thread, cc_thread, update_data.keys(), actions_form, context) _do_extra_actions(api_thread, cc_thread, update_data.keys(), actions_form, context, request)
return api_thread return api_thread
...@@ -690,7 +713,7 @@ def update_comment(request, comment_id, update_data): ...@@ -690,7 +713,7 @@ def update_comment(request, comment_id, update_data):
serializer.save() serializer.save()
comment_edited.send(sender=None, user=request.user, post=cc_comment) comment_edited.send(sender=None, user=request.user, post=cc_comment)
api_comment = serializer.data api_comment = serializer.data
_do_extra_actions(api_comment, cc_comment, update_data.keys(), actions_form, context) _do_extra_actions(api_comment, cc_comment, update_data.keys(), actions_form, context, request)
return api_comment return api_comment
......
...@@ -2107,7 +2107,8 @@ class UpdateThreadTest( ...@@ -2107,7 +2107,8 @@ class UpdateThreadTest(
@ddt.data(*itertools.product([True, False], [True, False])) @ddt.data(*itertools.product([True, False], [True, False]))
@ddt.unpack @ddt.unpack
def test_voted(self, current_vote_status, new_vote_status): @mock.patch("eventtracking.tracker.emit")
def test_voted(self, current_vote_status, new_vote_status, mock_emit):
""" """
Test attempts to edit the "voted" field. Test attempts to edit the "voted" field.
...@@ -2144,6 +2145,22 @@ class UpdateThreadTest( ...@@ -2144,6 +2145,22 @@ class UpdateThreadTest(
expected_request_data["value"] = ["up"] expected_request_data["value"] = ["up"]
self.assertEqual(actual_request_data, expected_request_data) self.assertEqual(actual_request_data, expected_request_data)
event_name, event_data = mock_emit.call_args[0]
self.assertEqual(event_name, "edx.forum.thread.voted")
self.assertEqual(
event_data,
{
'undo_vote': not new_vote_status,
'url': '',
'target_username': self.user.username,
'vote_value': 'up',
'user_forums_roles': [FORUM_ROLE_STUDENT],
'user_course_roles': [],
'commentable_id': 'original_topic',
'id': 'test_thread'
}
)
@ddt.data(*itertools.product([True, False], [True, False], [True, False])) @ddt.data(*itertools.product([True, False], [True, False], [True, False]))
@ddt.unpack @ddt.unpack
def test_vote_count(self, current_vote_status, first_vote, second_vote): def test_vote_count(self, current_vote_status, first_vote, second_vote):
...@@ -2499,7 +2516,8 @@ class UpdateCommentTest( ...@@ -2499,7 +2516,8 @@ class UpdateCommentTest(
@ddt.data(*itertools.product([True, False], [True, False])) @ddt.data(*itertools.product([True, False], [True, False]))
@ddt.unpack @ddt.unpack
def test_voted(self, current_vote_status, new_vote_status): @mock.patch("eventtracking.tracker.emit")
def test_voted(self, current_vote_status, new_vote_status, mock_emit):
""" """
Test attempts to edit the "voted" field. Test attempts to edit the "voted" field.
...@@ -2539,6 +2557,23 @@ class UpdateCommentTest( ...@@ -2539,6 +2557,23 @@ class UpdateCommentTest(
expected_request_data["value"] = ["up"] expected_request_data["value"] = ["up"]
self.assertEqual(actual_request_data, expected_request_data) self.assertEqual(actual_request_data, expected_request_data)
event_name, event_data = mock_emit.call_args[0]
self.assertEqual(event_name, "edx.forum.response.voted")
self.assertEqual(
event_data,
{
'undo_vote': not new_vote_status,
'url': '',
'target_username': self.user.username,
'vote_value': 'up',
'user_forums_roles': [FORUM_ROLE_STUDENT],
'user_course_roles': [],
'commentable_id': 'dummy',
'id': 'test_comment'
}
)
@ddt.data(*itertools.product([True, False], [True, False], [True, False])) @ddt.data(*itertools.product([True, False], [True, False], [True, False]))
@ddt.unpack @ddt.unpack
def test_vote_count(self, current_vote_status, first_vote, second_vote): def test_vote_count(self, current_vote_status, first_vote, second_vote):
......
...@@ -358,6 +358,7 @@ def make_minimal_cs_comment(overrides=None): ...@@ -358,6 +358,7 @@ def make_minimal_cs_comment(overrides=None):
ret = { ret = {
"type": "comment", "type": "comment",
"id": "dummy", "id": "dummy",
"commentable_id": "dummy",
"thread_id": "dummy", "thread_id": "dummy",
"parent_id": None, "parent_id": None,
"user_id": "0", "user_id": "0",
......
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