2
0

test_urls.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. from django.conf import settings
  2. from django.core.checks.messages import Warning
  3. from django.core.checks.urls import (
  4. E006, check_url_config, check_url_namespaces_unique, check_url_settings,
  5. get_warning_for_invalid_pattern,
  6. )
  7. from django.test import SimpleTestCase
  8. from django.test.utils import override_settings
  9. class CheckUrlConfigTests(SimpleTestCase):
  10. @override_settings(ROOT_URLCONF='check_framework.urls.no_warnings')
  11. def test_no_warnings(self):
  12. result = check_url_config(None)
  13. self.assertEqual(result, [])
  14. @override_settings(ROOT_URLCONF='check_framework.urls.warning_in_include')
  15. def test_check_resolver_recursive(self):
  16. # The resolver is checked recursively (examining url()s in include()).
  17. result = check_url_config(None)
  18. self.assertEqual(len(result), 1)
  19. warning = result[0]
  20. self.assertEqual(warning.id, 'urls.W001')
  21. @override_settings(ROOT_URLCONF='check_framework.urls.include_with_dollar')
  22. def test_include_with_dollar(self):
  23. result = check_url_config(None)
  24. self.assertEqual(len(result), 1)
  25. warning = result[0]
  26. self.assertEqual(warning.id, 'urls.W001')
  27. expected_msg = "Your URL pattern '^include-with-dollar$' uses include with a regex ending with a '$'."
  28. self.assertIn(expected_msg, warning.msg)
  29. @override_settings(ROOT_URLCONF='check_framework.urls.contains_tuple')
  30. def test_contains_tuple_not_url_instance(self):
  31. result = check_url_config(None)
  32. warning = result[0]
  33. self.assertEqual(warning.id, 'urls.E004')
  34. self.assertRegex(warning.msg, (
  35. r"^Your URL pattern \('\^tuple/\$', <function <lambda> at 0x(\w+)>\) is "
  36. r"invalid. Ensure that urlpatterns is a list of url\(\) instances.$"
  37. ))
  38. @override_settings(ROOT_URLCONF='check_framework.urls.beginning_with_slash')
  39. def test_beginning_with_slash(self):
  40. result = check_url_config(None)
  41. self.assertEqual(len(result), 1)
  42. warning = result[0]
  43. self.assertEqual(warning.id, 'urls.W002')
  44. expected_msg = (
  45. "Your URL pattern '/starting-with-slash/$' has a regex beginning "
  46. "with a '/'. Remove this slash as it is unnecessary. If this "
  47. "pattern is targeted in an include(), ensure the include() pattern "
  48. "has a trailing '/'."
  49. )
  50. self.assertIn(expected_msg, warning.msg)
  51. @override_settings(
  52. ROOT_URLCONF='check_framework.urls.beginning_with_slash',
  53. APPEND_SLASH=False,
  54. )
  55. def test_beginning_with_slash_append_slash(self):
  56. # It can be useful to start a URL pattern with a slash when
  57. # APPEND_SLASH=False (#27238).
  58. result = check_url_config(None)
  59. self.assertEqual(result, [])
  60. @override_settings(ROOT_URLCONF='check_framework.urls.name_with_colon')
  61. def test_name_with_colon(self):
  62. result = check_url_config(None)
  63. self.assertEqual(len(result), 1)
  64. warning = result[0]
  65. self.assertEqual(warning.id, 'urls.W003')
  66. expected_msg = "Your URL pattern '^$' [name='name_with:colon'] has a name including a ':'."
  67. self.assertIn(expected_msg, warning.msg)
  68. @override_settings(ROOT_URLCONF=None)
  69. def test_no_root_urlconf_in_settings(self):
  70. delattr(settings, 'ROOT_URLCONF')
  71. result = check_url_config(None)
  72. self.assertEqual(result, [])
  73. def test_get_warning_for_invalid_pattern_string(self):
  74. warning = get_warning_for_invalid_pattern('')[0]
  75. self.assertEqual(
  76. warning.hint,
  77. "Try removing the string ''. The list of urlpatterns should "
  78. "not have a prefix string as the first element.",
  79. )
  80. def test_get_warning_for_invalid_pattern_tuple(self):
  81. warning = get_warning_for_invalid_pattern((r'^$', lambda x: x))[0]
  82. self.assertEqual(warning.hint, "Try using url() instead of a tuple.")
  83. def test_get_warning_for_invalid_pattern_other(self):
  84. warning = get_warning_for_invalid_pattern(object())[0]
  85. self.assertIsNone(warning.hint)
  86. @override_settings(ROOT_URLCONF='check_framework.urls.non_unique_namespaces')
  87. def test_check_non_unique_namespaces(self):
  88. result = check_url_namespaces_unique(None)
  89. self.assertEqual(len(result), 2)
  90. non_unique_namespaces = ['app-ns1', 'app-1']
  91. warning_messages = [
  92. "URL namespace '{}' isn't unique. You may not be able to reverse "
  93. "all URLs in this namespace".format(namespace)
  94. for namespace in non_unique_namespaces
  95. ]
  96. for warning in result:
  97. self.assertIsInstance(warning, Warning)
  98. self.assertEqual('urls.W005', warning.id)
  99. self.assertIn(warning.msg, warning_messages)
  100. @override_settings(ROOT_URLCONF='check_framework.urls.unique_namespaces')
  101. def test_check_unique_namespaces(self):
  102. result = check_url_namespaces_unique(None)
  103. self.assertEqual(result, [])
  104. class CheckURLSettingsTests(SimpleTestCase):
  105. @override_settings(STATIC_URL='a/', MEDIA_URL='b/')
  106. def test_slash_no_errors(self):
  107. self.assertEqual(check_url_settings(None), [])
  108. @override_settings(STATIC_URL='', MEDIA_URL='')
  109. def test_empty_string_no_errors(self):
  110. self.assertEqual(check_url_settings(None), [])
  111. @override_settings(STATIC_URL='noslash')
  112. def test_static_url_no_slash(self):
  113. self.assertEqual(check_url_settings(None), [E006('STATIC_URL')])
  114. @override_settings(STATIC_URL='slashes//')
  115. def test_static_url_double_slash_allowed(self):
  116. # The check allows for a double slash, presuming the user knows what
  117. # they are doing.
  118. self.assertEqual(check_url_settings(None), [])
  119. @override_settings(MEDIA_URL='noslash')
  120. def test_media_url_no_slash(self):
  121. self.assertEqual(check_url_settings(None), [E006('MEDIA_URL')])