From c9f6872be334fa4668fbb87ced360ccac7f05d07 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 10 May 2017 15:27:01 -0400 Subject: [PATCH] Capture the language preference set by an anonymous user when the register or login [LEARNER-168] --- common/djangoapps/student/tests/factories.py | 4 +- .../core/djangoapps/lang_pref/middleware.py | 47 ++++++++++-------- .../lang_pref/tests/test_middleware.py | 48 +++++++++++++++++++ 3 files changed, 79 insertions(+), 20 deletions(-) diff --git a/common/djangoapps/student/tests/factories.py b/common/djangoapps/student/tests/factories.py index 792c2124de..ac7b2175e5 100644 --- a/common/djangoapps/student/tests/factories.py +++ b/common/djangoapps/student/tests/factories.py @@ -84,9 +84,11 @@ class UserFactory(DjangoModelFactory): model = User django_get_or_create = ('email', 'username') + _DEFAULT_PASSWORD = 'test' + username = factory.Sequence(u'robot{0}'.format) email = factory.Sequence(u'robot+test+{0}@edx.org'.format) - password = factory.PostGenerationMethodCall('set_password', 'test') + password = factory.PostGenerationMethodCall('set_password', _DEFAULT_PASSWORD) first_name = factory.Sequence(u'Robot{0}'.format) last_name = 'Test' is_staff = False diff --git a/openedx/core/djangoapps/lang_pref/middleware.py b/openedx/core/djangoapps/lang_pref/middleware.py index e9fd010c8f..0759337ab7 100644 --- a/openedx/core/djangoapps/lang_pref/middleware.py +++ b/openedx/core/djangoapps/lang_pref/middleware.py @@ -32,6 +32,8 @@ class LanguagePreferenceMiddleware(object): if cookie_lang: if request.user.is_authenticated(): set_user_preference(request.user, LANGUAGE_KEY, cookie_lang) + else: + request._anonymous_user_cookie_lang = cookie_lang accept_header = request.META.get(LANGUAGE_HEADER, None) if accept_header: @@ -51,25 +53,32 @@ class LanguagePreferenceMiddleware(object): def process_response(self, request, response): # If the user is logged in, check for their language preference if getattr(request, 'user', None) and request.user.is_authenticated(): - # Get the user's language preference - try: - user_pref = get_user_preference(request.user, LANGUAGE_KEY) - except (UserAPIRequestError, UserAPIInternalError): - # If we can't find the user preferences, then don't modify the cookie - pass + user_pref = None + + anonymous_cookie_lang = getattr(request, '_anonymous_user_cookie_lang', None) + if anonymous_cookie_lang: + user_pref = anonymous_cookie_lang + set_user_preference(request.user, LANGUAGE_KEY, anonymous_cookie_lang) else: - # Set it in the LANGUAGE_COOKIE - if user_pref: - response.set_cookie( - settings.LANGUAGE_COOKIE, - value=user_pref, - domain=settings.SESSION_COOKIE_DOMAIN, - max_age=COOKIE_DURATION, - ) - else: - response.delete_cookie( - settings.LANGUAGE_COOKIE, - domain=settings.SESSION_COOKIE_DOMAIN - ) + # Get the user's language preference + try: + user_pref = get_user_preference(request.user, LANGUAGE_KEY) + except (UserAPIRequestError, UserAPIInternalError): + # If we can't find the user preferences, then don't modify the cookie + pass + + # If set, set the user_pref in the LANGUAGE_COOKIE + if user_pref: + response.set_cookie( + settings.LANGUAGE_COOKIE, + value=user_pref, + domain=settings.SESSION_COOKIE_DOMAIN, + max_age=COOKIE_DURATION, + ) + else: + response.delete_cookie( + settings.LANGUAGE_COOKIE, + domain=settings.SESSION_COOKIE_DOMAIN + ) return response diff --git a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py index 04bbe4c122..91b5384014 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py @@ -168,6 +168,54 @@ class TestUserPreferenceMiddleware(TestCase): else: self.assertNotIn(settings.LANGUAGE_COOKIE, self.client.cookies) + @ddt.data( + (None, None), + ('es', 'es-419'), + ('en', 'en'), + ('es-419', 'es-419') + ) + @ddt.unpack + def test_login_captures_lang_pref(self, lang_cookie, expected_lang): + if lang_cookie: + self.client.cookies[settings.LANGUAGE_COOKIE] = lang_cookie + elif settings.LANGUAGE_COOKIE in self.client.cookies: + del self.client.cookies[settings.LANGUAGE_COOKIE] + + # Use an actual call to the login endpoint, to validate that the middleware + # stack does the right thing + if settings.FEATURES.get('ENABLE_COMBINED_LOGIN_REGISTRATION'): + response = self.client.post( + reverse('user_api_login_session'), + data={ + 'email': self.user.email, + 'password': UserFactory._DEFAULT_PASSWORD, + 'remember': True, + } + ) + else: + response = self.client.post( + reverse('login_post'), + data={ + 'email': self.user.email, + 'password': UserFactory._DEFAULT_PASSWORD, + 'honor_code': True, + } + ) + + self.assertEqual(response.status_code, 200) + + if lang_cookie: + self.assertEqual(response['Content-Language'], expected_lang) + self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), lang_cookie) + self.assertEqual( + self.client.cookies[settings.LANGUAGE_COOKIE].value, + lang_cookie + ) + else: + self.assertEqual(response['Content-Language'], 'en') + self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), None) + self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE].value, '') + def test_process_response_no_user_noop(self): del self.request.user response = mock.Mock(spec=HttpResponse)