def update_indexed_score(instance, instance_type, vote_action=None): """ Runs a task to update the score for a post/comment document in ES. Args: instance: A PRAW Comment or Submission (a.k.a. post) object instance_type (str): A string indicating the type of object being passed in vote_action (VoteActions): A value indicating what kind of vote action was taken """ if vote_action in (VoteActions.UPVOTE, VoteActions.CLEAR_DOWNVOTE): vote_increment = 1 elif vote_action in (VoteActions.DOWNVOTE, VoteActions.CLEAR_UPVOTE): vote_increment = -1 else: raise ValueError("Received an invalid vote action value: %s" % vote_action) if instance_type not in [POST_TYPE, COMMENT_TYPE]: return content_id = (gen_post_id(instance.id) if instance_type == POST_TYPE else gen_comment_id(instance.id)) increment_document_integer_field.delay( content_id, field_name="score", incr_amount=vote_increment, object_type=instance_type, )
def test_set_comment_to_deleted(mocker, reddit_comment_obj): """ Test that set_comment_to_deleted calls the indexing task to update a comment's deleted property and calls another task to decrement the parent post's comment count """ patched_partial_update_task = mocker.patch( "search.task_helpers.update_document_with_partial" ) patched_increment_task = mocker.patch( "search.task_helpers.increment_document_integer_field" ) set_comment_to_deleted(reddit_comment_obj) assert patched_partial_update_task.delay.called is True assert patched_partial_update_task.delay.call_args[0] == ( gen_comment_id(reddit_comment_obj.id), {"deleted": True}, COMMENT_TYPE, ) assert patched_increment_task.delay.called is True assert patched_increment_task.delay.call_args[0] == ( gen_post_id(reddit_comment_obj.submission.id), ) assert patched_increment_task.delay.call_args[1] == { "field_name": "num_comments", "incr_amount": -1, "object_type": POST_TYPE, }
def test_update_post_removal_status( mocker, reddit_submission_obj, removal_status, expected_removed_arg ): """ Test that update_post_removal_status calls the indexing task with the right parameters and calls an additional task to update child comment removal status """ patched_task = mocker.patch("search.task_helpers.update_document_with_partial") patched_comment_update_func = mocker.patch( "search.task_helpers.update_field_for_all_post_comments" ) patched_reddit_object_removed = mocker.patch( "search.task_helpers.is_reddit_object_removed" ) patched_reddit_object_removed.return_value = removal_status update_post_removal_status(reddit_submission_obj) assert patched_reddit_object_removed.called is True assert patched_task.delay.called is True assert patched_task.delay.call_args[0] == ( gen_post_id(reddit_submission_obj.id), {"removed": expected_removed_arg}, POST_TYPE, ) patched_comment_update_func.assert_called_with( reddit_submission_obj, field_name="parent_post_removed", field_value=expected_removed_arg, )
def test_index_new_comment(mocker): """ Test that index_new_comment calls indexing tasks with the right parameters """ fake_serialized_data = {"serialized": "comment"} comment = CommentFactory.create() mock_submission = mocker.Mock(id="123") mock_comment = mocker.Mock(id=comment.comment_id, submission=mock_submission) patched_serialize_func = mocker.patch( "search.task_helpers.ESCommentSerializer.to_representation", return_value=fake_serialized_data, ) patched_create_task = mocker.patch("search.task_helpers.create_document") patched_increment_task = mocker.patch( "search.task_helpers.increment_document_integer_field" ) index_new_comment(mock_comment) patched_serialize_func.assert_called_once_with(comment) assert patched_create_task.delay.called is True assert patched_create_task.delay.call_args[0] == ( gen_comment_id(mock_comment.id), fake_serialized_data, ) assert patched_increment_task.delay.called is True assert patched_increment_task.delay.call_args[0] == ( gen_post_id(mock_submission.id), ) assert patched_increment_task.delay.call_args[1] == { "field_name": "num_comments", "incr_amount": 1, "object_type": POST_TYPE, }
def index_new_post(post_obj): """ Serializes a post object and runs a task to create an ES document for it. Args: post_obj (channels.proxies.PostProxy): A proxied post/submission """ post = post_obj._self_post # pylint: disable=protected-access data = ESPostSerializer(instance=post).data create_post_document.delay(gen_post_id(post.post_id), data)
def set_post_to_deleted(post_obj): """ Sets a post to deleted and updates child comments to be deleted as well. Args: post_obj (praw.models.reddit.submission.Submission): A PRAW post ('submission') object """ update_document_with_partial.delay(gen_post_id(post_obj.id), {"deleted": True}, POST_TYPE) update_field_for_all_post_comments(post_obj, field_name="deleted", field_value=True)
def test_update_indexed_score( mocker, reddit_submission_obj, vote_action, expected_increment ): """ Test that update_indexed_score calls the indexing task with the right parameters """ patched_task = mocker.patch("search.task_helpers.increment_document_integer_field") update_indexed_score(reddit_submission_obj, POST_TYPE, vote_action=vote_action) assert patched_task.delay.called is True assert patched_task.delay.call_args[0] == (gen_post_id(reddit_submission_obj.id),) assert patched_task.delay.call_args[1] == { "field_name": "score", "incr_amount": expected_increment, "object_type": POST_TYPE, }
def test_update_post_text(mocker, reddit_submission_obj): """ Test that update_post_text calls the indexing task with the right parameters """ patched_task = mocker.patch("search.task_helpers.update_document_with_partial") update_post_text(reddit_submission_obj) assert patched_task.delay.called is True assert patched_task.delay.call_args[0] == ( gen_post_id(reddit_submission_obj.id), { "text": reddit_submission_obj.selftext, "plain_text": render_article_text(reddit_submission_obj.article_content), }, POST_TYPE, )
def update_post_text(post_obj): """ Serializes post object text and runs a task to update the text for the associated ES document. Args: post_obj (praw.models.reddit.submission.Submission): A PRAW post ('submission') object """ update_document_with_partial.delay( gen_post_id(post_obj.id), { "plain_text": render_article_text(post_obj.article_content), "text": post_obj.selftext, }, POST_TYPE, )
def _update_parent_post_comment_count(comment_obj, incr_amount=1): """ Updates the comment count for a post object (retrieved via a comment object) and runs a task to update that count for the associated ES document. Args: comment_obj (praw.models.reddit.comment.Comment): A PRAW comment object incr_amount (int): The amount to increment to count """ post_obj = comment_obj.submission increment_document_integer_field.delay( gen_post_id(post_obj.id), field_name="num_comments", incr_amount=incr_amount, object_type=POST_TYPE, )
def test_update_post_comment_count( mocker, reddit_comment_obj, update_comment_count_func, expected_increment ): """ Test that update_post_removal_status calls the indexing task with the right parameters """ patched_task = mocker.patch("search.task_helpers.increment_document_integer_field") update_comment_count_func(reddit_comment_obj) assert patched_task.delay.called is True assert patched_task.delay.call_args[0] == ( gen_post_id(reddit_comment_obj.submission.id), ) assert patched_task.delay.call_args[1] == { "field_name": "num_comments", "incr_amount": expected_increment, "object_type": POST_TYPE, }
def update_post_removal_status(post_obj): """ Serializes the removal status for a post object and runs a task to update that status for the associated ES document. Args: post_obj (praw.models.reddit.submission.Submission): A PRAW post ('submission') object """ update_document_with_partial.delay( gen_post_id(post_obj.id), {"removed": is_reddit_object_removed(post_obj)}, POST_TYPE, ) update_field_for_all_post_comments( post_obj, field_name="parent_post_removed", field_value=is_reddit_object_removed(post_obj), )
def serialize_post_for_bulk(post_obj): """ Serialize a reddit Submission for a bulk API request Args: post (channels.models.Post): A Post object Returns: dict: the serialized post """ try: return { "_id": gen_post_id(post_obj.post_id), **ESPostSerializer(instance=post_obj).data, } except NotFound: log.exception("Reddit post not found: %s", post_obj.id) raise
def test_index_new_post(mocker): """ Test that index_new_post calls the indexing task with the right parameters """ fake_serialized_data = {"serialized": "post"} mock_post = mocker.Mock(post_id="abc") mock_post_proxy = mocker.Mock(_self_post=mock_post) patched_serialize_func = mocker.patch( "search.task_helpers.ESPostSerializer.to_representation", return_value=fake_serialized_data, ) patched_task = mocker.patch("search.task_helpers.create_post_document") index_new_post(mock_post_proxy) patched_serialize_func.assert_called_once_with(mock_post) assert patched_task.delay.called is True assert patched_task.delay.call_args[0] == ( gen_post_id(mock_post.post_id), fake_serialized_data, )