Skip to content

Commit c8e6a76

Browse files
feat: add grouping for new response notification (#37674)
1 parent a765273 commit c8e6a76

5 files changed

Lines changed: 46 additions & 4 deletions

File tree

lms/djangoapps/discussion/rest_api/discussions_notifications.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def send_new_response_notification(self):
122122
if not self.parent_id and self.creator.id != int(self.thread.user_id):
123123
context = {
124124
'email_content': clean_thread_html_body(self.comment.body),
125+
'group_by_id': str(self.thread.id),
125126
}
126127
self._populate_context_with_ids_for_mobile(context, notification_type)
127128
self._send_notification([self.thread.user_id], notification_type, extra_context=context)
@@ -229,6 +230,7 @@ def send_response_on_followed_post_notification(self):
229230
if not self.parent_id:
230231
context = {
231232
"email_content": clean_thread_html_body(self.comment.body),
233+
"group_by_id": str(self.thread.id),
232234
}
233235
notification_type = "response_on_followed_post"
234236
self._populate_context_with_ids_for_mobile(context, notification_type)

lms/djangoapps/discussion/rest_api/tests/test_tasks_v2.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def test_send_notification_to_thread_creator(self):
148148
'topic_id': None,
149149
'thread_id': 1,
150150
'comment_id': None,
151+
'group_by_id': '1',
151152
}
152153
self.assertDictEqual(args.context, expected_context)
153154
self.assertEqual(
@@ -214,6 +215,8 @@ def test_send_notification_to_followers(self, parent_id, notification_type):
214215
'thread_id': 1,
215216
'comment_id': 4 if not notification_type == 'response_on_followed_post' else None,
216217
}
218+
if notification_type == 'response_on_followed_post':
219+
expected_context['group_by_id'] = '1'
217220
if parent_id:
218221
expected_context['author_name'] = 'dummy\'s'
219222
expected_context['author_pronoun'] = 'dummy\'s'

openedx/core/djangoapps/notifications/base_notification.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class NotificationType(TypedDict):
9595
'is_core': True,
9696
'content_template': _('<{p}><{strong}>{replier_name}</{strong}> responded to your '
9797
'post <{strong}>{post_title}</{strong}></{p}>'),
98+
'grouped_content_template': _('<{p}><{strong}>{replier_name}</{strong}> and others have responded to your post '
99+
'<{strong}>{post_title}</{strong}></{p}>'),
98100
'content_context': {
99101
'post_title': 'Post title',
100102
'replier_name': 'replier name',
@@ -148,6 +150,8 @@ class NotificationType(TypedDict):
148150
'non_editable': [],
149151
'content_template': _('<{p}><{strong}>{replier_name}</{strong}> responded to a post you’re following: '
150152
'<{strong}>{post_title}</{strong}></{p}>'),
153+
'grouped_content_template': _('<{p}><{strong}>{replier_name}</{strong}> and others responded to a post you’re '
154+
'following: <{strong}>{post_title}</{strong}></{p}>'),
151155
'content_context': {
152156
'post_title': 'Post title',
153157
'replier_name': 'replier name',

openedx/core/djangoapps/notifications/grouping_notifications.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,38 @@ def group(self, new_notification, old_notification):
106106
return content_context
107107

108108

109+
@NotificationRegistry.register('new_response')
110+
class NewResponseGrouper(BaseNotificationGrouper):
111+
"""
112+
Grouper for new response on post.
113+
"""
114+
115+
def group(self, new_notification, old_notification):
116+
"""
117+
Groups new ora staff notifications based on the xblock ID.
118+
"""
119+
content_context = old_notification.content_context
120+
content_context.setdefault("grouped", True)
121+
content_context["replier_name"] = new_notification.content_context["replier_name"]
122+
return content_context
123+
124+
125+
@NotificationRegistry.register('response_on_followed_post')
126+
class NewResponseOnFollowedPostGrouper(BaseNotificationGrouper):
127+
"""
128+
Grouper for new response on post.
129+
"""
130+
131+
def group(self, new_notification, old_notification):
132+
"""
133+
Groups new ora staff notifications based on the xblock ID.
134+
"""
135+
content_context = old_notification.content_context
136+
content_context.setdefault("grouped", True)
137+
content_context["replier_name"] = new_notification.content_context["replier_name"]
138+
return content_context
139+
140+
109141
def group_user_notifications(new_notification: Notification, old_notification: Notification):
110142
"""
111143
Groups user notification based on notification type and group_id

openedx/core/djangoapps/notifications/tests/test_notification_grouping.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
BaseNotificationGrouper,
1414
NotificationRegistry,
1515
group_user_notifications,
16-
get_user_existing_notifications, NewPostGrouper
16+
get_user_existing_notifications, NewPostGrouper, NewResponseGrouper, NewResponseOnFollowedPostGrouper
1717
)
1818
from openedx.core.djangoapps.notifications.models import Notification
1919
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@@ -98,12 +98,13 @@ class TestGroupUserNotifications(ModuleStoreTestCase):
9898
"""
9999

100100
@patch('openedx.core.djangoapps.notifications.grouping_notifications.NotificationRegistry.get_grouper')
101-
def test_group_user_notifications(self, mock_get_grouper):
101+
@ddt.data(NewPostGrouper, NewResponseGrouper, NewResponseOnFollowedPostGrouper)
102+
def test_group_user_notifications(self, grouper_class, mock_get_grouper):
102103
"""
103-
Test that the function groups notifications using the appropriate grou
104+
Test that the function groups notifications using the appropriate grouping class
104105
"""
105106
# Mock the grouper
106-
mock_grouper = MagicMock(spec=NewPostGrouper)
107+
mock_grouper = MagicMock(spec=grouper_class)
107108
mock_get_grouper.return_value = mock_grouper
108109

109110
new_notification = MagicMock(spec=Notification)

0 commit comments

Comments
 (0)