summaryrefslogtreecommitdiff
path: root/tests/views/tests/i18n.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/views/tests/i18n.py')
-rw-r--r--tests/views/tests/i18n.py221
1 files changed, 221 insertions, 0 deletions
diff --git a/tests/views/tests/i18n.py b/tests/views/tests/i18n.py
new file mode 100644
index 0000000000..33ffab59f2
--- /dev/null
+++ b/tests/views/tests/i18n.py
@@ -0,0 +1,221 @@
+# -*- coding:utf-8 -*-
+from __future__ import absolute_import
+
+import gettext
+import os
+from os import path
+
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.test import LiveServerTestCase, TestCase
+from django.test.utils import override_settings
+from django.utils import six, unittest
+from django.utils._os import upath
+from django.utils.translation import override
+from django.utils.text import javascript_quote
+
+try:
+ from selenium.webdriver.firefox import webdriver as firefox
+except ImportError:
+ firefox = None
+
+from ..urls import locale_dir
+
+
+class I18NTests(TestCase):
+ """ Tests django views in django/views/i18n.py """
+
+ def test_setlang(self):
+ """
+ The set_language view can be used to change the session language.
+
+ The user is redirected to the 'next' argument if provided.
+ """
+ for lang_code, lang_name in settings.LANGUAGES:
+ post_data = dict(language=lang_code, next='/views/')
+ response = self.client.post('/views/i18n/setlang/', data=post_data)
+ self.assertRedirects(response, 'http://testserver/views/')
+ self.assertEqual(self.client.session['django_language'], lang_code)
+
+ def test_setlang_unsafe_next(self):
+ """
+ The set_language view only redirects to the 'next' argument if it is
+ "safe".
+ """
+ lang_code, lang_name = settings.LANGUAGES[0]
+ post_data = dict(language=lang_code, next='//unsafe/redirection/')
+ response = self.client.post('/views/i18n/setlang/', data=post_data)
+ self.assertEqual(response.url, 'http://testserver/')
+ self.assertEqual(self.client.session['django_language'], lang_code)
+
+ def test_setlang_reversal(self):
+ self.assertEqual(reverse('set_language'), '/views/i18n/setlang/')
+
+ def test_jsi18n(self):
+ """The javascript_catalog can be deployed with language settings"""
+ for lang_code in ['es', 'fr', 'ru']:
+ with override(lang_code):
+ catalog = gettext.translation('djangojs', locale_dir, [lang_code])
+ if six.PY3:
+ trans_txt = catalog.gettext('this is to be translated')
+ else:
+ trans_txt = catalog.ugettext('this is to be translated')
+ response = self.client.get('/views/jsi18n/')
+ # in response content must to be a line like that:
+ # catalog['this is to be translated'] = 'same_that_trans_txt'
+ # javascript_quote is used to be able to check unicode strings
+ self.assertContains(response, javascript_quote(trans_txt), 1)
+ if lang_code == 'fr':
+ # Message with context (msgctxt)
+ self.assertContains(response, "['month name\x04May'] = 'mai';", 1)
+
+
+class JsI18NTests(TestCase):
+ """
+ Tests django views in django/views/i18n.py that need to change
+ settings.LANGUAGE_CODE.
+ """
+
+ def test_jsi18n_with_missing_en_files(self):
+ """
+ The javascript_catalog shouldn't load the fallback language in the
+ case that the current selected language is actually the one translated
+ from, and hence missing translation files completely.
+
+ This happens easily when you're translating from English to other
+ languages and you've set settings.LANGUAGE_CODE to some other language
+ than English.
+ """
+ with self.settings(LANGUAGE_CODE='es'):
+ with override('en-us'):
+ response = self.client.get('/views/jsi18n/')
+ self.assertNotContains(response, 'esto tiene que ser traducido')
+
+ def test_jsi18n_fallback_language(self):
+ """
+ Let's make sure that the fallback language is still working properly
+ in cases where the selected language cannot be found.
+ """
+ with self.settings(LANGUAGE_CODE='fr'):
+ with override('fi'):
+ response = self.client.get('/views/jsi18n/')
+ self.assertContains(response, 'il faut le traduire')
+
+ def testI18NLanguageNonEnglishDefault(self):
+ """
+ Check if the Javascript i18n view returns an empty language catalog
+ if the default language is non-English, the selected language
+ is English and there is not 'en' translation available. See #13388,
+ #3594 and #13726 for more details.
+ """
+ with self.settings(LANGUAGE_CODE='fr'):
+ with override('en-us'):
+ response = self.client.get('/views/jsi18n/')
+ self.assertNotContains(response, 'Choisir une heure')
+
+ def test_nonenglish_default_english_userpref(self):
+ """
+ Same as above with the difference that there IS an 'en' translation
+ available. The Javascript i18n view must return a NON empty language catalog
+ with the proper English translations. See #13726 for more details.
+ """
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views.app0']
+ with self.settings(LANGUAGE_CODE='fr', INSTALLED_APPS=extended_apps):
+ with override('en-us'):
+ response = self.client.get('/views/jsi18n_english_translation/')
+ self.assertContains(response, javascript_quote('this app0 string is to be translated'))
+
+ def testI18NLanguageNonEnglishFallback(self):
+ """
+ Makes sure that the fallback language is still working properly
+ in cases where the selected language cannot be found.
+ """
+ with self.settings(LANGUAGE_CODE='fr'):
+ with override('none'):
+ response = self.client.get('/views/jsi18n/')
+ self.assertContains(response, 'Choisir une heure')
+
+
+class JsI18NTestsMultiPackage(TestCase):
+ """
+ Tests for django views in django/views/i18n.py that need to change
+ settings.LANGUAGE_CODE and merge JS translation from several packages.
+ """
+ def testI18NLanguageEnglishDefault(self):
+ """
+ Check if the JavaScript i18n view returns a complete language catalog
+ if the default language is en-us, the selected language has a
+ translation available and a catalog composed by djangojs domain
+ translations of multiple Python packages is requested. See #13388,
+ #3594 and #13514 for more details.
+ """
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views.app1', 'regressiontests.views.app2']
+ with self.settings(LANGUAGE_CODE='en-us', INSTALLED_APPS=extended_apps):
+ with override('fr'):
+ response = self.client.get('/views/jsi18n_multi_packages1/')
+ self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1'))
+
+ def testI18NDifferentNonEnLangs(self):
+ """
+ Similar to above but with neither default or requested language being
+ English.
+ """
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views.app3', 'regressiontests.views.app4']
+ with self.settings(LANGUAGE_CODE='fr', INSTALLED_APPS=extended_apps):
+ with override('es-ar'):
+ response = self.client.get('/views/jsi18n_multi_packages2/')
+ self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido'))
+
+ def testI18NWithLocalePaths(self):
+ extended_locale_paths = settings.LOCALE_PATHS + (
+ path.join(path.dirname(
+ path.dirname(path.abspath(upath(__file__)))), 'app3', 'locale'),)
+ with self.settings(LANGUAGE_CODE='es-ar', LOCALE_PATHS=extended_locale_paths):
+ with override('es-ar'):
+ response = self.client.get('/views/jsi18n/')
+ self.assertContains(response,
+ javascript_quote('este texto de app3 debe ser traducido'))
+
+
+skip_selenium = not os.environ.get('DJANGO_SELENIUM_TESTS', False)
+
+
+@unittest.skipIf(skip_selenium, 'Selenium tests not requested')
+@unittest.skipUnless(firefox, 'Selenium not installed')
+class JavascriptI18nTests(LiveServerTestCase):
+ urls = 'regressiontests.views.urls'
+
+ @classmethod
+ def setUpClass(cls):
+ cls.selenium = firefox.WebDriver()
+ super(JavascriptI18nTests, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.selenium.quit()
+ super(JavascriptI18nTests, cls).tearDownClass()
+
+ @override_settings(LANGUAGE_CODE='de')
+ def test_javascript_gettext(self):
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views']
+ with self.settings(INSTALLED_APPS=extended_apps):
+ self.selenium.get('%s%s' % (self.live_server_url, '/jsi18n_template/'))
+
+ elem = self.selenium.find_element_by_id("gettext")
+ self.assertEqual(elem.text, "Entfernen")
+ elem = self.selenium.find_element_by_id("ngettext_sing")
+ self.assertEqual(elem.text, "1 Element")
+ elem = self.selenium.find_element_by_id("ngettext_plur")
+ self.assertEqual(elem.text, "455 Elemente")
+ elem = self.selenium.find_element_by_id("pgettext")
+ self.assertEqual(elem.text, "Kann")
+ elem = self.selenium.find_element_by_id("npgettext_sing")
+ self.assertEqual(elem.text, "1 Resultat")
+ elem = self.selenium.find_element_by_id("npgettext_plur")
+ self.assertEqual(elem.text, "455 Resultate")
+
+ def test_escaping(self):
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views']
+ with self.settings(INSTALLED_APPS=extended_apps):
+ response = self.client.get('%s%s' % (self.live_server_url, '/jsi18n_admin/'))
+ self.assertContains(response, '\\x04')