Skip to content

Commit

Permalink
feat: add user lang cookie preference (#265)
Browse files Browse the repository at this point in the history
* feat: add user lang cookie preference

* test: add UserLanguagePreferenceMiddlewere tests
  • Loading branch information
dcoa committed May 23, 2024
1 parent 3021272 commit 5dec49b
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 2 deletions.
9 changes: 9 additions & 0 deletions eox_core/edxapp_wrapper/backends/lang_pref_middleware_p_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
LanguagePreferenceMiddleware Backend.
"""
from openedx.core.djangoapps.lang_pref.middleware import LanguagePreferenceMiddleware # pylint: disable=import-error


def get_language_preference_middleware():
"""Backend to get the LanguagePreferenceMiddleware from openedx."""
return LanguagePreferenceMiddleware
18 changes: 18 additions & 0 deletions eox_core/edxapp_wrapper/backends/lang_pref_middleware_p_v1_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
LanguagePreferenceMiddleware Backend.
"""


def get_language_preference_middleware():
"""Backend to get the LanguagePreferenceMiddleware from openedx."""
class LanguagePreferenceMiddleware:
"""LanguagePreferenceMiddleware Backend Mock."""
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
# Simulate the behavior of LanguagePreferenceMiddleware
# For example, set a language preference in the request
request.LANGUAGE_CODE = 'en'
return self.get_response(request)
return LanguagePreferenceMiddleware
11 changes: 11 additions & 0 deletions eox_core/edxapp_wrapper/language_preference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
""" Backend abstraction. """
from importlib import import_module

from django.conf import settings


def get_language_preference_middleware(*args, **kwargs):
""" Get LanguagePreferenceMiddleware. """
backend_function = settings.EOX_CORE_LANG_PREF_BACKEND
backend = import_module(backend_function)
return backend.get_language_preference_middleware(*args, **kwargs)
25 changes: 24 additions & 1 deletion eox_core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
from django.db import IntegrityError
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.http import Http404, HttpResponseRedirect
from django.http import Http404, HttpResponseRedirect, parse_cookie
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
from requests.exceptions import HTTPError
from social_core.exceptions import AuthAlreadyAssociated, AuthFailed, AuthUnreachableProvider

from eox_core.edxapp_wrapper.configuration_helpers import get_configuration_helper
from eox_core.edxapp_wrapper.language_preference import get_language_preference_middleware
from eox_core.edxapp_wrapper.third_party_auth import get_tpa_exception_middleware
from eox_core.models import Redirection
from eox_core.utils import cache, fasthash
Expand All @@ -42,6 +43,7 @@ class EoxTenantAuthException:

configuration_helper = get_configuration_helper() # pylint: disable=invalid-name
ExceptionMiddleware = get_tpa_exception_middleware()
LanguagePreferenceMiddleware = get_language_preference_middleware()


class PathRedirectionMiddleware(MiddlewareMixin):
Expand Down Expand Up @@ -284,3 +286,24 @@ def process_exception(self, request, exception):
return super().process_exception(request, new_exception)

return super().process_exception(request, exception)


class UserLanguagePreferenceMiddleware(LanguagePreferenceMiddleware):
"""This Middleware allows the user set the language preference for the site, avoiding the default LANGUAGE_CODE.
The previous behavior was modified here
https://github.com/openedx/edx-platform/blob/open-release/palm.master/openedx/core/djangoapps/lang_pref/middleware.py#L61-L62
"""
def process_request(self, request):
"""
If a user's UserPreference contains a language preference, use the user's preference.
Save the current language preference cookie as the user's preferred language.
"""
original_user_language_cookie = parse_cookie(request.META.get("HTTP_COOKIE", "")).get(
settings.LANGUAGE_COOKIE_NAME
)

if original_user_language_cookie:
request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = original_user_language_cookie

return self.get_response(request)
1 change: 1 addition & 0 deletions eox_core/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def plugin_settings(settings):
settings.EOX_CORE_BEARER_AUTHENTICATION = 'eox_core.edxapp_wrapper.backends.bearer_authentication_j_v1'
settings.EOX_CORE_ASYNC_TASKS = []
settings.EOX_CORE_THIRD_PARTY_AUTH_BACKEND = 'eox_core.edxapp_wrapper.backends.third_party_auth_l_v1'
settings.EOX_CORE_LANG_PREF_BACKEND = 'eox_core.edxapp_wrapper.backends.lang_pref_middleware_p_v1'

if settings.EOX_CORE_USER_ENABLE_MULTI_TENANCY:
settings.EOX_CORE_USER_ORIGIN_SITE_SOURCES = [
Expand Down
5 changes: 5 additions & 0 deletions eox_core/settings/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ def plugin_settings(settings): # pylint: disable=function-redefined
'eox_core.middleware.TPAExceptionMiddleware'
]

settings.MIDDLEWARE.insert(
settings.MIDDLEWARE.index("openedx.core.djangoapps.lang_pref.middleware.LanguagePreferenceMiddleware") + 1,
"eox_core.middleware.UserLanguagePreferenceMiddleware",
)

# Sentry Integration
sentry_integration_dsn = getattr(settings, 'ENV_TOKENS', {}).get(
'EOX_CORE_SENTRY_INTEGRATION_DSN',
Expand Down
1 change: 1 addition & 0 deletions eox_core/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def plugin_settings(settings): # pylint: disable=function-redefined
settings.EOX_CORE_USER_UPDATE_SAFE_FIELDS = ["is_active", "password", "fullname"]
settings.EOX_CORE_BEARER_AUTHENTICATION = 'eox_core.edxapp_wrapper.backends.bearer_authentication_j_v1_test'
settings.EOX_CORE_THIRD_PARTY_AUTH_BACKEND = 'eox_core.edxapp_wrapper.backends.third_party_auth_l_v1'
settings.EOX_CORE_LANG_PREF_BACKEND = 'eox_core.edxapp_wrapper.backends.lang_pref_middleware_p_v1_test'


SETTINGS = SettingsClass()
Expand Down
36 changes: 35 additions & 1 deletion eox_core/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
Test module for the custom Middlewares
"""
import mock
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.http import Http404
from django.test import RequestFactory, TestCase

from eox_core.middleware import PathRedirectionMiddleware, RedirectionsMiddleware
from eox_core.middleware import PathRedirectionMiddleware, RedirectionsMiddleware, UserLanguagePreferenceMiddleware
from eox_core.models import Redirection


Expand Down Expand Up @@ -165,3 +166,36 @@ def test_redirection(self, redirection_get_mock):
result = self.middleware_instance.process_request(request)

self.assertIsNotNone(result)


class UserLanguagePreferenceMiddlewareTestCase(TestCase):
"""
Test the UserLanguagePreferenceMiddleware.
"""
def setUp(self):
self.factory = RequestFactory()
self.middleware = UserLanguagePreferenceMiddleware(get_response=lambda req: None)

def test_process_request_with_language_cookie(self):
"""
Test if the language cookie is set correctly in the request.
"""
language_code = 'fr'
request = self.factory.get('/')
request.META['HTTP_COOKIE'] = f'{settings.LANGUAGE_COOKIE_NAME}={language_code}'
self.middleware(request)

# Check if the language cookie was set correctly in the request
self.assertIn(settings.LANGUAGE_COOKIE_NAME, request.COOKIES)
self.assertEqual(request.COOKIES[settings.LANGUAGE_COOKIE_NAME], language_code)

def test_process_request_without_language_cookie(self):
"""
Test if the language cookie is not set in the request.
"""

request = self.factory.get('/')
self.middleware(request)

# Check that the language cookie is not set in the request
self.assertNotIn(settings.LANGUAGE_COOKIE_NAME, request.COOKIES)

0 comments on commit 5dec49b

Please sign in to comment.