diff options
| author | Jannis Leidel <jannis@leidel.info> | 2011-06-15 17:29:10 +0000 |
|---|---|---|
| committer | Jannis Leidel <jannis@leidel.info> | 2011-06-15 17:29:10 +0000 |
| commit | 896e3c69c7eec311085da349a329ee80c8fca132 (patch) | |
| tree | dcc608e4b47fb9621e731f3af476443a56ca56aa /tests | |
| parent | 62bb4b8c37ada04c10d2a37990326636ea7791d6 (diff) | |
Fixed #11585 -- Added ability to translate and prefix URL patterns with a language code as an alternative method for language discovery. Many thanks to Orne Brocaar for his initial work and Carl Meyer for feedback.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16405 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
17 files changed, 419 insertions, 11 deletions
diff --git a/tests/regressiontests/i18n/patterns/__init__.py b/tests/regressiontests/i18n/patterns/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/__init__.py diff --git a/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.mo b/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 0000000000..ec7644b504 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.mo diff --git a/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.po b/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000000..9a14a80ceb --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,37 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-15 11:33+0200\n" +"PO-Revision-Date: 2011-06-14 16:16+0100\n" +"Last-Translator: Jannis Leidel <jannis@leidel.info>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" + +#: urls/default.py:11 +msgid "^translated/$" +msgstr "^translated/$" + +#: urls/default.py:12 +msgid "^translated/(?P<slug>[\\w-]+)/$" +msgstr "^translated/(?P<slug>[\\w-]+)/$" + +#: urls/default.py:17 +msgid "^users/$" +msgstr "^users/$" + +#: urls/default.py:18 urls/wrong.py:7 +msgid "^account/" +msgstr "^account/" + +#: urls/namespace.py:9 urls/wrong_namespace.py:10 +msgid "^register/$" +msgstr "^register/$" diff --git a/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.mo b/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 0000000000..86c847ecf2 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.mo diff --git a/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.po b/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.po new file mode 100644 index 0000000000..fff4bfe394 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/nl/LC_MESSAGES/django.po @@ -0,0 +1,38 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-15 11:33+0200\n" +"PO-Revision-Date: 2011-06-14 16:16+0100\n" +"Last-Translator: Jannis Leidel <jannis@leidel.info>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: urls/default.py:11 +msgid "^translated/$" +msgstr "^vertaald/$" + +#: urls/default.py:12 +msgid "^translated/(?P<slug>[\\w-]+)/$" +msgstr "^vertaald/(?P<slug>[\\w-]+)/$" + +#: urls/default.py:17 +msgid "^users/$" +msgstr "^gebruikers/$" + +#: urls/default.py:18 urls/wrong.py:7 +msgid "^account/" +msgstr "^profiel/" + +#: urls/namespace.py:9 urls/wrong_namespace.py:10 +msgid "^register/$" +msgstr "^registeren/$" diff --git a/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.mo b/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 0000000000..1d7b346c27 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.mo diff --git a/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.po b/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.po new file mode 100644 index 0000000000..fd3388e4b0 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/locale/pt_BR/LC_MESSAGES/django.po @@ -0,0 +1,38 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-15 11:34+0200\n" +"PO-Revision-Date: 2011-06-14 16:17+0100\n" +"Last-Translator: Jannis Leidel <jannis@leidel.info>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: urls/default.py:11 +msgid "^translated/$" +msgstr "^traduzidos/$" + +#: urls/default.py:12 +msgid "^translated/(?P<slug>[\\w-]+)/$" +msgstr "^traduzidos/(?P<slug>[\\w-]+)/$" + +#: urls/default.py:17 +msgid "^users/$" +msgstr "^usuarios/$" + +#: urls/default.py:18 urls/wrong.py:7 +msgid "^account/" +msgstr "^conta/" + +#: urls/namespace.py:9 urls/wrong_namespace.py:10 +msgid "^register/$" +msgstr "^registre-se/$" diff --git a/tests/regressiontests/i18n/patterns/templates/404.html b/tests/regressiontests/i18n/patterns/templates/404.html new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/templates/404.html diff --git a/tests/regressiontests/i18n/patterns/templates/dummy.html b/tests/regressiontests/i18n/patterns/templates/dummy.html new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/templates/dummy.html diff --git a/tests/regressiontests/i18n/patterns/tests.py b/tests/regressiontests/i18n/patterns/tests.py new file mode 100644 index 0000000000..9451bc6966 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/tests.py @@ -0,0 +1,241 @@ +import os + +from django.core.exceptions import ImproperlyConfigured +from django.core.urlresolvers import reverse, clear_url_caches +from django.test import TestCase +from django.test.utils import override_settings +from django.utils import translation + + +class URLTestCaseBase(TestCase): + """ + TestCase base-class for the URL tests. + """ + urls = 'regressiontests.i18n.patterns.urls.default' + + def setUp(self): + # Make sure the cache is empty before we are doing our tests. + clear_url_caches() + + def tearDown(self): + # Make sure we will leave an empty cache for other testcases. + clear_url_caches() + +URLTestCaseBase = override_settings( + USE_I18N=True, + LOCALE_PATHS=( + os.path.join(os.path.dirname(__file__), 'locale'), + ), + TEMPLATE_DIRS=( + os.path.join(os.path.dirname(__file__), 'templates'), + ), + LANGUAGE_CODE='en', + LANGUAGES=( + ('nl', 'Dutch'), + ('en', 'English'), + ('pt-br', 'Brazilian Portuguese'), + ), + MIDDLEWARE_CLASSES=( + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + ), +)(URLTestCaseBase) + + +class URLPrefixTests(URLTestCaseBase): + """ + Tests if the `i18n_patterns` is adding the prefix correctly. + """ + def test_not_prefixed(self): + with translation.override('en'): + self.assertEqual(reverse('not-prefixed'), '/not-prefixed/') + with translation.override('nl'): + self.assertEqual(reverse('not-prefixed'), '/not-prefixed/') + + def test_prefixed(self): + with translation.override('en'): + self.assertEqual(reverse('prefixed'), '/en/prefixed/') + with translation.override('nl'): + self.assertEqual(reverse('prefixed'), '/nl/prefixed/') + + @override_settings(ROOT_URLCONF='regressiontests.i18n.patterns.urls.wrong') + def test_invalid_prefix_use(self): + self.assertRaises(ImproperlyConfigured, lambda: reverse('account:register')) + + +class URLDisabledTests(URLTestCaseBase): + urls = 'regressiontests.i18n.patterns.urls.disabled' + + @override_settings(USE_I18N=False) + def test_prefixed_i18n_disabled(self): + with translation.override('en'): + self.assertEqual(reverse('prefixed'), '/prefixed/') + with translation.override('nl'): + self.assertEqual(reverse('prefixed'), '/prefixed/') + + +class URLTranslationTests(URLTestCaseBase): + """ + Tests if the pattern-strings are translated correctly (within the + `i18n_patterns` and the normal `patterns` function). + """ + def test_no_prefix_translated(self): + with translation.override('en'): + self.assertEqual(reverse('no-prefix-translated'), '/translated/') + self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/translated/yeah/') + + with translation.override('nl'): + self.assertEqual(reverse('no-prefix-translated'), '/vertaald/') + self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/vertaald/yeah/') + + with translation.override('pt-br'): + self.assertEqual(reverse('no-prefix-translated'), '/traduzidos/') + self.assertEqual(reverse('no-prefix-translated-slug', kwargs={'slug': 'yeah'}), '/traduzidos/yeah/') + + def test_users_url(self): + with translation.override('en'): + self.assertEqual(reverse('users'), '/en/users/') + + with translation.override('nl'): + self.assertEqual(reverse('users'), '/nl/gebruikers/') + + with translation.override('pt-br'): + self.assertEqual(reverse('users'), '/pt-br/usuarios/') + + +class URLNamespaceTests(URLTestCaseBase): + """ + Tests if the translations are still working within namespaces. + """ + def test_account_register(self): + with translation.override('en'): + self.assertEqual(reverse('account:register'), '/en/account/register/') + + with translation.override('nl'): + self.assertEqual(reverse('account:register'), '/nl/profiel/registeren/') + + +class URLRedirectTests(URLTestCaseBase): + """ + Tests if the user gets redirected to the right URL when there is no + language-prefix in the request URL. + """ + def test_no_prefix_response(self): + response = self.client.get('/not-prefixed/') + self.assertEqual(response.status_code, 200) + + def test_en_redirect(self): + response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='en') + self.assertRedirects(response, 'http://testserver/en/account/register/') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 200) + + def test_en_redirect_wrong_url(self): + response = self.client.get('/profiel/registeren/', HTTP_ACCEPT_LANGUAGE='en') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], 'http://testserver/en/profiel/registeren/') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 404) + + def test_nl_redirect(self): + response = self.client.get('/profiel/registeren/', HTTP_ACCEPT_LANGUAGE='nl') + self.assertRedirects(response, 'http://testserver/nl/profiel/registeren/') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 200) + + def test_nl_redirect_wrong_url(self): + response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='nl') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], 'http://testserver/nl/account/register/') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 404) + + def test_pt_br_redirect(self): + response = self.client.get('/conta/registre-se/', HTTP_ACCEPT_LANGUAGE='pt-br') + self.assertRedirects(response, 'http://testserver/pt-br/conta/registre-se/') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 200) + + +class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase): + """ + Tests the redirect when the requested URL doesn't end with a slash + (`settings.APPEND_SLASH=True`). + """ + def test_not_prefixed_redirect(self): + response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en') + self.assertEqual(response.status_code, 301) + self.assertEqual(response['location'], 'http://testserver/not-prefixed/') + + def test_en_redirect(self): + response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], 'http://testserver/en/account/register') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 301) + self.assertEqual(response['location'], 'http://testserver/en/account/register/') + + +class URLRedirectWithoutTrailingSlashSettingTests(URLTestCaseBase): + """ + Tests the redirect when the requested URL doesn't end with a slash + (`settings.APPEND_SLASH=False`). + """ + @override_settings(APPEND_SLASH=False) + def test_not_prefixed_redirect(self): + response = self.client.get('/not-prefixed', HTTP_ACCEPT_LANGUAGE='en') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], 'http://testserver/en/not-prefixed') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 404) + + @override_settings(APPEND_SLASH=False) + def test_en_redirect(self): + response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], 'http://testserver/en/account/register') + + response = self.client.get(response['location']) + self.assertEqual(response.status_code, 404) + + +class URLResponseTests(URLTestCaseBase): + """ + Tests if the response has the right language-code. + """ + def test_not_prefixed_with_prefix(self): + response = self.client.get('/en/not-prefixed/') + self.assertEqual(response.status_code, 404) + + def test_en_url(self): + response = self.client.get('/en/account/register/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response['content-language'], 'en') + self.assertEqual(response.context['LANGUAGE_CODE'], 'en') + + def test_nl_url(self): + response = self.client.get('/nl/profiel/registeren/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response['content-language'], 'nl') + self.assertEqual(response.context['LANGUAGE_CODE'], 'nl') + + def test_wrong_en_prefix(self): + response = self.client.get('/en/profiel/registeren/') + self.assertEqual(response.status_code, 404) + + def test_wrong_nl_prefix(self): + response = self.client.get('/nl/account/register/') + self.assertEqual(response.status_code, 404) + + def test_pt_br_url(self): + response = self.client.get('/pt-br/conta/registre-se/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response['content-language'], 'pt-br') + self.assertEqual(response.context['LANGUAGE_CODE'], 'pt-br') diff --git a/tests/regressiontests/i18n/patterns/urls/__init__.py b/tests/regressiontests/i18n/patterns/urls/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/__init__.py diff --git a/tests/regressiontests/i18n/patterns/urls/default.py b/tests/regressiontests/i18n/patterns/urls/default.py new file mode 100644 index 0000000000..8d178e67d4 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/default.py @@ -0,0 +1,19 @@ +from django.conf.urls.defaults import patterns, include, url +from django.conf.urls.i18n import i18n_patterns +from django.utils.translation import ugettext_lazy as _ +from django.views.generic import TemplateView + + +view = TemplateView.as_view(template_name='dummy.html') + +urlpatterns = patterns('', + url(r'^not-prefixed/$', view, name='not-prefixed'), + url(_(r'^translated/$'), view, name='no-prefix-translated'), + url(_(r'^translated/(?P<slug>[\w-]+)/$'), view, name='no-prefix-translated-slug'), +) + +urlpatterns += i18n_patterns('', + url(r'^prefixed/$', view, name='prefixed'), + url(_(r'^users/$'), view, name='users'), + url(_(r'^account/'), include('regressiontests.i18n.patterns.urls.namespace', namespace='account')), +) diff --git a/tests/regressiontests/i18n/patterns/urls/disabled.py b/tests/regressiontests/i18n/patterns/urls/disabled.py new file mode 100644 index 0000000000..e4094695f9 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/disabled.py @@ -0,0 +1,9 @@ +from django.conf.urls.defaults import url +from django.conf.urls.i18n import i18n_patterns +from django.views.generic import TemplateView + +view = TemplateView.as_view(template_name='dummy.html') + +urlpatterns = i18n_patterns('', + url(r'^prefixed/$', view, name='prefixed'), +) diff --git a/tests/regressiontests/i18n/patterns/urls/namespace.py b/tests/regressiontests/i18n/patterns/urls/namespace.py new file mode 100644 index 0000000000..878e08feae --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/namespace.py @@ -0,0 +1,10 @@ +from django.conf.urls.defaults import patterns, include, url +from django.utils.translation import ugettext_lazy as _ +from django.views.generic import TemplateView + + +view = TemplateView.as_view(template_name='dummy.html') + +urlpatterns = patterns('', + url(_(r'^register/$'), view, name='register'), +) diff --git a/tests/regressiontests/i18n/patterns/urls/wrong.py b/tests/regressiontests/i18n/patterns/urls/wrong.py new file mode 100644 index 0000000000..3e45743cdf --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/wrong.py @@ -0,0 +1,8 @@ +from django.conf.urls.defaults import patterns, include, url +from django.conf.urls.i18n import i18n_patterns +from django.utils.translation import ugettext_lazy as _ + + +urlpatterns = i18n_patterns('', + url(_(r'^account/'), include('regressiontests.i18n.patterns.urls.wrong_namespace', namespace='account')), +) diff --git a/tests/regressiontests/i18n/patterns/urls/wrong_namespace.py b/tests/regressiontests/i18n/patterns/urls/wrong_namespace.py new file mode 100644 index 0000000000..90ee2a0538 --- /dev/null +++ b/tests/regressiontests/i18n/patterns/urls/wrong_namespace.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import include, url +from django.conf.urls.i18n import i18n_patterns +from django.utils.translation import ugettext_lazy as _ +from django.views.generic import TemplateView + + +view = TemplateView.as_view(template_name='dummy.html') + +urlpatterns = i18n_patterns('', + url(_(r'^register/$'), view, name='register'), +) diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py index e3add3e3d8..9c24c3fb40 100644 --- a/tests/regressiontests/i18n/tests.py +++ b/tests/regressiontests/i18n/tests.py @@ -3,13 +3,12 @@ from __future__ import with_statement import datetime import decimal import os -import sys import pickle from threading import local from django.conf import settings from django.template import Template, Context -from django.test import TestCase +from django.test import TestCase, RequestFactory from django.utils.formats import (get_format, date_format, time_format, localize, localize_input, iter_format_modules, get_format_modules) from django.utils.importlib import import_module @@ -18,14 +17,14 @@ from django.utils.safestring import mark_safe, SafeString, SafeUnicode from django.utils import translation from django.utils.translation import (ugettext, ugettext_lazy, activate, deactivate, gettext_lazy, pgettext, npgettext, to_locale, - get_language_info, get_language) + get_language_info, get_language, get_language_from_request) from forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm from models import Company, TestModel from commands.tests import * - +from patterns.tests import * from test_warnings import DeprecationWarningTests class TranslationTests(TestCase): @@ -494,6 +493,9 @@ class FormattingTests(TestCase): class MiscTests(TestCase): + def setUp(self): + self.rf = RequestFactory() + def test_parse_spec_http_header(self): """ Testing HTTP header parsing. First, we test that we can parse the @@ -534,10 +536,8 @@ class MiscTests(TestCase): """ Now test that we parse a literal HTTP header correctly. """ - from django.utils.translation.trans_real import get_language_from_request g = get_language_from_request - from django.http import HttpRequest - r = HttpRequest + r = self.rf.get('/') r.COOKIES = {} r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'} self.assertEqual('pt-br', g(r)) @@ -569,10 +569,8 @@ class MiscTests(TestCase): """ Now test that we parse language preferences stored in a cookie correctly. """ - from django.utils.translation.trans_real import get_language_from_request g = get_language_from_request - from django.http import HttpRequest - r = HttpRequest + r = self.rf.get('/') r.COOKIES = {settings.LANGUAGE_COOKIE_NAME: 'pt-br'} r.META = {} self.assertEqual('pt-br', g(r)) @@ -827,4 +825,3 @@ class MultipleLocaleActivationTests(TestCase): t = Template("{% load i18n %}{% blocktrans %}No{% endblocktrans %}") with translation.override('nl'): self.assertEqual(t.render(Context({})), 'Nee') - |
