diff --git a/openedx/core/djangoapps/content_libraries/tests/test_runtime.py b/openedx/core/djangoapps/content_libraries/tests/test_runtime.py index 435a9ac1cd..4551fc7198 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_runtime.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_runtime.py @@ -20,6 +20,7 @@ from openedx.core.djangoapps.content_libraries.tests.base import ( ) from openedx.core.djangoapps.content_libraries.tests.user_state_block import UserStateTestBlock from openedx.core.djangoapps.content_libraries.constants import COMPLEX +from openedx.core.djangoapps.dark_lang.models import DarkLangConfig from openedx.core.djangoapps.xblock import api as xblock_api from openedx.core.djangolib.testing.utils import skip_unless_lms, skip_unless_cms from openedx.core.lib import blockstore_api @@ -431,6 +432,49 @@ class ContentLibraryXBlockUserStateTest(ContentLibraryContentTestMixin, TestCase self.assertEqual(sm.grade, 1) self.assertEqual(sm.max_grade, 1) + @skip_unless_lms + def test_i18n(self): + """ + Test that a block's rendered content respects the Accept-Language header and returns translated content. + """ + block_id = library_api.create_library_block(self.library.key, "problem", "i18n_problem").usage_key + new_olx = """ + + +

This is a normal capa problem. It has "maximum attempts" set to **5**.

+ + + XBlock metadata only + XBlock data/metadata and associated static asset files + Static asset files for XBlocks and courseware + XModule metadata only + +
+
+ """.strip() + library_api.set_library_block_olx(block_id, new_olx) + library_api.publish_changes(self.library.key) + + # Enable the dummy language in darklang + DarkLangConfig( + released_languages='eo', + changed_by=self.student_a, + enabled=True + ).save() + + client = APIClient() + + # View the problem without specifying a language + default_public_view = client.get(URL_BLOCK_RENDER_VIEW.format(block_key=block_id, view_name='public_view')) + self.assertIn("Submit", default_public_view.data["content"]) + self.assertNotIn("Süßmït", default_public_view.data["content"]) + + # View the problem and request the dummy language + dummy_public_view = client.get(URL_BLOCK_RENDER_VIEW.format(block_key=block_id, view_name='public_view'), + HTTP_ACCEPT_LANGUAGE='eo') + self.assertIn("Süßmït", dummy_public_view.data["content"]) + self.assertNotIn("Submit", dummy_public_view.data["content"]) + @requires_blockstore @skip_unless_lms # No completion tracking in Studio diff --git a/openedx/core/djangoapps/xblock/runtime/runtime.py b/openedx/core/djangoapps/xblock/runtime/runtime.py index 32764059e6..c92a6a0b9b 100644 --- a/openedx/core/djangoapps/xblock/runtime/runtime.py +++ b/openedx/core/djangoapps/xblock/runtime/runtime.py @@ -17,7 +17,7 @@ from web_fragments.fragment import Fragment from xblock.exceptions import NoSuchServiceError from xblock.field_data import SplitFieldData from xblock.fields import Scope -from xblock.runtime import KvsFieldData, MemoryIdManager, NullI18nService, Runtime +from xblock.runtime import KvsFieldData, MemoryIdManager, Runtime import track.contexts import track.views @@ -31,6 +31,7 @@ from openedx.core.djangoapps.xblock.utils import get_xblock_id_for_anonymous_use from openedx.core.lib.xblock_utils import wrap_fragment, xblock_local_resource_url from static_replace import process_static_urls from xmodule.errortracker import make_error_tracker +from xmodule.modulestore.django import ModuleI18nService from .id_managers import OpaqueKeyReader from .shims import RuntimeShim, XBlockShim @@ -78,7 +79,7 @@ class XBlockRuntime(RuntimeShim, Runtime): XBlockShim, # Adds deprecated LMS/Studio functionality / backwards compatibility ), services={ - "i18n": NullI18nService(), + "i18n": ModuleI18nService(), }, default_class=None, select=None,