1. from django.http import HttpResponse
    
  2. from django.template import engines
    
  3. from django.template.response import TemplateResponse
    
  4. from django.test import RequestFactory, SimpleTestCase
    
  5. from django.utils.decorators import decorator_from_middleware
    
  6. 
    
  7. 
    
  8. class ProcessViewMiddleware:
    
  9.     def __init__(self, get_response):
    
  10.         self.get_response = get_response
    
  11. 
    
  12.     def process_view(self, request, view_func, view_args, view_kwargs):
    
  13.         pass
    
  14. 
    
  15. 
    
  16. process_view_dec = decorator_from_middleware(ProcessViewMiddleware)
    
  17. 
    
  18. 
    
  19. @process_view_dec
    
  20. def process_view(request):
    
  21.     return HttpResponse()
    
  22. 
    
  23. 
    
  24. class ClassProcessView:
    
  25.     def __call__(self, request):
    
  26.         return HttpResponse()
    
  27. 
    
  28. 
    
  29. class_process_view = process_view_dec(ClassProcessView())
    
  30. 
    
  31. 
    
  32. class FullMiddleware:
    
  33.     def __init__(self, get_response):
    
  34.         self.get_response = get_response
    
  35. 
    
  36.     def process_request(self, request):
    
  37.         request.process_request_reached = True
    
  38. 
    
  39.     def process_view(self, request, view_func, view_args, view_kwargs):
    
  40.         request.process_view_reached = True
    
  41. 
    
  42.     def process_template_response(self, request, response):
    
  43.         request.process_template_response_reached = True
    
  44.         return response
    
  45. 
    
  46.     def process_response(self, request, response):
    
  47.         # This should never receive unrendered content.
    
  48.         request.process_response_content = response.content
    
  49.         request.process_response_reached = True
    
  50.         return response
    
  51. 
    
  52. 
    
  53. full_dec = decorator_from_middleware(FullMiddleware)
    
  54. 
    
  55. 
    
  56. class DecoratorFromMiddlewareTests(SimpleTestCase):
    
  57.     """
    
  58.     Tests for view decorators created using
    
  59.     ``django.utils.decorators.decorator_from_middleware``.
    
  60.     """
    
  61. 
    
  62.     rf = RequestFactory()
    
  63. 
    
  64.     def test_process_view_middleware(self):
    
  65.         """
    
  66.         Test a middleware that implements process_view.
    
  67.         """
    
  68.         process_view(self.rf.get("/"))
    
  69. 
    
  70.     def test_callable_process_view_middleware(self):
    
  71.         """
    
  72.         Test a middleware that implements process_view, operating on a callable class.
    
  73.         """
    
  74.         class_process_view(self.rf.get("/"))
    
  75. 
    
  76.     def test_full_dec_normal(self):
    
  77.         """
    
  78.         All methods of middleware are called for normal HttpResponses
    
  79.         """
    
  80. 
    
  81.         @full_dec
    
  82.         def normal_view(request):
    
  83.             template = engines["django"].from_string("Hello world")
    
  84.             return HttpResponse(template.render())
    
  85. 
    
  86.         request = self.rf.get("/")
    
  87.         normal_view(request)
    
  88.         self.assertTrue(getattr(request, "process_request_reached", False))
    
  89.         self.assertTrue(getattr(request, "process_view_reached", False))
    
  90.         # process_template_response must not be called for HttpResponse
    
  91.         self.assertFalse(getattr(request, "process_template_response_reached", False))
    
  92.         self.assertTrue(getattr(request, "process_response_reached", False))
    
  93. 
    
  94.     def test_full_dec_templateresponse(self):
    
  95.         """
    
  96.         All methods of middleware are called for TemplateResponses in
    
  97.         the right sequence.
    
  98.         """
    
  99. 
    
  100.         @full_dec
    
  101.         def template_response_view(request):
    
  102.             template = engines["django"].from_string("Hello world")
    
  103.             return TemplateResponse(request, template)
    
  104. 
    
  105.         request = self.rf.get("/")
    
  106.         response = template_response_view(request)
    
  107.         self.assertTrue(getattr(request, "process_request_reached", False))
    
  108.         self.assertTrue(getattr(request, "process_view_reached", False))
    
  109.         self.assertTrue(getattr(request, "process_template_response_reached", False))
    
  110.         # response must not be rendered yet.
    
  111.         self.assertFalse(response._is_rendered)
    
  112.         # process_response must not be called until after response is rendered,
    
  113.         # otherwise some decorators like csrf_protect and gzip_page will not
    
  114.         # work correctly. See #16004
    
  115.         self.assertFalse(getattr(request, "process_response_reached", False))
    
  116.         response.render()
    
  117.         self.assertTrue(getattr(request, "process_response_reached", False))
    
  118.         # process_response saw the rendered content
    
  119.         self.assertEqual(request.process_response_content, b"Hello world")