feat: adds waffle flag for show notifications tray (#32451)
* feat: adds waffle flag for show notifications tray * refactor: refactored notifications count api code
This commit is contained in:
@@ -17,3 +17,13 @@ WAFFLE_NAMESPACE = 'notifications'
|
||||
# .. toggle_warning: When the flag is ON, Notifications feature is enabled.
|
||||
# .. toggle_tickets: INF-866
|
||||
ENABLE_NOTIFICATIONS = CourseWaffleFlag(f'{WAFFLE_NAMESPACE}.enable_notifications', __name__)
|
||||
|
||||
# .. toggle_name: notifications.show_notifications_tray
|
||||
# .. toggle_implementation: CourseWaffleFlag
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Waffle flag to show notifications tray
|
||||
# .. toggle_use_cases: temporary, open_edx
|
||||
# .. toggle_creation_date: 2023-06-07
|
||||
# .. toggle_target_removal_date: 2023-12-07
|
||||
# .. toggle_tickets: INF-902
|
||||
SHOW_NOTIFICATIONS_TRAY = CourseWaffleFlag(f"{WAFFLE_NAMESPACE}.show_notifications_tray", __name__)
|
||||
|
||||
@@ -16,7 +16,7 @@ from rest_framework.test import APIClient, APITestCase
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
|
||||
from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS
|
||||
from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS, SHOW_NOTIFICATIONS_TRAY
|
||||
from openedx.core.djangoapps.notifications.models import (
|
||||
Notification,
|
||||
CourseNotificationPreference,
|
||||
@@ -397,31 +397,58 @@ class NotificationListAPIViewTest(APITestCase):
|
||||
self.assertEqual([data[0]['id'], data[1]['id']], [notification2.id, notification1.id])
|
||||
|
||||
|
||||
class NotificationCountViewSetTestCase(APITestCase):
|
||||
@ddt.ddt
|
||||
class NotificationCountViewSetTestCase(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the NotificationCountViewSet.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
# Create a user.
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.client = APIClient()
|
||||
|
||||
course = CourseFactory.create(
|
||||
org='testorg',
|
||||
number='testcourse',
|
||||
run='testrun'
|
||||
)
|
||||
|
||||
course_overview = CourseOverviewFactory.create(id=course.id, org='AwesomeOrg')
|
||||
self.enrollment = CourseEnrollment.objects.create(
|
||||
user=self.user,
|
||||
course=course_overview,
|
||||
is_active=True,
|
||||
mode='audit'
|
||||
)
|
||||
|
||||
self.url = reverse('notifications-count')
|
||||
|
||||
# Create some notifications for the user.
|
||||
Notification.objects.create(user=self.user, app_name='App Name 1', notification_type='Type A')
|
||||
Notification.objects.create(user=self.user, app_name='App Name 1', notification_type='Type B')
|
||||
Notification.objects.create(user=self.user, app_name='App Name 2', notification_type='Type A')
|
||||
Notification.objects.create(user=self.user, app_name='App Name 3', notification_type='Type C')
|
||||
|
||||
def test_get_unseen_notifications_count(self):
|
||||
@ddt.data((False,), (True,))
|
||||
@ddt.unpack
|
||||
def test_get_unseen_notifications_count_with_show_notifications_tray(self, show_notifications_tray_enabled):
|
||||
"""
|
||||
Test that the endpoint returns the correct count of unseen notifications.
|
||||
Test that the endpoint returns the correct count of unseen notifications and show_notifications_tray value.
|
||||
"""
|
||||
self.client.login(username=self.user.username, password='test')
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 4)
|
||||
self.assertEqual(response.data['count_by_app_name'], {'App Name 1': 2, 'App Name 2': 1, 'App Name 3': 1})
|
||||
# Enable or disable the waffle flag based on the test case data
|
||||
with override_waffle_flag(SHOW_NOTIFICATIONS_TRAY, active=show_notifications_tray_enabled):
|
||||
|
||||
# Make a request to the view
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 4)
|
||||
self.assertEqual(response.data['count_by_app_name'], {'App Name 1': 2, 'App Name 2': 1, 'App Name 3': 1})
|
||||
self.assertEqual(response.data['show_notifications_tray'], show_notifications_tray_enabled)
|
||||
|
||||
def test_get_unseen_notifications_count_for_unauthenticated_user(self):
|
||||
"""
|
||||
|
||||
@@ -4,7 +4,6 @@ Views for the notifications API.
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Count
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from pytz import UTC
|
||||
@@ -19,7 +18,7 @@ from openedx.core.djangoapps.notifications.models import (
|
||||
get_course_notification_preference_config_version
|
||||
)
|
||||
|
||||
from .config.waffle import ENABLE_NOTIFICATIONS
|
||||
from .config.waffle import ENABLE_NOTIFICATIONS, SHOW_NOTIFICATIONS_TRAY
|
||||
from .models import Notification
|
||||
from .serializers import (
|
||||
NotificationCourseEnrollmentSerializer,
|
||||
@@ -28,8 +27,6 @@ from .serializers import (
|
||||
UserNotificationPreferenceUpdateSerializer
|
||||
)
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class CourseEnrollmentListView(generics.ListAPIView):
|
||||
"""
|
||||
@@ -247,19 +244,20 @@ class NotificationListAPIView(generics.ListAPIView):
|
||||
|
||||
class NotificationCountView(APIView):
|
||||
"""
|
||||
API view for getting the unseen notifications count for a user.
|
||||
API view for getting the unseen notifications count and show_notification_tray flag for a user.
|
||||
"""
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Get the unseen notifications count for a user.
|
||||
Get the unseen notifications count and show_notification_tray flag for a user.
|
||||
|
||||
**Permissions**: User must be authenticated.
|
||||
**Response Format**:
|
||||
```json
|
||||
{
|
||||
"show_notifications_tray": (bool) show_notifications_tray,
|
||||
"count": (int) total_number_of_unseen_notifications,
|
||||
"count_by_app_name": {
|
||||
(str) app_name: (int) number_of_unseen_notifications,
|
||||
@@ -279,16 +277,26 @@ class NotificationCountView(APIView):
|
||||
)
|
||||
count_total = 0
|
||||
count_by_app_name_dict = {}
|
||||
show_notifications_tray_enabled = False
|
||||
|
||||
for item in count_by_app_name:
|
||||
app_name = item['app_name']
|
||||
count = item['count']
|
||||
|
||||
count_total += count
|
||||
count_by_app_name_dict[app_name] = count
|
||||
# Return the unseen notifications count for the user and the unseen notifications count for each app name.
|
||||
|
||||
learner_enrollments_course_ids = CourseEnrollment.objects.filter(
|
||||
user=request.user,
|
||||
is_active=True
|
||||
).values_list('course_id', flat=True)
|
||||
|
||||
for course_id in learner_enrollments_course_ids:
|
||||
if SHOW_NOTIFICATIONS_TRAY.is_enabled(course_id):
|
||||
show_notifications_tray_enabled = True
|
||||
break
|
||||
|
||||
return Response({
|
||||
"show_notifications_tray": show_notifications_tray_enabled,
|
||||
"count": count_total,
|
||||
"count_by_app_name": count_by_app_name_dict,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user