diff --git a/lms/djangoapps/discussion/rest_api/tasks.py b/lms/djangoapps/discussion/rest_api/tasks.py index f5bb20c3d8..385e2a1f46 100644 --- a/lms/djangoapps/discussion/rest_api/tasks.py +++ b/lms/djangoapps/discussion/rest_api/tasks.py @@ -7,7 +7,7 @@ from edx_django_utils.monitoring import set_code_owner_attribute from opaque_keys.edx.locator import CourseKey from lms.djangoapps.courseware.courses import get_course_with_access from openedx.core.djangoapps.django_comment_common.comment_client.thread import Thread -from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS +from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS, ENABLE_COURSEWIDE_NOTIFICATIONS from lms.djangoapps.discussion.rest_api.discussions_notifications import DiscussionNotificationSender @@ -21,7 +21,7 @@ def send_thread_created_notification(thread_id, course_key_str, user_id): Send notification when a new thread is created """ course_key = CourseKey.from_string(course_key_str) - if not ENABLE_NOTIFICATIONS.is_enabled(course_key): + if not (ENABLE_NOTIFICATIONS.is_enabled(course_key) and ENABLE_COURSEWIDE_NOTIFICATIONS.is_enabled(course_key)): return thread = Thread(id=thread_id).retrieve() user = User.objects.get(id=user_id) diff --git a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py index 20cef7a7c0..2046aa808c 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py @@ -25,7 +25,7 @@ from openedx.core.djangoapps.django_comment_common.models import ( FORUM_ROLE_STUDENT, CourseDiscussionSettings ) -from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS +from openedx.core.djangoapps.notifications.config.waffle import ENABLE_COURSEWIDE_NOTIFICATIONS, ENABLE_NOTIFICATIONS from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -44,6 +44,7 @@ def _get_mfe_url(course_id, post_id): @httpretty.activate @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) @override_waffle_flag(ENABLE_NOTIFICATIONS, active=True) +@override_waffle_flag(ENABLE_COURSEWIDE_NOTIFICATIONS, active=True) class TestNewThreadCreatedNotification(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """ Test cases related to new_discussion_post and new_question_post notification types diff --git a/openedx/core/djangoapps/notifications/config/waffle.py b/openedx/core/djangoapps/notifications/config/waffle.py index e05487b11b..51c4df6e40 100644 --- a/openedx/core/djangoapps/notifications/config/waffle.py +++ b/openedx/core/djangoapps/notifications/config/waffle.py @@ -37,3 +37,13 @@ SHOW_NOTIFICATIONS_TRAY = CourseWaffleFlag(f"{WAFFLE_NAMESPACE}.show_notificatio # .. toggle_target_removal_date: 2024-06-01 # .. toggle_tickets: INF-902 ENABLE_NOTIFICATIONS_FILTERS = CourseWaffleFlag(f"{WAFFLE_NAMESPACE}.enable_notifications_filters", __name__) + +# .. toggle_name: notifications.enable_coursewide_notifications +# .. toggle_implementation: CourseWaffleFlag +# .. toggle_default: False +# .. toggle_description: Waffle flag to enable coursewide notifications +# .. toggle_use_cases: temporary, open_edx +# .. toggle_creation_date: 2023-10-25 +# .. toggle_target_removal_date: 2024-06-01 +# .. toggle_tickets: INF-1145 +ENABLE_COURSEWIDE_NOTIFICATIONS = CourseWaffleFlag(f"{WAFFLE_NAMESPACE}.enable_coursewide_notifications", __name__) diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index 76da8756c6..e09b4989d5 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -18,7 +18,11 @@ 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, SHOW_NOTIFICATIONS_TRAY +from openedx.core.djangoapps.notifications.config.waffle import ( + ENABLE_COURSEWIDE_NOTIFICATIONS, + ENABLE_NOTIFICATIONS, + SHOW_NOTIFICATIONS_TRAY +) from openedx.core.djangoapps.notifications.models import CourseNotificationPreference, Notification from openedx.core.djangoapps.notifications.serializers import NotificationCourseEnrollmentSerializer from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -255,7 +259,8 @@ class UserNotificationPreferenceAPITest(ModuleStoreTestCase): Test get user notification preference. """ self.client.login(username=self.user.username, password=self.TEST_PASSWORD) - response = self.client.get(self.path) + with override_waffle_flag(ENABLE_COURSEWIDE_NOTIFICATIONS, active=True): + response = self.client.get(self.path) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data, self._expected_api_response()) event_name, event_data = mock_emit.call_args[0] diff --git a/openedx/core/djangoapps/notifications/utils.py b/openedx/core/djangoapps/notifications/utils.py index 39bf8755da..597ed59f0a 100644 --- a/openedx/core/djangoapps/notifications/utils.py +++ b/openedx/core/djangoapps/notifications/utils.py @@ -3,7 +3,7 @@ Utils function for notifications app """ from common.djangoapps.student.models import CourseEnrollment -from .config.waffle import SHOW_NOTIFICATIONS_TRAY +from .config.waffle import ENABLE_COURSEWIDE_NOTIFICATIONS, SHOW_NOTIFICATIONS_TRAY def find_app_in_normalized_apps(app_name, apps_list): @@ -51,3 +51,20 @@ def get_list_in_batches(input_list, batch_size): list_length = len(input_list) for index in range(0, list_length, batch_size): yield input_list[index: index + batch_size] + + +def filter_course_wide_preferences(course_key, preferences): + """ + If course wide notifications is disabled for course, it filters course_wide + preferences from response + """ + if ENABLE_COURSEWIDE_NOTIFICATIONS.is_enabled(course_key): + return preferences + course_wide_notification_types = ['new_discussion_post', 'new_question_post'] + config = preferences['notification_preference_config'] + for app_prefs in config.values(): + notification_types = app_prefs['notification_types'] + for course_wide_type in course_wide_notification_types: + if course_wide_type in notification_types.keys(): + notification_types.pop(course_wide_type) + return preferences diff --git a/openedx/core/djangoapps/notifications/views.py b/openedx/core/djangoapps/notifications/views.py index 6d82f67f01..810aa74928 100644 --- a/openedx/core/djangoapps/notifications/views.py +++ b/openedx/core/djangoapps/notifications/views.py @@ -36,7 +36,7 @@ from .serializers import ( UserCourseNotificationPreferenceSerializer, UserNotificationPreferenceUpdateSerializer ) -from .utils import get_show_notifications_tray +from .utils import filter_course_wide_preferences, get_show_notifications_tray @allow_any_authenticated_user() @@ -183,7 +183,8 @@ class UserNotificationPreferenceView(APIView): user_preference = CourseNotificationPreference.get_updated_user_course_preferences(request.user, course_id) serializer = UserCourseNotificationPreferenceSerializer(user_preference) notification_preferences_viewed_event(request, course_id) - return Response(serializer.data) + preferences = filter_course_wide_preferences(course_id, serializer.data) + return Response(preferences) def patch(self, request, course_key_string): """