From e2543c7bdbe123c916933a615763f13509408fac Mon Sep 17 00:00:00 2001 From: asadiqbal Date: Tue, 23 Feb 2016 18:03:27 +0500 Subject: [PATCH] asadiqbal08: tests --- .../contentstore/tests/test_i18n.py | 125 ++++++++++++++++++ .../lib/xmodule/xmodule/modulestore/django.py | 2 +- 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/tests/test_i18n.py b/cms/djangoapps/contentstore/tests/test_i18n.py index d3203e3b8956..fe9e24877589 100644 --- a/cms/djangoapps/contentstore/tests/test_i18n.py +++ b/cms/djangoapps/contentstore/tests/test_i18n.py @@ -4,6 +4,131 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from contentstore.tests.utils import AjaxEnabledTestClient +from xmodule.modulestore.django import ModuleI18nService +from django.utils import translation +from django.utils.translation import get_language +from django.conf import settings +import mock +import gettext + + +class FakeTranslations(ModuleI18nService): + """A test GNUTranslations class that takes a map of msg -> translations.""" + + def __init__(self, translations): # pylint: disable=super-init-not-called + self.translations = translations + + def ugettext(self, msgid): + return self.translations.get(msgid, msgid) + + @staticmethod + def translator(locales_map): # pylint: disable=method-hidden + """Build mock translator for the given locales. + Returns a mock gettext.translation function that uses + individual TestTranslations to translate in the given locales. + :param locales_map: A map from locale name to a translations map. + { + 'es': {'Hi': 'Hola', 'Bye': 'Adios'}, + 'zh': {'Hi': 'Ni Hao', 'Bye': 'Zaijian'} + } + """ + def _translation(domain, localedir=None, languages=None): # pylint: disable=unused-argument + """ + return gettext.translation for given language + """ + if languages: + language = languages[0] + if language in locales_map: + return FakeTranslations(locales_map[language]) + return gettext.NullTranslations() + return _translation + + +class TestModuleI18nService(ModuleStoreTestCase): + """ Test ModuleI18nService """ + + xblock_name = 'dummy_block' + + def setUp(self): + """ Setting up tests """ + super(TestModuleI18nService, self).setUp() + self.test_language = 'dummy language' + self.xblock_mock = mock.Mock() + self.xblock_mock.unmixed_class.__name__ = self.xblock_name + self.i18n_service = ModuleI18nService(self.xblock_mock) + self.addCleanup(translation.activate, settings.LANGUAGE_CODE) + + def test_django_service_translation_works(self): + """ + Test django translation service works fine. + """ + + def wrap_with_xyz(func): + """ + A decorator function that just adds 'XYZ ' to the front of all strings + """ + def new_func(*args, **kwargs): + """ custom function """ + output = func(*args, **kwargs) + return "XYZ " + output + return new_func + + old_lang = translation.get_language() + + # Activate french, so that if the fr files haven't been loaded, they will be loaded now. + translation.activate("fr") + french_translation = translation.trans_real._active.value # pylint: disable=protected-access + + # wrap the ugettext functions so that 'TEST ' will prefix each translation + french_translation.ugettext = wrap_with_xyz(french_translation.ugettext) + self.assertEqual(self.i18n_service.ugettext(self.test_language), 'XYZ dummy language') + + # Turn back on our old translations + translation.activate(old_lang) + del old_lang + self.assertEqual(self.i18n_service.ugettext(self.test_language), 'dummy language') + + @mock.patch('django.utils.translation.ugettext', mock.Mock(return_value='XYZ-TEST-LANGUAGE')) + def test_django_translator_in_use_with_empty_block(self): + """ + Test: Django default translator should in use if we have an empty block + """ + self.assertEqual(ModuleI18nService(block=None).ugettext(self.test_language), 'XYZ-TEST-LANGUAGE') + + @mock.patch('django.utils.translation.ugettext', mock.Mock(return_value='XYZ-TEST-LANGUAGE')) + def test_message_catalog_translations(self): + """ + Test: Message catalog from FakeTranslation should return required translations. + """ + _translator = FakeTranslations.translator( + { + 'es': {'Hello': 'es-hello-world'}, + 'fr': {'Hello': 'fr-hello-world'}, + }, + ) + localedir = '/conf/locale' + translation.activate("es") + with mock.patch('gettext.translation', return_value=_translator(domain='domain', localedir=localedir, + languages=[get_language()])): + self.assertEqual(ModuleI18nService(self.xblock_mock).ugettext('Hello'), 'es-hello-world') + + translation.activate("ar") + with mock.patch('gettext.translation', return_value=_translator(domain='domain', localedir=localedir, + languages=[get_language()])): + i18n_service_2 = ModuleI18nService(self.xblock_mock) + self.assertEqual(i18n_service_2.ugettext('Hello'), 'Hello') + self.assertNotEqual(i18n_service_2.ugettext('Hello'), 'fr-hello-world') + self.assertNotEqual(i18n_service_2.ugettext('Hello'), 'es-hello-world') + + translation.activate("fr") + with mock.patch('gettext.translation', return_value=_translator(domain='domain', localedir=localedir, + languages=[get_language()])): + self.assertEqual(ModuleI18nService(self.xblock_mock).ugettext('Hello'), 'fr-hello-world') + + # Django default translator should in use if we block is missing. + with mock.patch('gettext.translation', return_value=_translator(domain='domain', localedir=localedir, + languages=[get_language()])): + self.assertEqual(ModuleI18nService(block=None).ugettext('Hello'), 'XYZ-TEST-LANGUAGE') class InternationalizationTest(ModuleStoreTestCase): diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py index 409aa3b3f15a..17c627621513 100644 --- a/common/lib/xmodule/xmodule/modulestore/django.py +++ b/common/lib/xmodule/xmodule/modulestore/django.py @@ -187,7 +187,7 @@ def create_modulestore_instance( xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None), disabled_xblock_types=disabled_xblock_types, doc_store_config=doc_store_config, - i18n_service=i18n_service, + i18n_service=i18n_service or ModuleI18nService(), fs_service=fs_service or xblock.reference.plugins.FSService(), user_service=user_service or xb_user_service, signal_handler=signal_handler or SignalHandler(class_),