diff --git a/lms/djangoapps/email_marketing/signals.py b/lms/djangoapps/email_marketing/signals.py index b5fa747a4c..8bdb0aa119 100644 --- a/lms/djangoapps/email_marketing/signals.py +++ b/lms/djangoapps/email_marketing/signals.py @@ -13,6 +13,7 @@ from celery.exceptions import TimeoutError from email_marketing.models import EmailMarketingConfiguration from lms.djangoapps.email_marketing.tasks import update_user, update_user_email, get_email_cookies_via_sailthru +from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY from student.cookies import CREATE_LOGON_COOKIE from student.views import REGISTER_USER from util.model_utils import USER_FIELD_CHANGED @@ -22,7 +23,7 @@ log = logging.getLogger(__name__) # list of changed fields to pass to Sailthru CHANGED_FIELDNAMES = ['username', 'is_active', 'name', 'gender', 'education', 'age', 'level_of_education', 'year_of_birth', - 'country'] + 'country', LANGUAGE_KEY] @receiver(CREATE_LOGON_COOKIE) @@ -134,8 +135,8 @@ def email_marketing_user_field_changed(sender, user=None, table=None, setting=No if user.is_anonymous(): return - # ignore anything but User or Profile table - if table != 'auth_user' and table != 'auth_userprofile': + # ignore anything but User, Profile or UserPreference tables + if table not in {'auth_user', 'auth_userprofile', 'user_api_userpreference'}: return # ignore anything not in list of fields to handle @@ -167,6 +168,9 @@ def _create_sailthru_user_vars(user, profile): 'activated': int(user.is_active), 'joined_date': user.date_joined.strftime("%Y-%m-%d")} + # Set the ui_lang to the User's prefered language, if specified. Otherwise use the application's default language. + sailthru_vars['ui_lang'] = user.preferences.model.get_value(user, LANGUAGE_KEY, default=settings.LANGUAGE_CODE) + if profile: sailthru_vars['fullname'] = profile.name sailthru_vars['gender'] = profile.gender diff --git a/lms/djangoapps/email_marketing/tests/test_signals.py b/lms/djangoapps/email_marketing/tests/test_signals.py index 6faece5c64..a9d2525580 100644 --- a/lms/djangoapps/email_marketing/tests/test_signals.py +++ b/lms/djangoapps/email_marketing/tests/test_signals.py @@ -3,6 +3,7 @@ import datetime import logging import ddt +from django.conf import settings from django.contrib.auth.models import AnonymousUser from django.contrib.sites.models import Site from django.test import TestCase @@ -28,6 +29,7 @@ from email_marketing.tasks import ( update_user_email, get_email_cookies_via_sailthru ) +from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY from student.tests.factories import UserFactory, UserProfileFactory from util.json_request import JsonResponse @@ -450,11 +452,27 @@ class EmailMarketingTests(TestCase): email_marketing_register_user(None, user=self.user, profile=self.profile) self.assertTrue(mock_update_user.called) + @patch('lms.djangoapps.email_marketing.tasks.update_user.delay') + def test_register_user_language_preference(self, mock_update_user): + """ + make sure register user call invokes update_user and includes language preference + """ + # If the user hasn't set an explicit language preference, we should send the application's default. + self.assertIsNone(self.user.preferences.model.get_value(self.user, LANGUAGE_KEY)) + email_marketing_register_user(None, user=self.user, profile=self.profile) + self.assertEqual(mock_update_user.call_args[0][0]['ui_lang'], settings.LANGUAGE_CODE) + + # If the user has set an explicit language preference, we should send it. + self.user.preferences.create(key=LANGUAGE_KEY, value='es-419') + email_marketing_register_user(None, user=self.user, profile=self.profile) + self.assertEqual(mock_update_user.call_args[0][0]['ui_lang'], 'es-419') + @patch('email_marketing.signals.crum.get_current_request') @patch('lms.djangoapps.email_marketing.tasks.update_user.delay') @ddt.data(('auth_userprofile', 'gender', 'f', True), ('auth_user', 'is_active', 1, True), - ('auth_userprofile', 'shoe_size', 1, False)) + ('auth_userprofile', 'shoe_size', 1, False), + ('user_api_userpreference', 'pref-lang', 'en', True)) @ddt.unpack def test_modify_field(self, table, setting, value, result, mock_update_user, mock_get_current_request): """ @@ -464,6 +482,25 @@ class EmailMarketingTests(TestCase): email_marketing_user_field_changed(None, self.user, table=table, setting=setting, new_value=value) self.assertEqual(mock_update_user.called, result) + @patch('lms.djangoapps.email_marketing.tasks.update_user.delay') + def test_modify_language_preference(self, mock_update_user): + """ + Test that update_user is called with new language preference + """ + # If the user hasn't set an explicit language preference, we should send the application's default. + self.assertIsNone(self.user.preferences.model.get_value(self.user, LANGUAGE_KEY)) + email_marketing_user_field_changed( + None, self.user, table='user_api_userpreference', setting=LANGUAGE_KEY, new_value=None + ) + self.assertEqual(mock_update_user.call_args[0][0]['ui_lang'], settings.LANGUAGE_CODE) + + # If the user has set an explicit language preference, we should send it. + self.user.preferences.create(key=LANGUAGE_KEY, value='fr') + email_marketing_user_field_changed( + None, self.user, table='user_api_userpreference', setting=LANGUAGE_KEY, new_value='fr' + ) + self.assertEqual(mock_update_user.call_args[0][0]['ui_lang'], 'fr') + @patch('lms.djangoapps.email_marketing.tasks.update_user_email.delay') def test_modify_email(self, mock_update_user): """ diff --git a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py index 91b5384014..f588c72fbc 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py @@ -232,7 +232,11 @@ class TestUserPreferenceMiddleware(TestCase): self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), None) - with self.assertNumQueries(5): + # The 'email_marketing' app is installed in the LMS env but not the CMS env. It listens for the + # USER_FIELD_CHANGED signal (utils.model_utils) and does a query to check the EmailMarketingConfiguration + # table to see if Sailthru integreation is enabled. + expected_queries = 6 if 'email_marketing' in settings.INSTALLED_APPS else 5 + with self.assertNumQueries(expected_queries): self.middleware.process_request(self.request) self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), 'es') @@ -258,7 +262,11 @@ class TestUserPreferenceMiddleware(TestCase): self.request.COOKIES[settings.LANGUAGE_COOKIE] = 'en' - with self.assertNumQueries(5): + # The 'email_marketing' app is installed in the LMS env but not the CMS env. It listens for the + # USER_FIELD_CHANGED signal (utils.model_utils) and does a query to check the EmailMarketingConfiguration + # table to see if Sailthru integreation is enabled. + expected_queries = 6 if 'email_marketing' in settings.INSTALLED_APPS else 5 + with self.assertNumQueries(expected_queries): self.middleware.process_request(self.request) self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), 'en')