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:
ayesha waris
2023-06-15 14:38:46 +05:00
committed by GitHub
parent bc8576a9bb
commit d3b1ce176a
3 changed files with 61 additions and 16 deletions

View File

@@ -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__)

View File

@@ -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):
"""

View File

@@ -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,
})