feat: update/create notifiction pref while sending notifications (#32665)
* feat: update user pref while sending notifications * feat: added flag and bulk create in task
This commit is contained in:
@@ -11,7 +11,12 @@ from edx_django_utils.monitoring import set_code_owner_attribute
|
||||
from pytz import UTC
|
||||
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from openedx.core.djangoapps.notifications.models import CourseNotificationPreference, Notification
|
||||
from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS
|
||||
from openedx.core.djangoapps.notifications.models import (
|
||||
CourseNotificationPreference,
|
||||
Notification,
|
||||
get_course_notification_preference_config_version
|
||||
)
|
||||
|
||||
logger = get_task_logger(__name__)
|
||||
|
||||
@@ -78,6 +83,8 @@ def send_notifications(user_ids, course_key, app_name, notification_type, contex
|
||||
"""
|
||||
Send notifications to the users.
|
||||
"""
|
||||
if not ENABLE_NOTIFICATIONS.is_enabled(course_key):
|
||||
return
|
||||
user_ids = list(set(user_ids))
|
||||
|
||||
# check if what is preferences of user and make decision to send notification or not
|
||||
@@ -85,8 +92,10 @@ def send_notifications(user_ids, course_key, app_name, notification_type, contex
|
||||
user_id__in=user_ids,
|
||||
course_id=course_key,
|
||||
)
|
||||
preferences = create_notification_pref_if_not_exists(user_ids, preferences, course_key)
|
||||
notifications = []
|
||||
for preference in preferences:
|
||||
preference = update_user_preference(preference, preference.user, course_key)
|
||||
if preference and preference.get_web_config(app_name, notification_type):
|
||||
notifications.append(Notification(
|
||||
user_id=preference.user_id,
|
||||
@@ -98,3 +107,34 @@ def send_notifications(user_ids, course_key, app_name, notification_type, contex
|
||||
))
|
||||
# send notification to users but use bulk_create
|
||||
Notification.objects.bulk_create(notifications)
|
||||
|
||||
|
||||
def update_user_preference(preference: CourseNotificationPreference, user, course_id):
|
||||
"""
|
||||
Update user preference if config version is changed.
|
||||
"""
|
||||
current_version = get_course_notification_preference_config_version()
|
||||
if preference.config_version != current_version:
|
||||
return preference.get_updated_user_course_preferences(user, course_id)
|
||||
return preference
|
||||
|
||||
|
||||
def create_notification_pref_if_not_exists(user_ids, preferences, course_id):
|
||||
"""
|
||||
Create notification preference if not exist.
|
||||
"""
|
||||
new_preferences = []
|
||||
|
||||
for user_id in user_ids:
|
||||
if not any(preference.user_id == user_id for preference in preferences):
|
||||
new_preferences.append(CourseNotificationPreference(
|
||||
user_id=user_id,
|
||||
course_id=course_id,
|
||||
))
|
||||
logger.info('Creating new notification preference for user because it does not exist.')
|
||||
if new_preferences:
|
||||
# ignoring conflicts because it is possible that preference is already created by another process
|
||||
# conflicts may arise because of constraint on user_id and course_id fields in model
|
||||
CourseNotificationPreference.objects.bulk_create(new_preferences, ignore_conflicts=True)
|
||||
preferences = preferences + new_preferences
|
||||
return preferences
|
||||
|
||||
78
openedx/core/djangoapps/notifications/tests/test_tasks.py
Normal file
78
openedx/core/djangoapps/notifications/tests/test_tasks.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""
|
||||
Tests for notifications tasks.
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from ..config.waffle import ENABLE_NOTIFICATIONS
|
||||
|
||||
from ..models import CourseNotificationPreference
|
||||
from ..tasks import create_notification_pref_if_not_exists, update_user_preference
|
||||
|
||||
|
||||
@patch('openedx.core.djangoapps.notifications.models.COURSE_NOTIFICATION_CONFIG_VERSION', 1)
|
||||
class TestNotificationsTasks(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for notifications tasks.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Create a course and users for the course.
|
||||
"""
|
||||
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.user_1 = UserFactory()
|
||||
self.user_2 = UserFactory()
|
||||
self.course_1 = CourseFactory.create(
|
||||
org='testorg',
|
||||
number='testcourse',
|
||||
run='testrun'
|
||||
)
|
||||
self.course_2 = CourseFactory.create(
|
||||
org='testorg',
|
||||
number='testcourse_2',
|
||||
run='testrun'
|
||||
)
|
||||
self.preference_v1 = CourseNotificationPreference.objects.create(
|
||||
user_id=self.user.id,
|
||||
course_id=self.course_1.id,
|
||||
config_version=0,
|
||||
)
|
||||
self.preference_v2 = CourseNotificationPreference.objects.create(
|
||||
user_id=self.user.id,
|
||||
course_id=self.course_2.id,
|
||||
config_version=1,
|
||||
)
|
||||
|
||||
def test_update_user_preference(self):
|
||||
"""
|
||||
Test whether update_user_preference updates the preference with the latest config version.
|
||||
"""
|
||||
# Test whether update_user_preference updates the preference with a different config version
|
||||
updated_preference = update_user_preference(self.preference_v1, self.user, self.course_1.id)
|
||||
self.assertEqual(updated_preference.config_version, 1)
|
||||
|
||||
# Test whether update_user_preference does not update the preference if the config version is the same
|
||||
updated_preference = update_user_preference(self.preference_v2, self.user, self.course_2.id)
|
||||
self.assertEqual(updated_preference.config_version, 1)
|
||||
|
||||
@override_waffle_flag(ENABLE_NOTIFICATIONS, active=True)
|
||||
def test_create_notification_pref_if_not_exists(self):
|
||||
"""
|
||||
Test whether create_notification_pref_if_not_exists creates a new preference if it doesn't exist.
|
||||
"""
|
||||
# Test whether create_notification_pref_if_not_exists creates a new preference if it doesn't exist
|
||||
user_ids = [self.user.id, self.user_1.id, self.user_2.id]
|
||||
preferences = [self.preference_v2]
|
||||
updated_preferences = create_notification_pref_if_not_exists(user_ids, preferences, self.course_2.id)
|
||||
self.assertEqual(len(updated_preferences), 3) # Should have created two new preferences
|
||||
|
||||
# Test whether create_notification_pref_if_not_exists doesn't create a new preference if it already exists
|
||||
updated_preferences = create_notification_pref_if_not_exists(user_ids, preferences, self.course_2.id)
|
||||
self.assertEqual(len(updated_preferences), 3) # No new preferences should be created this time
|
||||
Reference in New Issue
Block a user