diff --git a/openedx/core/djangoapps/notifications/events.py b/openedx/core/djangoapps/notifications/events.py index 11166b841d3b..c86801a4a8eb 100644 --- a/openedx/core/djangoapps/notifications/events.py +++ b/openedx/core/djangoapps/notifications/events.py @@ -1,12 +1,13 @@ """ Events for notification app. """ from eventtracking import tracker -from common.djangoapps.track import contexts +from common.djangoapps.track import contexts NOTIFICATION_PREFERENCES_VIEWED = 'edx.notifications.preferences.viewed' NOTIFICATION_GENERATED = 'edx.notifications.generated' -NOTIFICATION_READ = 'edx.notifications.read' +NOTIFICATION_READ = 'edx.notification.read' +NOTIFICATION_APP_ALL_READ = 'edx.notifications.app_all_read' NOTIFICATION_PREFERENCES_UPDATED = 'edx.notifications.preferences.updated' @@ -74,7 +75,7 @@ def notification_generated_event(user, notification): def notification_read_event(user, notification): """ - Emit an event when a notification is read. + Emit an event when a notification app is marked read for a user. """ context = contexts.course_context_from_course_id(notification.course_id) with tracker.get_tracker().context(NOTIFICATION_READ, context): @@ -84,6 +85,19 @@ def notification_read_event(user, notification): ) +def notifications_app_all_read_event(user, app_name): + """ + Emit an event when a notification is read. + """ + tracker.emit( + NOTIFICATION_APP_ALL_READ, + { + 'user_id': str(user.id), + 'notification_app': app_name, + } + ) + + def notification_preference_update_event(user, course_id, updated_preference): """ Emit an event when a notification preference is updated. diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index 2e901116ba2b..ee0ea0c1b029 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -588,7 +588,8 @@ def setUp(self): Notification.objects.create(user=self.user, app_name=app_name, notification_type='Type A') Notification.objects.create(user=self.user, app_name=app_name, notification_type='Type B') - def test_mark_all_notifications_read_with_app_name(self): + @mock.patch("eventtracking.tracker.emit") + def test_mark_all_notifications_read_with_app_name(self, mock_emit): # Create a PATCH request to mark all notifications as read for already existing app e.g 'discussion' app_name = next(iter(COURSE_NOTIFICATION_APPS)) data = {'app_name': app_name} @@ -599,6 +600,9 @@ def test_mark_all_notifications_read_with_app_name(self): self.assertEqual(response.data, {'message': 'Notifications marked read.'}) notifications = Notification.objects.filter(user=self.user, app_name=app_name, last_read__isnull=False) self.assertEqual(notifications.count(), 2) + event_name, event_data = mock_emit.call_args[0] + self.assertEqual(event_name, 'edx.notifications.app_all_read') + self.assertEqual(event_data['notification_app'], 'discussion') def test_mark_all_notifications_read_with_invalid_app_name(self): # Create a PATCH request to mark all notifications as read for 'app_name_1' @@ -623,7 +627,7 @@ def test_mark_notification_read_with_notification_id(self, mock_emit): notifications = Notification.objects.filter(user=self.user, id=notification_id, last_read__isnull=False) self.assertEqual(notifications.count(), 1) event_name, event_data = mock_emit.call_args[0] - self.assertEqual(event_name, 'edx.notifications.read') + self.assertEqual(event_name, 'edx.notification.read') self.assertEqual(event_data.get('notification_metadata').get('notification_id'), notification_id) self.assertEqual(event_data['notification_app'], 'discussion') self.assertEqual(event_data['notification_type'], 'Type A') diff --git a/openedx/core/djangoapps/notifications/views.py b/openedx/core/djangoapps/notifications/views.py index ca355db8be04..d8e579635f86 100644 --- a/openedx/core/djangoapps/notifications/views.py +++ b/openedx/core/djangoapps/notifications/views.py @@ -22,7 +22,12 @@ from .base_notification import COURSE_NOTIFICATION_APPS from .config.waffle import ENABLE_NOTIFICATIONS -from .events import notification_preferences_viewed_event, notification_read_event, notification_preference_update_event +from .events import ( + notification_preference_update_event, + notification_preferences_viewed_event, + notification_read_event, + notifications_app_all_read_event, +) from .models import Notification from .serializers import ( NotificationCourseEnrollmentSerializer, @@ -397,13 +402,14 @@ def patch(self, request, *args, **kwargs): app_name = request.data.get('app_name', '') - if app_name and app_name in COURSE_NOTIFICATION_APPS: + if app_name in COURSE_NOTIFICATION_APPS: notifications = Notification.objects.filter( user=request.user, app_name=app_name, last_read__isnull=True, ) notifications.update(last_read=read_at) + notifications_app_all_read_event(request.user, app_name) return Response({'message': _('Notifications marked read.')}, status=status.HTTP_200_OK) return Response({'error': _('Invalid app_name or notification_id.')}, status=status.HTTP_400_BAD_REQUEST)