tests.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. from django.conf import settings
  2. from django.core.exceptions import MiddlewareNotUsed
  3. from django.http import HttpResponse
  4. from django.test import RequestFactory, SimpleTestCase, override_settings
  5. from . import middleware as mw
  6. @override_settings(ROOT_URLCONF='middleware_exceptions.urls')
  7. class MiddlewareTests(SimpleTestCase):
  8. def tearDown(self):
  9. mw.log = []
  10. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessViewNoneMiddleware'])
  11. def test_process_view_return_none(self):
  12. response = self.client.get('/middleware_exceptions/view/')
  13. self.assertEqual(mw.log, ['processed view normal_view'])
  14. self.assertEqual(response.content, b'OK')
  15. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessViewMiddleware'])
  16. def test_process_view_return_response(self):
  17. response = self.client.get('/middleware_exceptions/view/')
  18. self.assertEqual(response.content, b'Processed view normal_view')
  19. @override_settings(MIDDLEWARE=[
  20. 'middleware_exceptions.middleware.ProcessViewTemplateResponseMiddleware',
  21. 'middleware_exceptions.middleware.LogMiddleware',
  22. ])
  23. def test_templateresponse_from_process_view_rendered(self):
  24. """
  25. TemplateResponses returned from process_view() must be rendered before
  26. being passed to any middleware that tries to access response.content,
  27. such as middleware_exceptions.middleware.LogMiddleware.
  28. """
  29. response = self.client.get('/middleware_exceptions/view/')
  30. self.assertEqual(response.content, b'Processed view normal_view\nProcessViewTemplateResponseMiddleware')
  31. @override_settings(MIDDLEWARE=[
  32. 'middleware_exceptions.middleware.ProcessViewTemplateResponseMiddleware',
  33. 'middleware_exceptions.middleware.TemplateResponseMiddleware',
  34. ])
  35. def test_templateresponse_from_process_view_passed_to_process_template_response(self):
  36. """
  37. TemplateResponses returned from process_view() should be passed to any
  38. template response middleware.
  39. """
  40. response = self.client.get('/middleware_exceptions/view/')
  41. expected_lines = [
  42. b'Processed view normal_view',
  43. b'ProcessViewTemplateResponseMiddleware',
  44. b'TemplateResponseMiddleware',
  45. ]
  46. self.assertEqual(response.content, b'\n'.join(expected_lines))
  47. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.TemplateResponseMiddleware'])
  48. def test_process_template_response(self):
  49. response = self.client.get('/middleware_exceptions/template_response/')
  50. self.assertEqual(response.content, b'template_response OK\nTemplateResponseMiddleware')
  51. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.NoTemplateResponseMiddleware'])
  52. def test_process_template_response_returns_none(self):
  53. msg = (
  54. "NoTemplateResponseMiddleware.process_template_response didn't "
  55. "return an HttpResponse object. It returned None instead."
  56. )
  57. with self.assertRaisesMessage(ValueError, msg):
  58. self.client.get('/middleware_exceptions/template_response/')
  59. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.LogMiddleware'])
  60. def test_view_exception_converted_before_middleware(self):
  61. response = self.client.get('/middleware_exceptions/permission_denied/')
  62. self.assertEqual(mw.log, [(response.status_code, response.content)])
  63. self.assertEqual(response.status_code, 403)
  64. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessExceptionMiddleware'])
  65. def test_view_exception_handled_by_process_exception(self):
  66. response = self.client.get('/middleware_exceptions/error/')
  67. self.assertEqual(response.content, b'Exception caught')
  68. @override_settings(MIDDLEWARE=[
  69. 'middleware_exceptions.middleware.ProcessExceptionLogMiddleware',
  70. 'middleware_exceptions.middleware.ProcessExceptionMiddleware',
  71. ])
  72. def test_response_from_process_exception_short_circuits_remainder(self):
  73. response = self.client.get('/middleware_exceptions/error/')
  74. self.assertEqual(mw.log, [])
  75. self.assertEqual(response.content, b'Exception caught')
  76. @override_settings(MIDDLEWARE=[
  77. 'middleware_exceptions.middleware.LogMiddleware',
  78. 'middleware_exceptions.middleware.NotFoundMiddleware',
  79. ])
  80. def test_exception_in_middleware_converted_before_prior_middleware(self):
  81. response = self.client.get('/middleware_exceptions/view/')
  82. self.assertEqual(mw.log, [(404, response.content)])
  83. self.assertEqual(response.status_code, 404)
  84. @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessExceptionMiddleware'])
  85. def test_exception_in_render_passed_to_process_exception(self):
  86. response = self.client.get('/middleware_exceptions/exception_in_render/')
  87. self.assertEqual(response.content, b'Exception caught')
  88. @override_settings(ROOT_URLCONF='middleware_exceptions.urls')
  89. class RootUrlconfTests(SimpleTestCase):
  90. @override_settings(ROOT_URLCONF=None)
  91. def test_missing_root_urlconf(self):
  92. # Removing ROOT_URLCONF is safe, as override_settings will restore
  93. # the previously defined settings.
  94. del settings.ROOT_URLCONF
  95. with self.assertRaises(AttributeError):
  96. self.client.get("/middleware_exceptions/view/")
  97. class MyMiddleware:
  98. def __init__(self, get_response):
  99. raise MiddlewareNotUsed
  100. def process_request(self, request):
  101. pass
  102. class MyMiddlewareWithExceptionMessage:
  103. def __init__(self, get_response):
  104. raise MiddlewareNotUsed('spam eggs')
  105. def process_request(self, request):
  106. pass
  107. @override_settings(
  108. DEBUG=True,
  109. ROOT_URLCONF='middleware_exceptions.urls',
  110. MIDDLEWARE=['django.middleware.common.CommonMiddleware'],
  111. )
  112. class MiddlewareNotUsedTests(SimpleTestCase):
  113. rf = RequestFactory()
  114. def test_raise_exception(self):
  115. request = self.rf.get('middleware_exceptions/view/')
  116. with self.assertRaises(MiddlewareNotUsed):
  117. MyMiddleware(lambda req: HttpResponse()).process_request(request)
  118. @override_settings(MIDDLEWARE=['middleware_exceptions.tests.MyMiddleware'])
  119. def test_log(self):
  120. with self.assertLogs('django.request', 'DEBUG') as cm:
  121. self.client.get('/middleware_exceptions/view/')
  122. self.assertEqual(
  123. cm.records[0].getMessage(),
  124. "MiddlewareNotUsed: 'middleware_exceptions.tests.MyMiddleware'"
  125. )
  126. @override_settings(MIDDLEWARE=['middleware_exceptions.tests.MyMiddlewareWithExceptionMessage'])
  127. def test_log_custom_message(self):
  128. with self.assertLogs('django.request', 'DEBUG') as cm:
  129. self.client.get('/middleware_exceptions/view/')
  130. self.assertEqual(
  131. cm.records[0].getMessage(),
  132. "MiddlewareNotUsed('middleware_exceptions.tests.MyMiddlewareWithExceptionMessage'): spam eggs"
  133. )
  134. @override_settings(DEBUG=False)
  135. def test_do_not_log_when_debug_is_false(self):
  136. with self.assertRaisesMessage(AssertionError, 'no logs'):
  137. with self.assertLogs('django.request', 'DEBUG'):
  138. self.client.get('/middleware_exceptions/view/')