summaryrefslogtreecommitdiff
path: root/tests/middleware_exceptions
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2016-06-14 00:41:58 -0700
committerCarl Meyer <carl@oddbird.net>2016-06-17 10:00:39 -0700
commit7d1b69dbe7f72ac04d2513f0468fe2146231b286 (patch)
tree31478358078d603fb54c02f22792d47707b9aed5 /tests/middleware_exceptions
parent104ee2fdae7fcd402396c709c91f5c84de6e4165 (diff)
downloaddjango-7d1b69dbe7f72ac04d2513f0468fe2146231b286.tar.gz
Refs #26601 -- Improved backwards-compatibility of DEP 5 middleware exception handling.
Diffstat (limited to 'tests/middleware_exceptions')
-rw-r--r--tests/middleware_exceptions/middleware.py54
-rw-r--r--tests/middleware_exceptions/test_legacy.py89
-rw-r--r--tests/middleware_exceptions/tests.py133
3 files changed, 188 insertions, 88 deletions
diff --git a/tests/middleware_exceptions/middleware.py b/tests/middleware_exceptions/middleware.py
index 6871d9556e..690660fb53 100644
--- a/tests/middleware_exceptions/middleware.py
+++ b/tests/middleware_exceptions/middleware.py
@@ -1,10 +1,58 @@
from __future__ import unicode_literals
-from django.http import HttpResponse
-from django.utils.deprecation import MiddlewareMixin
+from django.http import Http404, HttpResponse
+from django.template import engines
+log = []
-class ProcessExceptionMiddleware(MiddlewareMixin):
+class BaseMiddleware(object):
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ return self.get_response(request)
+
+
+class ProcessExceptionMiddleware(BaseMiddleware):
def process_exception(self, request, exception):
return HttpResponse('Exception caught')
+
+
+class ProcessExceptionLogMiddleware(BaseMiddleware):
+ def process_exception(self, request, exception):
+ log.append('process-exception')
+
+
+class ProcessExceptionExcMiddleware(BaseMiddleware):
+ def process_exception(self, request, exception):
+ raise Exception('from process-exception')
+
+
+class ProcessViewMiddleware(BaseMiddleware):
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ return HttpResponse('Processed view %s' % view_func.__name__)
+
+
+class ProcessViewNoneMiddleware(BaseMiddleware):
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ log.append('processed view %s' % view_func.__name__)
+ return None
+
+
+class TemplateResponseMiddleware(BaseMiddleware):
+ def process_template_response(self, request, response):
+ response.template_name = engines['django'].from_string('template-response middleware')
+ return response
+
+
+class LogMiddleware(BaseMiddleware):
+ def __call__(self, request):
+ response = self.get_response(request)
+ log.append((response.status_code, response.content))
+ return response
+
+
+class NotFoundMiddleware(BaseMiddleware):
+ def __call__(self, request):
+ raise Http404('not found')
diff --git a/tests/middleware_exceptions/test_legacy.py b/tests/middleware_exceptions/test_legacy.py
index 6aab3782d8..d59caa3882 100644
--- a/tests/middleware_exceptions/test_legacy.py
+++ b/tests/middleware_exceptions/test_legacy.py
@@ -1,15 +1,15 @@
import sys
-from django.conf import settings
-from django.core.exceptions import MiddlewareNotUsed
from django.core.signals import got_request_exception
from django.http import HttpResponse
from django.template import engines
from django.template.response import TemplateResponse
-from django.test import RequestFactory, SimpleTestCase, override_settings
-from django.test.utils import ignore_warnings, patch_logger
+from django.test import SimpleTestCase, override_settings
+from django.test.utils import ignore_warnings
from django.utils.deprecation import MiddlewareMixin, RemovedInDjango20Warning
+from .tests import MiddlewareNotUsedTests
+
class TestException(Exception):
pass
@@ -512,14 +512,6 @@ class MiddlewareTests(BaseMiddlewareExceptionTest):
# Check that the right middleware methods have been invoked
self.assert_middleware_usage(middleware, True, True, True, True, False)
- @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessExceptionMiddleware'])
- def test_exception_in_render_passed_to_process_exception(self):
- # Repopulate the list of middlewares since it's already been populated
- # by setUp() before the MIDDLEWARE setting got overridden.
- self.client.handler.load_middleware()
- response = self.client.get('/middleware_exceptions/exception_in_render/')
- self.assertEqual(response.content, b'Exception caught')
-
class BadMiddlewareTests(BaseMiddlewareExceptionTest):
@@ -869,79 +861,6 @@ class BadMiddlewareTests(BaseMiddlewareExceptionTest):
self.assert_middleware_usage(middleware, True, True, True, True, False)
self.assert_middleware_usage(post_middleware, True, True, True, True, False)
-_missing = object()
-
-
-@override_settings(ROOT_URLCONF='middleware_exceptions.urls')
-class RootUrlconfTests(SimpleTestCase):
-
- @override_settings(ROOT_URLCONF=None)
- def test_missing_root_urlconf(self):
- # Removing ROOT_URLCONF is safe, as override_settings will restore
- # the previously defined settings.
- del settings.ROOT_URLCONF
- with self.assertRaises(AttributeError):
- self.client.get("/middleware_exceptions/view/")
-
-
-class MyMiddleware(object):
-
- def __init__(self, get_response=None):
- raise MiddlewareNotUsed
-
- def process_request(self, request):
- pass
-
-
-class MyMiddlewareWithExceptionMessage(object):
-
- def __init__(self, get_response=None):
- raise MiddlewareNotUsed('spam eggs')
-
- def process_request(self, request):
- pass
-
-
-@override_settings(
- DEBUG=True,
- ROOT_URLCONF='middleware_exceptions.urls',
- MIDDLEWARE=['django.middleware.common.CommonMiddleware'],
-)
-class MiddlewareNotUsedTests(SimpleTestCase):
-
- rf = RequestFactory()
-
- def test_raise_exception(self):
- request = self.rf.get('middleware_exceptions/view/')
- with self.assertRaises(MiddlewareNotUsed):
- MyMiddleware().process_request(request)
-
- @override_settings(MIDDLEWARE=['middleware_exceptions.test_legacy.MyMiddleware'])
- def test_log(self):
- with patch_logger('django.request', 'debug') as calls:
- self.client.get('/middleware_exceptions/view/')
- self.assertEqual(len(calls), 1)
- self.assertEqual(
- calls[0],
- "MiddlewareNotUsed: 'middleware_exceptions.test_legacy.MyMiddleware'"
- )
-
- @override_settings(MIDDLEWARE=['middleware_exceptions.test_legacy.MyMiddlewareWithExceptionMessage'])
- def test_log_custom_message(self):
- with patch_logger('django.request', 'debug') as calls:
- self.client.get('/middleware_exceptions/view/')
- self.assertEqual(len(calls), 1)
- self.assertEqual(
- calls[0],
- "MiddlewareNotUsed('middleware_exceptions.test_legacy.MyMiddlewareWithExceptionMessage'): spam eggs"
- )
-
- @override_settings(DEBUG=False)
- def test_do_not_log_when_debug_is_false(self):
- with patch_logger('django.request', 'debug') as calls:
- self.client.get('/middleware_exceptions/view/')
- self.assertEqual(len(calls), 0)
-
@ignore_warnings(category=RemovedInDjango20Warning)
@override_settings(
diff --git a/tests/middleware_exceptions/tests.py b/tests/middleware_exceptions/tests.py
new file mode 100644
index 0000000000..f6a7e24e59
--- /dev/null
+++ b/tests/middleware_exceptions/tests.py
@@ -0,0 +1,133 @@
+from django.conf import settings
+from django.core.exceptions import MiddlewareNotUsed
+from django.test import RequestFactory, SimpleTestCase, override_settings
+from django.test.utils import patch_logger
+
+from . import middleware as mw
+
+
+@override_settings(ROOT_URLCONF='middleware_exceptions.urls')
+class MiddlewareTests(SimpleTestCase):
+ def tearDown(self):
+ mw.log = []
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessViewNoneMiddleware'])
+ def test_process_view_return_none(self):
+ response = self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(mw.log, ['processed view normal_view'])
+ self.assertEqual(response.content, b'OK')
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessViewMiddleware'])
+ def test_process_view_return_response(self):
+ response = self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(response.content, b'Processed view normal_view')
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.TemplateResponseMiddleware'])
+ def test_process_template_response(self):
+ response = self.client.get('/middleware_exceptions/template_response/')
+ self.assertEqual(response.content, b'template-response middleware')
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.LogMiddleware'])
+ def test_view_exception_converted_before_middleware(self):
+ response = self.client.get('/middleware_exceptions/permission_denied/')
+ self.assertEqual(mw.log, [(response.status_code, response.content)])
+ self.assertEqual(response.status_code, 403)
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessExceptionMiddleware'])
+ def test_view_exception_handled_by_process_exception(self):
+ response = self.client.get('/middleware_exceptions/error/')
+ self.assertEqual(response.content, b'Exception caught')
+
+ @override_settings(MIDDLEWARE=[
+ 'middleware_exceptions.middleware.ProcessExceptionLogMiddleware',
+ 'middleware_exceptions.middleware.ProcessExceptionMiddleware',
+ ])
+ def test_response_from_process_exception_short_circuits_remainder(self):
+ response = self.client.get('/middleware_exceptions/error/')
+ self.assertEqual(mw.log, [])
+ self.assertEqual(response.content, b'Exception caught')
+
+ @override_settings(MIDDLEWARE=[
+ 'middleware_exceptions.middleware.LogMiddleware',
+ 'middleware_exceptions.middleware.NotFoundMiddleware',
+ ])
+ def test_exception_in_middleware_converted_before_prior_middleware(self):
+ response = self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(mw.log, [(404, response.content)])
+ self.assertEqual(response.status_code, 404)
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.middleware.ProcessExceptionMiddleware'])
+ def test_exception_in_render_passed_to_process_exception(self):
+ response = self.client.get('/middleware_exceptions/exception_in_render/')
+ self.assertEqual(response.content, b'Exception caught')
+
+
+@override_settings(ROOT_URLCONF='middleware_exceptions.urls')
+class RootUrlconfTests(SimpleTestCase):
+
+ @override_settings(ROOT_URLCONF=None)
+ def test_missing_root_urlconf(self):
+ # Removing ROOT_URLCONF is safe, as override_settings will restore
+ # the previously defined settings.
+ del settings.ROOT_URLCONF
+ with self.assertRaises(AttributeError):
+ self.client.get("/middleware_exceptions/view/")
+
+
+class MyMiddleware(object):
+
+ def __init__(self, get_response=None):
+ raise MiddlewareNotUsed
+
+ def process_request(self, request):
+ pass
+
+
+class MyMiddlewareWithExceptionMessage(object):
+
+ def __init__(self, get_response=None):
+ raise MiddlewareNotUsed('spam eggs')
+
+ def process_request(self, request):
+ pass
+
+
+@override_settings(
+ DEBUG=True,
+ ROOT_URLCONF='middleware_exceptions.urls',
+ MIDDLEWARE=['django.middleware.common.CommonMiddleware'],
+)
+class MiddlewareNotUsedTests(SimpleTestCase):
+
+ rf = RequestFactory()
+
+ def test_raise_exception(self):
+ request = self.rf.get('middleware_exceptions/view/')
+ with self.assertRaises(MiddlewareNotUsed):
+ MyMiddleware().process_request(request)
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.tests.MyMiddleware'])
+ def test_log(self):
+ with patch_logger('django.request', 'debug') as calls:
+ self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(len(calls), 1)
+ self.assertEqual(
+ calls[0],
+ "MiddlewareNotUsed: 'middleware_exceptions.tests.MyMiddleware'"
+ )
+
+ @override_settings(MIDDLEWARE=['middleware_exceptions.tests.MyMiddlewareWithExceptionMessage'])
+ def test_log_custom_message(self):
+ with patch_logger('django.request', 'debug') as calls:
+ self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(len(calls), 1)
+ self.assertEqual(
+ calls[0],
+ "MiddlewareNotUsed('middleware_exceptions.tests.MyMiddlewareWithExceptionMessage'): spam eggs"
+ )
+
+ @override_settings(DEBUG=False)
+ def test_do_not_log_when_debug_is_false(self):
+ with patch_logger('django.request', 'debug') as calls:
+ self.client.get('/middleware_exceptions/view/')
+ self.assertEqual(len(calls), 0)