2016-02-02 01:24:33 +08:00
|
|
|
from django.conf import settings
|
2016-12-22 05:54:15 +08:00
|
|
|
from django.core.checks.messages import Warning
|
2016-04-02 18:49:12 +08:00
|
|
|
from django.core.checks.urls import (
|
2016-12-22 06:05:59 +08:00
|
|
|
check_url_config, check_url_namespaces_unique,
|
|
|
|
get_warning_for_invalid_pattern,
|
2016-04-02 18:49:12 +08:00
|
|
|
)
|
2015-09-17 06:07:39 +08:00
|
|
|
from django.test import SimpleTestCase
|
|
|
|
from django.test.utils import override_settings
|
|
|
|
|
|
|
|
|
|
|
|
class CheckUrlsTest(SimpleTestCase):
|
2015-09-22 01:45:56 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.no_warnings')
|
|
|
|
def test_no_warnings(self):
|
2015-09-17 06:07:39 +08:00
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(result, [])
|
|
|
|
|
2016-04-28 05:38:00 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.warning_in_include')
|
|
|
|
def test_check_resolver_recursive(self):
|
|
|
|
# The resolver is checked recursively (examining url()s in include()).
|
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(len(result), 1)
|
|
|
|
warning = result[0]
|
|
|
|
self.assertEqual(warning.id, 'urls.W001')
|
|
|
|
|
2015-09-22 01:45:56 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.include_with_dollar')
|
2015-09-17 06:07:39 +08:00
|
|
|
def test_include_with_dollar(self):
|
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(len(result), 1)
|
|
|
|
warning = result[0]
|
|
|
|
self.assertEqual(warning.id, 'urls.W001')
|
|
|
|
expected_msg = "Your URL pattern '^include-with-dollar$' uses include with a regex ending with a '$'."
|
|
|
|
self.assertIn(expected_msg, warning.msg)
|
|
|
|
|
2016-04-02 18:49:12 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.contains_tuple')
|
|
|
|
def test_contains_tuple_not_url_instance(self):
|
|
|
|
result = check_url_config(None)
|
|
|
|
warning = result[0]
|
|
|
|
self.assertEqual(warning.id, 'urls.E004')
|
2016-12-08 06:42:31 +08:00
|
|
|
self.assertRegex(warning.msg, (
|
2016-04-02 18:49:12 +08:00
|
|
|
r"^Your URL pattern \('\^tuple/\$', <function <lambda> at 0x(\w+)>\) is "
|
|
|
|
r"invalid. Ensure that urlpatterns is a list of url\(\) instances.$"
|
|
|
|
))
|
|
|
|
|
2015-09-22 01:45:56 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.beginning_with_slash')
|
|
|
|
def test_beginning_with_slash(self):
|
2015-09-17 06:07:39 +08:00
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(len(result), 1)
|
|
|
|
warning = result[0]
|
|
|
|
self.assertEqual(warning.id, 'urls.W002')
|
2016-09-01 21:39:56 +08:00
|
|
|
expected_msg = (
|
|
|
|
"Your URL pattern '/starting-with-slash/$' has a regex beginning "
|
|
|
|
"with a '/'. Remove this slash as it is unnecessary. If this "
|
|
|
|
"pattern is targeted in an include(), ensure the include() pattern "
|
|
|
|
"has a trailing '/'."
|
|
|
|
)
|
|
|
|
|
2015-09-17 06:07:39 +08:00
|
|
|
self.assertIn(expected_msg, warning.msg)
|
|
|
|
|
2016-09-20 04:18:41 +08:00
|
|
|
@override_settings(
|
|
|
|
ROOT_URLCONF='check_framework.urls.beginning_with_slash',
|
|
|
|
APPEND_SLASH=False,
|
|
|
|
)
|
|
|
|
def test_beginning_with_slash_append_slash(self):
|
|
|
|
# It can be useful to start a URL pattern with a slash when
|
|
|
|
# APPEND_SLASH=False (#27238).
|
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(result, [])
|
|
|
|
|
2015-09-22 01:45:56 +08:00
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.name_with_colon')
|
|
|
|
def test_name_with_colon(self):
|
2015-09-17 06:07:39 +08:00
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(len(result), 1)
|
|
|
|
warning = result[0]
|
|
|
|
self.assertEqual(warning.id, 'urls.W003')
|
|
|
|
expected_msg = "Your URL pattern '^$' [name='name_with:colon'] has a name including a ':'."
|
|
|
|
self.assertIn(expected_msg, warning.msg)
|
2016-02-02 01:24:33 +08:00
|
|
|
|
|
|
|
@override_settings(ROOT_URLCONF=None)
|
|
|
|
def test_no_root_urlconf_in_settings(self):
|
|
|
|
delattr(settings, 'ROOT_URLCONF')
|
|
|
|
result = check_url_config(None)
|
|
|
|
self.assertEqual(result, [])
|
2016-04-02 18:49:12 +08:00
|
|
|
|
|
|
|
def test_get_warning_for_invalid_pattern_string(self):
|
|
|
|
warning = get_warning_for_invalid_pattern('')[0]
|
|
|
|
self.assertEqual(
|
|
|
|
warning.hint,
|
|
|
|
"Try removing the string ''. The list of urlpatterns should "
|
|
|
|
"not have a prefix string as the first element.",
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_get_warning_for_invalid_pattern_tuple(self):
|
|
|
|
warning = get_warning_for_invalid_pattern((r'^$', lambda x: x))[0]
|
|
|
|
self.assertEqual(warning.hint, "Try using url() instead of a tuple.")
|
|
|
|
|
|
|
|
def test_get_warning_for_invalid_pattern_other(self):
|
|
|
|
warning = get_warning_for_invalid_pattern(object())[0]
|
|
|
|
self.assertIsNone(warning.hint)
|
2016-12-22 05:54:15 +08:00
|
|
|
|
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.non_unique_namespaces')
|
|
|
|
def test_check_non_unique_namespaces(self):
|
|
|
|
result = check_url_namespaces_unique(None)
|
|
|
|
self.assertEqual(len(result), 2)
|
|
|
|
non_unique_namespaces = ['app-ns1', 'app-1']
|
|
|
|
warning_messages = [
|
|
|
|
"URL namespace '{}' isn't unique. You may not be able to reverse "
|
|
|
|
"all URLs in this namespace".format(namespace)
|
|
|
|
for namespace in non_unique_namespaces
|
|
|
|
]
|
|
|
|
for warning in result:
|
|
|
|
self.assertIsInstance(warning, Warning)
|
|
|
|
self.assertEqual('urls.W005', warning.id)
|
|
|
|
self.assertIn(warning.msg, warning_messages)
|
|
|
|
|
|
|
|
@override_settings(ROOT_URLCONF='check_framework.urls.unique_namespaces')
|
|
|
|
def test_check_unique_namespaces(self):
|
|
|
|
result = check_url_namespaces_unique(None)
|
|
|
|
self.assertEqual(result, [])
|