Fixed #24476 -- Added context manager/decorator for overriding script prefix.
Tests were using an undocumented keyword argument for easily overriding script prefix while reversing. This is now changed into a test utility which can be used as decorator or context manager.
This commit is contained in:
parent
6bff343989
commit
0339844b70
|
@ -527,14 +527,13 @@ def resolve(path, urlconf=None):
|
||||||
return get_resolver(urlconf).resolve(path)
|
return get_resolver(urlconf).resolve(path)
|
||||||
|
|
||||||
|
|
||||||
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
|
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
|
||||||
if urlconf is None:
|
if urlconf is None:
|
||||||
urlconf = get_urlconf()
|
urlconf = get_urlconf()
|
||||||
resolver = get_resolver(urlconf)
|
resolver = get_resolver(urlconf)
|
||||||
args = args or []
|
args = args or []
|
||||||
kwargs = kwargs or {}
|
kwargs = kwargs or {}
|
||||||
|
|
||||||
if prefix is None:
|
|
||||||
prefix = get_script_prefix()
|
prefix = get_script_prefix()
|
||||||
|
|
||||||
if not isinstance(viewname, six.string_types):
|
if not isinstance(viewname, six.string_types):
|
||||||
|
|
|
@ -12,11 +12,13 @@ from django.apps import apps
|
||||||
from django.conf import UserSettingsHolder, settings
|
from django.conf import UserSettingsHolder, settings
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.signals import request_started
|
from django.core.signals import request_started
|
||||||
|
from django.core.urlresolvers import get_script_prefix, set_script_prefix
|
||||||
from django.db import reset_queries
|
from django.db import reset_queries
|
||||||
from django.http import request
|
from django.http import request
|
||||||
from django.template import Template
|
from django.template import Template
|
||||||
from django.test.signals import setting_changed, template_rendered
|
from django.test.signals import setting_changed, template_rendered
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils.decorators import ContextDecorator
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.translation import deactivate
|
from django.utils.translation import deactivate
|
||||||
|
|
||||||
|
@ -595,3 +597,22 @@ def require_jinja2(test_func):
|
||||||
'OPTIONS': {'keep_trailing_newline': True},
|
'OPTIONS': {'keep_trailing_newline': True},
|
||||||
}])(test_func)
|
}])(test_func)
|
||||||
return test_func
|
return test_func
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptPrefix(ContextDecorator):
|
||||||
|
def __enter__(self):
|
||||||
|
set_script_prefix(self.prefix)
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, traceback):
|
||||||
|
set_script_prefix(self.old_prefix)
|
||||||
|
|
||||||
|
def __init__(self, prefix):
|
||||||
|
self.prefix = prefix
|
||||||
|
self.old_prefix = get_script_prefix()
|
||||||
|
|
||||||
|
|
||||||
|
def override_script_prefix(prefix):
|
||||||
|
"""
|
||||||
|
Decorator or context manager to temporary override the script prefix.
|
||||||
|
"""
|
||||||
|
return ScriptPrefix(prefix)
|
||||||
|
|
|
@ -22,15 +22,13 @@ from django.contrib.staticfiles.storage import staticfiles_storage
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.checks import Error
|
from django.core.checks import Error
|
||||||
from django.core.files import temp as tempfile
|
from django.core.files import temp as tempfile
|
||||||
from django.core.urlresolvers import (
|
from django.core.urlresolvers import NoReverseMatch, resolve, reverse
|
||||||
NoReverseMatch, get_script_prefix, resolve, reverse, set_script_prefix,
|
|
||||||
)
|
|
||||||
from django.forms.utils import ErrorList
|
from django.forms.utils import ErrorList
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.test import (
|
from django.test import (
|
||||||
TestCase, modify_settings, override_settings, skipUnlessDBFeature,
|
TestCase, modify_settings, override_settings, skipUnlessDBFeature,
|
||||||
)
|
)
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import override_script_prefix, patch_logger
|
||||||
from django.utils import formats, six, translation
|
from django.utils import formats, six, translation
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.cache import get_max_age
|
from django.utils.cache import get_max_age
|
||||||
|
@ -5822,16 +5820,12 @@ class AdminKeepChangeListFiltersTests(TestCase):
|
||||||
add_preserved_filters(context, url),
|
add_preserved_filters(context, url),
|
||||||
)
|
)
|
||||||
|
|
||||||
original_prefix = get_script_prefix()
|
with override_script_prefix('/prefix/'):
|
||||||
try:
|
|
||||||
set_script_prefix('/prefix/')
|
|
||||||
url = reverse('admin:auth_user_changelist', current_app=self.admin_site.name)
|
url = reverse('admin:auth_user_changelist', current_app=self.admin_site.name)
|
||||||
self.assertURLEqual(
|
self.assertURLEqual(
|
||||||
self.get_changelist_url(),
|
self.get_changelist_url(),
|
||||||
add_preserved_filters(context, url),
|
add_preserved_filters(context, url),
|
||||||
)
|
)
|
||||||
finally:
|
|
||||||
set_script_prefix(original_prefix)
|
|
||||||
|
|
||||||
|
|
||||||
class NamespacedAdminKeepChangeListFiltersTests(AdminKeepChangeListFiltersTests):
|
class NamespacedAdminKeepChangeListFiltersTests(AdminKeepChangeListFiltersTests):
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.flatpages.models import FlatPage
|
from django.contrib.flatpages.models import FlatPage
|
||||||
from django.core.urlresolvers import clear_script_prefix, set_script_prefix
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.test.utils import override_script_prefix
|
||||||
|
|
||||||
|
|
||||||
class FlatpageModelTests(TestCase):
|
class FlatpageModelTests(TestCase):
|
||||||
|
@ -13,10 +13,7 @@ class FlatpageModelTests(TestCase):
|
||||||
pf = FlatPage(title="Café!", url='/café/')
|
pf = FlatPage(title="Café!", url='/café/')
|
||||||
self.assertEqual(pf.get_absolute_url(), '/caf%C3%A9/')
|
self.assertEqual(pf.get_absolute_url(), '/caf%C3%A9/')
|
||||||
|
|
||||||
|
@override_script_prefix('/beverages/')
|
||||||
def test_get_absolute_url_honors_script_prefix(self):
|
def test_get_absolute_url_honors_script_prefix(self):
|
||||||
pf = FlatPage(title="Tea!", url='/tea/')
|
pf = FlatPage(title="Tea!", url='/tea/')
|
||||||
set_script_prefix('/beverages/')
|
|
||||||
try:
|
|
||||||
self.assertEqual(pf.get_absolute_url(), '/beverages/tea/')
|
self.assertEqual(pf.get_absolute_url(), '/beverages/tea/')
|
||||||
finally:
|
|
||||||
clear_script_prefix()
|
|
||||||
|
|
|
@ -3,13 +3,12 @@ from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.urlresolvers import (
|
from django.core.urlresolvers import clear_url_caches, reverse, translate_url
|
||||||
clear_url_caches, reverse, set_script_prefix, translate_url,
|
|
||||||
)
|
|
||||||
from django.http import HttpResponsePermanentRedirect
|
from django.http import HttpResponsePermanentRedirect
|
||||||
from django.middleware.locale import LocaleMiddleware
|
from django.middleware.locale import LocaleMiddleware
|
||||||
from django.template import Context, Template
|
from django.template import Context, Template
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
|
from django.test.utils import override_script_prefix
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
|
||||||
|
@ -314,19 +313,11 @@ class URLRedirectWithScriptAliasTests(URLTestCaseBase):
|
||||||
"""
|
"""
|
||||||
#21579 - LocaleMiddleware should respect the script prefix.
|
#21579 - LocaleMiddleware should respect the script prefix.
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
|
||||||
super(URLRedirectWithScriptAliasTests, self).setUp()
|
|
||||||
self.script_prefix = '/script_prefix'
|
|
||||||
set_script_prefix(self.script_prefix)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(URLRedirectWithScriptAliasTests, self).tearDown()
|
|
||||||
# reset script prefix
|
|
||||||
set_script_prefix('')
|
|
||||||
|
|
||||||
def test_language_prefix_with_script_prefix(self):
|
def test_language_prefix_with_script_prefix(self):
|
||||||
response = self.client.get('/prefixed/', HTTP_ACCEPT_LANGUAGE='en', SCRIPT_NAME=self.script_prefix)
|
prefix = '/script_prefix'
|
||||||
self.assertRedirects(response, '%s/en/prefixed/' % self.script_prefix, target_status_code=404)
|
with override_script_prefix(prefix):
|
||||||
|
response = self.client.get('/prefixed/', HTTP_ACCEPT_LANGUAGE='en', SCRIPT_NAME=prefix)
|
||||||
|
self.assertRedirects(response, '%s/en/prefixed/' % prefix, target_status_code=404)
|
||||||
|
|
||||||
|
|
||||||
class URLTagTests(URLTestCaseBase):
|
class URLTagTests(URLTestCaseBase):
|
||||||
|
|
|
@ -24,6 +24,7 @@ from django.shortcuts import redirect
|
||||||
from django.test import (
|
from django.test import (
|
||||||
SimpleTestCase, TestCase, ignore_warnings, override_settings,
|
SimpleTestCase, TestCase, ignore_warnings, override_settings,
|
||||||
)
|
)
|
||||||
|
from django.test.utils import override_script_prefix
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
|
||||||
|
@ -199,33 +200,38 @@ class URLPatternReverse(TestCase):
|
||||||
# Reversing None should raise an error, not return the last un-named view.
|
# Reversing None should raise an error, not return the last un-named view.
|
||||||
self.assertRaises(NoReverseMatch, reverse, None)
|
self.assertRaises(NoReverseMatch, reverse, None)
|
||||||
|
|
||||||
|
@override_script_prefix('/{{invalid}}/')
|
||||||
def test_prefix_braces(self):
|
def test_prefix_braces(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/%7B%7Binvalid%7D%7D/includes/non_path_include/',
|
'/%7B%7Binvalid%7D%7D/includes/non_path_include/',
|
||||||
reverse('non_path_include', prefix='/{{invalid}}/')
|
reverse('non_path_include')
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_prefix_parenthesis(self):
|
def test_prefix_parenthesis(self):
|
||||||
# Parentheses are allowed and should not cause errors or be escaped
|
# Parentheses are allowed and should not cause errors or be escaped
|
||||||
|
with override_script_prefix('/bogus)/'):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/bogus)/includes/non_path_include/',
|
'/bogus)/includes/non_path_include/',
|
||||||
reverse('non_path_include', prefix='/bogus)/')
|
reverse('non_path_include')
|
||||||
)
|
)
|
||||||
|
with override_script_prefix('/(bogus)/'):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/(bogus)/includes/non_path_include/',
|
'/(bogus)/includes/non_path_include/',
|
||||||
reverse('non_path_include', prefix='/(bogus)/')
|
reverse('non_path_include')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@override_script_prefix('/bump%20map/')
|
||||||
def test_prefix_format_char(self):
|
def test_prefix_format_char(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'/bump%2520map/includes/non_path_include/',
|
'/bump%2520map/includes/non_path_include/',
|
||||||
reverse('non_path_include', prefix='/bump%20map/')
|
reverse('non_path_include')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@override_script_prefix('/%7Eme/')
|
||||||
def test_non_urlsafe_prefix_with_args(self):
|
def test_non_urlsafe_prefix_with_args(self):
|
||||||
# Regression for #20022, adjusted for #24013 because ~ is an unreserved
|
# Regression for #20022, adjusted for #24013 because ~ is an unreserved
|
||||||
# character. Tests whether % is escaped.
|
# character. Tests whether % is escaped.
|
||||||
self.assertEqual('/%257Eme/places/1/', reverse('places', args=[1], prefix='/%7Eme/'))
|
self.assertEqual('/%257Eme/places/1/', reverse('places', args=[1]))
|
||||||
|
|
||||||
def test_patterns_reported(self):
|
def test_patterns_reported(self):
|
||||||
# Regression for #17076
|
# Regression for #17076
|
||||||
|
@ -240,9 +246,10 @@ class URLPatternReverse(TestCase):
|
||||||
# exception
|
# exception
|
||||||
self.fail("Expected a NoReverseMatch, but none occurred.")
|
self.fail("Expected a NoReverseMatch, but none occurred.")
|
||||||
|
|
||||||
|
@override_script_prefix('/script:name/')
|
||||||
def test_script_name_escaping(self):
|
def test_script_name_escaping(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
reverse('optional', args=['foo:bar'], prefix='/script:name/'),
|
reverse('optional', args=['foo:bar']),
|
||||||
'/script:name/optional/foo:bar/'
|
'/script:name/optional/foo:bar/'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue