From 4400d8296d268f5a8523cd02ddc33b12219b2535 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Mon, 26 Nov 2018 12:19:13 +0000 Subject: [PATCH] Fixed #30241 -- Added more system checks of translation settings. --- django/core/checks/translation.py | 52 +++++++++++++++++ docs/ref/checks.txt | 10 ++++ tests/check_framework/test_translation.py | 69 +++++++++++++++++++---- 3 files changed, 121 insertions(+), 10 deletions(-) diff --git a/django/core/checks/translation.py b/django/core/checks/translation.py index 7ad6d2364c..a385c2d098 100644 --- a/django/core/checks/translation.py +++ b/django/core/checks/translation.py @@ -8,6 +8,28 @@ E001 = Error( id='translation.E001', ) +E002 = Error( + 'You have provided an invalid language code in the LANGUAGES setting: {}.', + id='translation.E002', +) + +E003 = Error( + 'You have provided an invalid language code in the LANGUAGES_BIDI setting: {}.', + id='translation.E003', +) + +E004 = Error( + 'You have provided a value for the LANGUAGE_CODE setting that is not in ' + 'the LANGUAGES setting.', + id='translation.E004', +) + +E005 = Error( + 'You have provided values in the LANGUAGES_BIDI setting that are not in ' + 'the LANGUAGES setting.', + id='translation.E005', +) + @register(Tags.translation) def check_setting_language_code(app_configs, **kwargs): @@ -16,3 +38,33 @@ def check_setting_language_code(app_configs, **kwargs): if not isinstance(tag, str) or not language_code_re.match(tag): return [Error(E001.msg.format(tag), id=E001.id)] return [] + + +@register(Tags.translation) +def check_setting_languages(app_configs, **kwargs): + """Error if LANGUAGES setting is invalid.""" + return [ + Error(E002.msg.format(tag), id=E002.id) + for tag, _ in settings.LANGUAGES if not isinstance(tag, str) or not language_code_re.match(tag) + ] + + +@register(Tags.translation) +def check_setting_languages_bidi(app_configs, **kwargs): + """Error if LANGUAGES_BIDI setting is invalid.""" + return [ + Error(E003.msg.format(tag), id=E003.id) + for tag in settings.LANGUAGES_BIDI if not isinstance(tag, str) or not language_code_re.match(tag) + ] + + +@register(Tags.translation) +def check_language_settings_consistent(app_configs, **kwargs): + """Error if language settings are not consistent with each other.""" + available_tags = {i for i, _ in settings.LANGUAGES} | {'en-us'} + messages = [] + if settings.LANGUAGE_CODE not in available_tags: + messages.append(E004) + if not available_tags.issuperset(settings.LANGUAGES_BIDI): + messages.append(E005) + return messages diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 9f2c538fed..84b126bf5f 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -441,6 +441,16 @@ The following checks are performed on your translation configuration: * **translation.E001**: You have provided an invalid value for the :setting:`LANGUAGE_CODE` setting: ````. +* **translation.E002**: You have provided an invalid language code in the + :setting:`LANGUAGES` setting: ````. +* **translation.E003**: You have provided an invalid language code in the + :setting:`LANGUAGES_BIDI` setting: ````. +* **translation.E004**: You have provided a value for the + :setting:`LANGUAGE_CODE` setting that is not in the :setting:`LANGUAGES` + setting. +* **translation.E005**: You have provided values in the + :setting:`LANGUAGES_BIDI` setting that are not in the :setting:`LANGUAGES` + setting. URLs ---- diff --git a/tests/check_framework/test_translation.py b/tests/check_framework/test_translation.py index 7f6d93b38f..9a34b65c06 100644 --- a/tests/check_framework/test_translation.py +++ b/tests/check_framework/test_translation.py @@ -1,12 +1,15 @@ from django.core.checks import Error -from django.core.checks.translation import check_setting_language_code +from django.core.checks.translation import ( + check_language_settings_consistent, check_setting_language_code, + check_setting_languages, check_setting_languages_bidi, +) from django.test import SimpleTestCase class TranslationCheckTests(SimpleTestCase): - def test_valid_language_code(self): - tags = ( + def setUp(self): + self.valid_tags = ( 'en', # language 'mas', # language 'sgn-ase', # language+extlang @@ -17,12 +20,7 @@ class TranslationCheckTests(SimpleTestCase): # FIXME: The following should be invalid: 'sr@latin', # language+script ) - for tag in tags: - with self.subTest(tag), override_settings(LANGUAGE_CODE=tag): - self.assertEqual(check_setting_language_code(None), []) - - def test_invalid_language_code(self): - tags = ( + self.invalid_tags = ( None, # invalid type: None. 123, # invalid type: int. b'en', # invalid type: bytes. @@ -37,9 +35,60 @@ class TranslationCheckTests(SimpleTestCase): # FIXME: The following should be invalid: # 'sr@latin', # locale instead of language tag. ) + + def test_valid_language_code(self): + for tag in self.valid_tags: + with self.subTest(tag), self.settings(LANGUAGE_CODE=tag): + self.assertEqual(check_setting_language_code(None), []) + + def test_invalid_language_code(self): msg = 'You have provided an invalid value for the LANGUAGE_CODE setting: %s.' - for tag in tags: + for tag in self.invalid_tags: with self.subTest(tag), self.settings(LANGUAGE_CODE=tag): self.assertEqual(check_setting_language_code(None), [ Error(msg % tag, id='translation.E001'), ]) + + def test_valid_languages(self): + for tag in self.valid_tags: + with self.subTest(tag), self.settings(LANGUAGES=[(tag, tag)]): + self.assertEqual(check_setting_languages(None), []) + + def test_invalid_languages(self): + msg = 'You have provided an invalid language code in the LANGUAGES setting: %s.' + for tag in self.invalid_tags: + with self.subTest(tag), self.settings(LANGUAGES=[(tag, tag)]): + self.assertEqual(check_setting_languages(None), [ + Error(msg % tag, id='translation.E002'), + ]) + + def test_valid_languages_bidi(self): + for tag in self.valid_tags: + with self.subTest(tag), self.settings(LANGUAGES_BIDI=[tag]): + self.assertEqual(check_setting_languages_bidi(None), []) + + def test_invalid_languages_bidi(self): + msg = 'You have provided an invalid language code in the LANGUAGES_BIDI setting: %s.' + for tag in self.invalid_tags: + with self.subTest(tag), self.settings(LANGUAGES_BIDI=[tag]): + self.assertEqual(check_setting_languages_bidi(None), [ + Error(msg % tag, id='translation.E003'), + ]) + + def test_inconsistent_language_settings(self): + msg = ( + 'You have provided a value for the LANGUAGE_CODE setting that is ' + 'not in the LANGUAGES setting.' + ) + with self.settings(LANGUAGE_CODE='fr', LANGUAGES=[('en', 'English')], LANGUAGES_BIDI=[]): + self.assertEqual(check_language_settings_consistent(None), [ + Error(msg, id='translation.E004'), + ]) + msg = ( + 'You have provided values in the LANGUAGES_BIDI setting that are ' + 'not in the LANGUAGES setting.' + ) + with self.settings(LANGUAGE_CODE='en', LANGUAGES=[('en', 'English')], LANGUAGES_BIDI=['he']): + self.assertEqual(check_language_settings_consistent(None), [ + Error(msg, id='translation.E005'), + ])