Merge pull request #31408 from open-craft/agrendalath/fix_site_language
fix: use language specified in SiteConfiguration
This commit is contained in:
@@ -501,21 +501,17 @@ class TestCourseStatusGET(CourseStatusAPITestCase, MobileAuthUserTestMixin,
|
||||
assert response.data['last_visited_block_id'] == str(self.unit.location)
|
||||
|
||||
# Since we are testing an non atomic view in atomic test case, therefore we are expecting error on failures
|
||||
def api_error_response(self, reverse_args=None, data=None, **kwargs):
|
||||
def api_atomic_response(self, reverse_args=None, data=None, **kwargs):
|
||||
"""
|
||||
Same as api response from MobileAPITestCase but handle views which throw errors
|
||||
Same as the api_response from MobileAPITestCase, but handles the view as an atomic transaction.
|
||||
"""
|
||||
url = self.reverse_url(reverse_args, **kwargs)
|
||||
try:
|
||||
with transaction.atomic():
|
||||
self.url_method(url, data=data, **kwargs)
|
||||
assert False
|
||||
except transaction.TransactionManagementError:
|
||||
assert True
|
||||
with transaction.atomic():
|
||||
self.url_method(url, data=data, **kwargs)
|
||||
|
||||
def test_invalid_user(self):
|
||||
self.login_and_enroll()
|
||||
self.api_error_response(username='no_user')
|
||||
self.api_atomic_response(username='no_user')
|
||||
|
||||
def test_other_user(self):
|
||||
# login and enroll as the test user
|
||||
@@ -530,22 +526,22 @@ class TestCourseStatusGET(CourseStatusAPITestCase, MobileAuthUserTestMixin,
|
||||
|
||||
# now login and call the API as the test user
|
||||
self.login()
|
||||
self.api_error_response(username=other.username)
|
||||
self.api_atomic_response(username=other.username)
|
||||
|
||||
def test_course_not_found(self):
|
||||
non_existent_course_id = CourseKey.from_string('a/b/c')
|
||||
self.init_course_access(course_id=non_existent_course_id)
|
||||
|
||||
self.api_error_response(course_id=non_existent_course_id)
|
||||
self.api_atomic_response(course_id=non_existent_course_id)
|
||||
|
||||
def test_unenrolled_user(self):
|
||||
self.login()
|
||||
self.unenroll()
|
||||
self.api_error_response(expected_response_code=None)
|
||||
self.api_atomic_response(expected_response_code=None)
|
||||
|
||||
def test_no_auth(self):
|
||||
self.logout()
|
||||
self.api_error_response()
|
||||
self.api_atomic_response()
|
||||
|
||||
|
||||
class TestCourseStatusPATCH(CourseStatusAPITestCase, MobileAuthUserTestMixin,
|
||||
|
||||
@@ -17,7 +17,6 @@ from django.utils.deprecation import MiddlewareMixin
|
||||
from openedx.core.djangoapps.dark_lang import DARK_LANGUAGE_KEY
|
||||
from openedx.core.djangoapps.dark_lang.models import DarkLangConfig
|
||||
from openedx.core.djangoapps.lang_pref.helpers import set_language_cookie
|
||||
from openedx.core.djangoapps.site_configuration.helpers import get_value
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
|
||||
|
||||
# If django 1.7 or higher is used, the right-side can be updated with new-style codes.
|
||||
@@ -98,20 +97,10 @@ class DarkLangMiddleware(MiddlewareMixin):
|
||||
Apply user's dark lang preference as a cookie for future requests.
|
||||
"""
|
||||
if DarkLangConfig.current().enabled:
|
||||
self._set_site_or_microsite_language(request, response)
|
||||
self._activate_preview_language(request, response)
|
||||
|
||||
return response
|
||||
|
||||
def _set_site_or_microsite_language(self, request, response):
|
||||
"""
|
||||
Apply language specified in site configuration.
|
||||
"""
|
||||
language = get_value('LANGUAGE_CODE', None)
|
||||
if language:
|
||||
request.session[LANGUAGE_SESSION_KEY] = language
|
||||
set_language_cookie(request, response, language)
|
||||
|
||||
def _fuzzy_match(self, lang_code):
|
||||
"""Returns a fuzzy match for lang_code"""
|
||||
match = None
|
||||
|
||||
@@ -14,7 +14,10 @@ from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
|
||||
from openedx.core.djangoapps.dark_lang.middleware import DarkLangMiddleware
|
||||
from openedx.core.djangoapps.dark_lang.models import DarkLangConfig
|
||||
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration
|
||||
from openedx.core.djangoapps.site_configuration.tests.test_util import (
|
||||
with_site_configuration,
|
||||
with_site_configuration_context,
|
||||
)
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
|
||||
@@ -258,16 +261,6 @@ class DarkLangMiddlewareTests(CacheIsolationTestCase):
|
||||
session[LANGUAGE_SESSION_KEY] = session_language
|
||||
session.save()
|
||||
|
||||
@with_site_configuration(configuration={'LANGUAGE_CODE': 'rel'})
|
||||
def test_site_configuration_language(self):
|
||||
# `LANGUAGE_CODE` in site configuration should override session lang
|
||||
self._set_client_session_language('notrel')
|
||||
self.client.get('/home')
|
||||
self.assert_session_lang_equals(
|
||||
'rel',
|
||||
self.client.session
|
||||
)
|
||||
|
||||
def test_preview_lang_with_released_language(self):
|
||||
# Preview lang should always override selection
|
||||
self._post_set_preview_lang('rel')
|
||||
@@ -404,3 +397,25 @@ class DarkLangMiddlewareTests(CacheIsolationTestCase):
|
||||
assert settings.LANGUAGE_COOKIE_NAME in response.cookies
|
||||
assert response.cookies.get(settings.LANGUAGE_COOKIE_NAME).value == ''
|
||||
assert response['Content-Language'] == site_lang
|
||||
|
||||
@with_site_configuration(configuration={'LANGUAGE_CODE': 'es'})
|
||||
def test_preview_language_ignores_site_configuration(self):
|
||||
"""
|
||||
Test that the preview language has a higher priority than the language set in SiteConfiguration.
|
||||
"""
|
||||
response = self.client.get('/')
|
||||
assert response['Content-Language'] == 'es-419'
|
||||
|
||||
# Set preview language.
|
||||
self._post_set_preview_lang('eo')
|
||||
response = self.client.get('/')
|
||||
assert response['Content-Language'] == 'eo'
|
||||
|
||||
# Reset preview language.
|
||||
self._post_clear_preview_lang()
|
||||
response = self.client.get('/')
|
||||
assert response['Content-Language'] == 'es-419'
|
||||
|
||||
# Clean up by making a request to a Site without specific configuration.
|
||||
with with_site_configuration_context():
|
||||
self.client.get('/')
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"""
|
||||
Middleware for Language Preferences
|
||||
"""
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
from django.utils.translation.trans_real import parse_accept_lang_header
|
||||
@@ -11,6 +10,7 @@ from openedx.core.djangoapps.dark_lang import DARK_LANGUAGE_KEY
|
||||
from openedx.core.djangoapps.dark_lang.models import DarkLangConfig
|
||||
from openedx.core.djangoapps.lang_pref import LANGUAGE_HEADER, LANGUAGE_KEY
|
||||
from openedx.core.djangoapps.lang_pref import helpers as lang_pref_helpers
|
||||
from openedx.core.djangoapps.site_configuration.helpers import get_value
|
||||
from openedx.core.djangoapps.user_api.errors import UserAPIInternalError, UserAPIRequestError
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference
|
||||
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
|
||||
@@ -28,6 +28,9 @@ class LanguagePreferenceMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
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.
|
||||
|
||||
If you specify the LANGUAGE_CODE in SiteConfiguration, it will have a higher priority than the user's language
|
||||
preference.
|
||||
"""
|
||||
cookie_lang = lang_pref_helpers.get_language_cookie(request)
|
||||
if cookie_lang:
|
||||
@@ -54,6 +57,10 @@ class LanguagePreferenceMiddleware(MiddlewareMixin):
|
||||
if LANGUAGE_SESSION_KEY in request.session and request.session[LANGUAGE_SESSION_KEY] != cookie_lang:
|
||||
del request.session[LANGUAGE_SESSION_KEY]
|
||||
|
||||
# Apply language specified in SiteConfiguration, ignoring user preferences.
|
||||
if language := get_value('LANGUAGE_CODE'):
|
||||
request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = language
|
||||
|
||||
def process_response(self, request, response): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
# If the user is logged in, check for their language preference. Also check for real user
|
||||
# if current user is a masquerading user,
|
||||
|
||||
@@ -14,8 +14,13 @@ from django.test.client import Client, RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
from django.utils.translation.trans_real import parse_accept_lang_header
|
||||
|
||||
from openedx.core.djangoapps.lang_pref import COOKIE_DURATION, LANGUAGE_KEY
|
||||
from openedx.core.djangoapps.lang_pref.middleware import LanguagePreferenceMiddleware
|
||||
from openedx.core.djangoapps.site_configuration.tests.test_util import (
|
||||
with_site_configuration,
|
||||
with_site_configuration_context,
|
||||
)
|
||||
from openedx.core.djangoapps.user_api.preferences.api import (
|
||||
delete_user_preference,
|
||||
get_user_preference,
|
||||
@@ -267,3 +272,31 @@ class TestUserPreferenceMiddleware(CacheIsolationTestCase):
|
||||
mock_is_mobile_request.return_value = True
|
||||
response = self.middleware.process_response(self.request, response)
|
||||
response.delete_cookie.assert_called()
|
||||
|
||||
@with_site_configuration(configuration={'LANGUAGE_CODE': 'eo'})
|
||||
@ddt.data(None, 'es', 'en')
|
||||
def test_site_language_ignores_user_preferences(self, user_preference):
|
||||
"""
|
||||
Test that the language set in SiteConfiguration has a higher priority than user preferences.
|
||||
It also does not create or update user preferences.
|
||||
"""
|
||||
self.request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = user_preference
|
||||
self.middleware.process_request(self.request)
|
||||
|
||||
# Do not alter user preferences.
|
||||
assert get_user_preference(self.user, LANGUAGE_KEY) == user_preference
|
||||
# Change the request's cookie instead.
|
||||
assert self.request.COOKIES[settings.LANGUAGE_COOKIE_NAME] == 'eo'
|
||||
|
||||
# Use an actual call to determine the language of the response.
|
||||
response = self.client.get('/')
|
||||
|
||||
assert get_user_preference(self.user, LANGUAGE_KEY) == user_preference
|
||||
assert response['Content-Language'] == 'eo'
|
||||
# `LocaleMiddleware` no longer looks for language in the session since Django 3.2. It checks the cookie instead.
|
||||
# See: https://docs.djangoproject.com/en/3.2/releases/3.0/#miscellaneous
|
||||
assert self.client.session.get(LANGUAGE_SESSION_KEY) is None
|
||||
|
||||
# Clean up by making a request to a Site without specific configuration.
|
||||
with with_site_configuration_context():
|
||||
self.client.get('/')
|
||||
|
||||
Reference in New Issue
Block a user