feat: added unsubscribe url in digest header (#35319)
This commit is contained in:
committed by
GitHub
parent
ca46c20abb
commit
00772693ef
@@ -7,7 +7,6 @@ import json
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
from pytz import utc
|
||||
from waffle import get_waffle_flag_model # pylint: disable=invalid-django-waffle-import
|
||||
|
||||
@@ -20,7 +19,10 @@ from openedx.core.djangoapps.notifications.base_notification import (
|
||||
)
|
||||
from openedx.core.djangoapps.notifications.config.waffle import ENABLE_EMAIL_NOTIFICATIONS
|
||||
from openedx.core.djangoapps.notifications.email_notifications import EmailCadence
|
||||
from openedx.core.djangoapps.notifications.models import CourseNotificationPreference
|
||||
from openedx.core.djangoapps.notifications.models import (
|
||||
CourseNotificationPreference,
|
||||
get_course_notification_preference_config_version
|
||||
)
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from .notification_icons import NotificationTypeIcons
|
||||
@@ -71,15 +73,7 @@ def get_unsubscribe_link(username, patch):
|
||||
"""
|
||||
encrypted_username = encrypt_string(username)
|
||||
encrypted_patch = encrypt_object(patch)
|
||||
kwargs = {
|
||||
'username': encrypted_username,
|
||||
'patch': encrypted_patch
|
||||
}
|
||||
relative_url = reverse('preference_update_from_encrypted_username_view', kwargs=kwargs)
|
||||
protocol = 'https://'
|
||||
if settings.DEBUG:
|
||||
protocol = 'http://'
|
||||
return f"{protocol}{settings.LMS_BASE}{relative_url}"
|
||||
return f"{settings.LEARNING_MICROFRONTEND_URL}/preferences-unsubscribe/{encrypted_username}/{encrypted_patch}"
|
||||
|
||||
|
||||
def create_email_template_context(username):
|
||||
@@ -363,6 +357,14 @@ def update_user_preferences_from_patch(encrypted_username, encrypted_patch):
|
||||
return COURSE_NOTIFICATION_APPS[app_name]['core_email_cadence']
|
||||
return COURSE_NOTIFICATION_TYPES[notification_type]['email_cadence']
|
||||
|
||||
def get_updated_preference(pref):
|
||||
"""
|
||||
Update preference if config version doesn't match
|
||||
"""
|
||||
if pref.config_version != get_course_notification_preference_config_version():
|
||||
pref = pref.get_user_course_preference(pref.user_id, pref.course_id)
|
||||
return pref
|
||||
|
||||
course_ids = CourseEnrollment.objects.filter(user=user).values_list('course_id', flat=True)
|
||||
CourseNotificationPreference.objects.bulk_create(
|
||||
[
|
||||
@@ -375,6 +377,7 @@ def update_user_preferences_from_patch(encrypted_username, encrypted_patch):
|
||||
|
||||
# pylint: disable=too-many-nested-blocks
|
||||
for preference in preferences:
|
||||
preference = get_updated_preference(preference)
|
||||
preference_json = preference.notification_preference_config
|
||||
for app_name, app_prefs in preference_json.items():
|
||||
if not is_name_match(app_name, app_value):
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
Notification Settings
|
||||
</a>
|
||||
<a href="{{unsubscribe_url}}" rel="noopener noreferrer" target="_blank" style="color: black; margin-left: 1rem">
|
||||
Unsubscribe
|
||||
Unsubscribe from email digest for learning activity
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
style="background: #00262b; color: white; width: 100%; padding: 1.5rem"
|
||||
>
|
||||
<tbody>
|
||||
<tr align="right">
|
||||
<td>
|
||||
<a href="{{unsubscribe_url}}" rel="noopener noreferrer" target="_blank" style="color: white; text-decoration: none; font-size: 12px; line-height: 10px">
|
||||
Unsubscribe
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td>
|
||||
<img src="{{ logo_url }}" style="width: 64px" height="auto" alt="logo_url" />
|
||||
|
||||
@@ -28,9 +28,13 @@ from openedx.core.djangoapps.django_comment_common.models import (
|
||||
)
|
||||
from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS
|
||||
from openedx.core.djangoapps.notifications.email_notifications import EmailCadence
|
||||
from openedx.core.djangoapps.notifications.models import CourseNotificationPreference, Notification
|
||||
from openedx.core.djangoapps.notifications.models import (
|
||||
CourseNotificationPreference,
|
||||
Notification,
|
||||
get_course_notification_preference_config_version
|
||||
)
|
||||
from openedx.core.djangoapps.notifications.serializers import NotificationCourseEnrollmentSerializer
|
||||
from openedx.core.djangoapps.notifications.email.utils import get_unsubscribe_link
|
||||
from openedx.core.djangoapps.notifications.email.utils import encrypt_object, encrypt_string
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
@@ -910,7 +914,13 @@ class UpdatePreferenceFromEncryptedDataView(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests if preference is updated when url is hit
|
||||
"""
|
||||
url = get_unsubscribe_link(self.user.username, {'channel': 'email', 'value': False})
|
||||
user_hash = encrypt_string(self.user.username)
|
||||
patch_hash = encrypt_object({'channel': 'email', 'value': False})
|
||||
url_params = {
|
||||
"username": user_hash,
|
||||
"patch": patch_hash
|
||||
}
|
||||
url = reverse("preference_update_from_encrypted_username_view", kwargs=url_params)
|
||||
func = getattr(self.client, request_type)
|
||||
response = func(url)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
@@ -921,6 +931,24 @@ class UpdatePreferenceFromEncryptedDataView(ModuleStoreTestCase):
|
||||
assert type_prefs['email'] is False
|
||||
assert type_prefs['email_cadence'] == EmailCadence.NEVER
|
||||
|
||||
def test_if_config_version_is_updated(self):
|
||||
"""
|
||||
Tests if preference version is updated before applying patch data
|
||||
"""
|
||||
preference = CourseNotificationPreference.objects.get(user=self.user, course_id=self.course.id)
|
||||
preference.config_version -= 1
|
||||
preference.save()
|
||||
user_hash = encrypt_string(self.user.username)
|
||||
patch_hash = encrypt_object({'channel': 'email', 'value': False})
|
||||
url_params = {
|
||||
"username": user_hash,
|
||||
"patch": patch_hash
|
||||
}
|
||||
url = reverse("preference_update_from_encrypted_username_view", kwargs=url_params)
|
||||
self.client.get(url)
|
||||
preference = CourseNotificationPreference.objects.get(user=self.user, course_id=self.course.id)
|
||||
assert preference.config_version == get_course_notification_preference_config_version()
|
||||
|
||||
|
||||
def remove_notifications_with_visibility_settings(expected_response):
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,7 @@ from datetime import datetime, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext as _
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from pytz import UTC
|
||||
@@ -441,7 +441,4 @@ def preference_update_from_encrypted_username_view(request, username, patch):
|
||||
username and patch must be string
|
||||
"""
|
||||
update_user_preferences_from_patch(username, patch)
|
||||
context = {
|
||||
"notification_preferences_url": f"{settings.ACCOUNT_MICROFRONTEND_URL}/notifications"
|
||||
}
|
||||
return render(request, "notifications/email_digest_preference_update.html", context=context)
|
||||
return Response({"result": "success"}, status=status.HTTP_200_OK)
|
||||
|
||||
Reference in New Issue
Block a user