diff --git a/lms/djangoapps/discussion/rest_api/discussions_notifications.py b/lms/djangoapps/discussion/rest_api/discussions_notifications.py index 4012ed7e925d..c8c0f3a980fe 100644 --- a/lms/djangoapps/discussion/rest_api/discussions_notifications.py +++ b/lms/djangoapps/discussion/rest_api/discussions_notifications.py @@ -240,8 +240,7 @@ def send_new_response_endorsed_notification(self): response on his thread has been endorsed """ context = { - "author_name": self.creator.username, - "post_title": self.thread.title + "username": self.creator.username, } self._send_notification([self.thread.user_id], "response_endorsed_on_thread", context) diff --git a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py index 9e5a5bc79a9f..96cd14683c12 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py @@ -13,8 +13,11 @@ from common.djangoapps.student.models import CourseEnrollment from common.djangoapps.student.tests.factories import StaffFactory, UserFactory from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory -from lms.djangoapps.discussion.rest_api.tasks import send_response_notifications, send_thread_created_notification -from lms.djangoapps.discussion.rest_api.tests.utils import ThreadMock, make_minimal_cs_thread +from lms.djangoapps.discussion.rest_api.tasks import ( + send_response_notifications, + send_thread_created_notification, + send_response_endorsed_notification) +from lms.djangoapps.discussion.rest_api.tests.utils import ThreadMock, make_minimal_cs_thread, make_minimal_cs_comment from openedx.core.djangoapps.course_groups.models import CohortMembership, CourseCohortsSettings from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.djangoapps.discussions.models import DiscussionTopicLink @@ -158,6 +161,23 @@ def _create_thread(self, thread_type="discussion", group_id=None): self.register_get_thread_response(thread) return thread + def _create_response(self, thread_id): + """ + Create a response + """ + response = make_minimal_cs_comment({ + "id": 2, + "thread_id": thread_id, + "raw_body": "

response

", + "user_id": str(self.student_role.users.first().id), + "username": self.student_role.users.first().username, + "course_id": str(self.course.id), + "parent_id": None, + "endorsed": False, + }) + self.register_get_comment_response(response) + return response + def test_basic(self): """ Left empty intentionally. This test case is inherited from DiscussionAPIViewTestMixin @@ -193,6 +213,33 @@ def test_notification_is_send_to_all_enrollments(self, notification_type): notification_audience_filters = {} assert notification_audience_filters == course_notification_data.audience_filters + def test_notification_sent_to_thread_author_on_response_endorsement(self): + """ + Test that a notification is sent to the thread author when a response on their thread is endorsed. + """ + self._assign_enrollments() + thread = self._create_thread() + response = self._create_response(thread_id=thread['id']) + handler = mock.Mock() + USER_NOTIFICATION_REQUESTED.connect(handler) + send_response_endorsed_notification(thread['id'], str(self.course.id), str(self.student_role.users.first().id)) + self.assertEqual(handler.call_count, 1) + notification_data = handler.call_args_list[0][1]['notification_data'] + self.assertEqual([int(user_id) for user_id in notification_data.user_ids], [int(thread['user_id'])]) # Target only the thread author + self.assertEqual(notification_data.notification_type, 'response_endorsed_on_thread') + + expected_context = { + 'replier_name': response['username'], + 'post_title': 'Test Title', + 'course_name': self.course.display_name, + 'sender_id': int(response['user_id']), + 'username': response['username'], + } + self.assertDictEqual(notification_data.context, expected_context) + self.assertEqual(notification_data.content_url, _get_mfe_url(self.course.id, thread['id'])) + self.assertEqual(notification_data.app_name, 'discussion') + self.assertEqual('response_endorsed_on_thread', notification_data.notification_type) + @ddt.data( ('cohort_1', 'new_question_post'), ('cohort_1', 'new_discussion_post'), @@ -478,6 +525,7 @@ class TestSendCommentNotification(DiscussionAPIViewTestMixin, ModuleStoreTestCas """ Test case to send new_comment notification """ + def setUp(self): super().setUp() httpretty.reset() diff --git a/openedx/core/djangoapps/notifications/base_notification.py b/openedx/core/djangoapps/notifications/base_notification.py index b028be482fca..07d74d79d676 100644 --- a/openedx/core/djangoapps/notifications/base_notification.py +++ b/openedx/core/djangoapps/notifications/base_notification.py @@ -123,7 +123,7 @@ '<{strong}>{post_title}'), 'content_context': { 'post_title': 'Post title', - 'username': 'Post author name', + 'username': 'Response author name', }, 'email_template': '', 'filters': [FILTER_AUDIT_EXPIRED_USERS_WITH_NO_ROLE] diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index 90b3fd39d3d8..ccc63eeb2516 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -234,7 +234,8 @@ def _expected_api_response(self, course=None): 'new_comment', 'new_response', 'response_on_followed_post', - 'comment_on_followed_post' + 'comment_on_followed_post', + 'response_endorsed_on_thread' ], 'notification_types': { 'core': {