test_decorators.py 4.76 KB
Newer Older
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 classproperty, decorator_from_middleware
6 7


8 9 10
class ProcessViewMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        pass
11

12
process_view_dec = decorator_from_middleware(ProcessViewMiddleware)
13

Jason Myers's avatar
Jason Myers committed
14

15 16
@process_view_dec
def process_view(request):
17 18 19
    return HttpResponse()


20
class ClassProcessView(object):
21 22 23
    def __call__(self, request):
        return HttpResponse()

24
class_process_view = process_view_dec(ClassProcessView())
25

26

27 28 29 30
class FullMiddleware(object):
    def process_request(self, request):
        request.process_request_reached = True

31
    def process_view(self, request, view_func, view_args, view_kwargs):
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
        request.process_view_reached = True

    def process_template_response(self, request, response):
        request.process_template_response_reached = True
        return response

    def process_response(self, request, response):
        # This should never receive unrendered content.
        request.process_response_content = response.content
        request.process_response_reached = True
        return response

full_dec = decorator_from_middleware(FullMiddleware)


47
class DecoratorFromMiddlewareTests(SimpleTestCase):
48 49 50 51
    """
    Tests for view decorators created using
    ``django.utils.decorators.decorator_from_middleware``.
    """
52
    rf = RequestFactory()
53 54 55 56 57

    def test_process_view_middleware(self):
        """
        Test a middleware that implements process_view.
        """
58
        process_view(self.rf.get('/'))
59 60 61 62 63

    def test_callable_process_view_middleware(self):
        """
        Test a middleware that implements process_view, operating on a callable class.
        """
64
        class_process_view(self.rf.get('/'))
65 66 67 68 69 70 71 72

    def test_full_dec_normal(self):
        """
        Test that all methods of middleware are called for normal HttpResponses
        """

        @full_dec
        def normal_view(request):
73 74
            template = engines['django'].from_string("Hello world")
            return HttpResponse(template.render())
75 76

        request = self.rf.get('/')
77
        normal_view(request)
78 79 80 81 82 83 84 85 86 87 88 89 90 91
        self.assertTrue(getattr(request, 'process_request_reached', False))
        self.assertTrue(getattr(request, 'process_view_reached', False))
        # process_template_response must not be called for HttpResponse
        self.assertFalse(getattr(request, 'process_template_response_reached', False))
        self.assertTrue(getattr(request, 'process_response_reached', False))

    def test_full_dec_templateresponse(self):
        """
        Test that all methods of middleware are called for TemplateResponses in
        the right sequence.
        """

        @full_dec
        def template_response_view(request):
92 93
            template = engines['django'].from_string("Hello world")
            return TemplateResponse(request, template)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

        request = self.rf.get('/')
        response = template_response_view(request)
        self.assertTrue(getattr(request, 'process_request_reached', False))
        self.assertTrue(getattr(request, 'process_view_reached', False))
        self.assertTrue(getattr(request, 'process_template_response_reached', False))
        # response must not be rendered yet.
        self.assertFalse(response._is_rendered)
        # process_response must not be called until after response is rendered,
        # otherwise some decorators like csrf_protect and gzip_page will not
        # work correctly. See #16004
        self.assertFalse(getattr(request, 'process_response_reached', False))
        response.render()
        self.assertTrue(getattr(request, 'process_response_reached', False))
        # Check that process_response saw the rendered content
109
        self.assertEqual(request.process_response_content, b"Hello world")
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147


class ClassPropertyTest(SimpleTestCase):
    def test_getter(self):
        class Foo(object):
            foo_attr = 123

            def __init__(self):
                self.foo_attr = 456

            @classproperty
            def foo(cls):
                return cls.foo_attr

        class Bar(object):
            bar = classproperty()

            @bar.getter
            def bar(cls):
                return 123

        self.assertEqual(Foo.foo, 123)
        self.assertEqual(Foo().foo, 123)
        self.assertEqual(Bar.bar, 123)
        self.assertEqual(Bar().bar, 123)

    def test_override_getter(self):
        class Foo(object):
            @classproperty
            def foo(cls):
                return 123

            @foo.getter
            def foo(cls):
                return 456

        self.assertEqual(Foo.foo, 456)
        self.assertEqual(Foo().foo, 456)