From 154a4a60800569e91d4ec4370f26f0578c855586 Mon Sep 17 00:00:00 2001 From: muhammad-ammar Date: Wed, 8 May 2024 12:07:44 +0500 Subject: [PATCH] fix: update language cookie if langauge cookie is not same as user's language preference --- CHANGELOG.rst | 4 ++++ enterprise/__init__.py | 2 +- enterprise/middleware.py | 12 ++++++++++++ tests/test_middleware.py | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8d7e366bd5..cc909f0623 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,10 @@ Unreleased ---------- * nothing unreleased +[4.17.4] +-------- +* fix: update language cookie if langauge cookie is not same as user's language preference + [4.17.3] -------- * feat: replacing non encrypted fields of blackboard config model with encypted ones diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 28330ba3ca..ace7fdb00a 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.17.3" +__version__ = "4.17.4" diff --git a/enterprise/middleware.py b/enterprise/middleware.py index abf5dc484e..d754e49d58 100644 --- a/enterprise/middleware.py +++ b/enterprise/middleware.py @@ -67,6 +67,18 @@ def process_request(self, request): # Ignore errors related to user preferences not found. pass + # This is to handle a bug where a user is logged in multiple tabs/browsers. + # User updates the language preference in one tab. After update, user's language preference + # in the database and language cookie in the browser is set to new language. + # But in the other tab/browser, user still has the old language cookie. So when the user + # refreshes the page, the language cookie is sent to the server and overrides the user's preference. + # NOTE: The assumption here is to consider user's language preference as the single source of truth. + cookie_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) + if user_pref and cookie_lang and cookie_lang != user_pref: + # pylint: disable=protected-access + request._anonymous_user_cookie_lang = user_pref + request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = user_pref + # If user's language preference is not set and enterprise customer has a default language configured # then set the default language as the learner's language if not user_pref and not is_request_from_mobile_app(request): diff --git a/tests/test_middleware.py b/tests/test_middleware.py index edc328719a..ab30b9bff2 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -8,6 +8,7 @@ import ddt from pytest import mark +from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware from django.test.client import Client, RequestFactory @@ -156,3 +157,19 @@ def test_cookie_not_set_for_mobile_requests(self): # Make sure the set cookie is not called for anonymous users assert getattr(self.request, '_anonymous_user_cookie_lang', None) is None + + def test_middleware_when_cookie_lang_is_different_from_user_pref(self): + """ + Validate that when user pref and cookie language are set but have different values + then the middleware updates the cookie with user preference value. + """ + user_pref_lang = 'ar' + cookie_lang = 'en' + self.request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = cookie_lang + + with mock.patch('enterprise.middleware.get_user_preference') as mock_get_user_preference: + mock_get_user_preference.return_value = user_pref_lang + self.middleware.process_request(self.request) + + assert self.request.COOKIES[settings.LANGUAGE_COOKIE_NAME] == user_pref_lang + assert getattr(self.request, '_anonymous_user_cookie_lang', None) == user_pref_lang