-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
/
tests.py
153 lines (129 loc) · 6.03 KB
/
tests.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
148
149
150
151
152
153
from unittest import TestCase
from sys import version_info
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.3, 2.4 fallback.
from django.http import HttpResponse, HttpRequest
from django.utils.functional import allow_lazy, lazy, memoize
from django.views.decorators.http import require_http_methods, require_GET, require_POST
from django.views.decorators.vary import vary_on_headers, vary_on_cookie
from django.views.decorators.cache import cache_page, never_cache, cache_control
from django.utils.decorators import auto_adapt_to_methods
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
from django.contrib.admin.views.decorators import staff_member_required
def fully_decorated(request):
"""Expected __doc__"""
return HttpResponse('<html><body>dummy</body></html>')
fully_decorated.anything = "Expected __dict__"
# django.views.decorators.http
fully_decorated = require_http_methods(["GET"])(fully_decorated)
fully_decorated = require_GET(fully_decorated)
fully_decorated = require_POST(fully_decorated)
# django.views.decorators.vary
fully_decorated = vary_on_headers('Accept-language')(fully_decorated)
fully_decorated = vary_on_cookie(fully_decorated)
# django.views.decorators.cache
fully_decorated = cache_page(60*15)(fully_decorated)
fully_decorated = cache_control(private=True)(fully_decorated)
fully_decorated = never_cache(fully_decorated)
# django.contrib.auth.decorators
# Apply user_passes_test twice to check #9474
fully_decorated = user_passes_test(lambda u:True)(fully_decorated)
fully_decorated = login_required(fully_decorated)
fully_decorated = permission_required('change_world')(fully_decorated)
# django.contrib.admin.views.decorators
fully_decorated = staff_member_required(fully_decorated)
# django.utils.functional
fully_decorated = memoize(fully_decorated, {}, 1)
fully_decorated = allow_lazy(fully_decorated)
fully_decorated = lazy(fully_decorated)
class DecoratorsTest(TestCase):
def test_attributes(self):
"""
Tests that django decorators set certain attributes of the wrapped
function.
"""
# Only check __name__ on Python 2.4 or later since __name__ can't be
# assigned to in earlier Python versions.
if version_info[0] >= 2 and version_info[1] >= 4:
self.assertEquals(fully_decorated.__name__, 'fully_decorated')
self.assertEquals(fully_decorated.__doc__, 'Expected __doc__')
self.assertEquals(fully_decorated.__dict__['anything'], 'Expected __dict__')
def test_user_passes_test_composition(self):
"""
Test that the user_passes_test decorator can be applied multiple times
(#9474).
"""
def test1(user):
user.decorators_applied.append('test1')
return True
def test2(user):
user.decorators_applied.append('test2')
return True
def callback(request):
return request.user.decorators_applied
callback = user_passes_test(test1)(callback)
callback = user_passes_test(test2)(callback)
class DummyUser(object): pass
class DummyRequest(object): pass
request = DummyRequest()
request.user = DummyUser()
request.user.decorators_applied = []
response = callback(request)
self.assertEqual(response, ['test2', 'test1'])
def test_cache_page_new_style(self):
"""
Test that we can call cache_page the new way
"""
def my_view(request):
return "response"
my_view_cached = cache_page(123)(my_view)
self.assertEqual(my_view_cached(HttpRequest()), "response")
my_view_cached2 = cache_page(123, key_prefix="test")(my_view)
self.assertEqual(my_view_cached2(HttpRequest()), "response")
def test_cache_page_old_style(self):
"""
Test that we can call cache_page the old way
"""
def my_view(request):
return "response"
my_view_cached = cache_page(my_view, 123)
self.assertEqual(my_view_cached(HttpRequest()), "response")
my_view_cached2 = cache_page(my_view, 123, key_prefix="test")
self.assertEqual(my_view_cached2(HttpRequest()), "response")
class MethodDecoratorAdapterTests(TestCase):
def test_auto_adapt_to_methods(self):
"""
Test that auto_adapt_to_methods actually works.
"""
# Need 2 decorators with auto_adapt_to_methods,
# to check it plays nicely with composing itself.
def my_decorator(func):
def wrapped(*args, **kwargs):
# need to ensure that the first arg isn't 'self'
self.assertEqual(args[0], "test")
return "my_decorator:" + func(*args, **kwargs)
wrapped.my_decorator_custom_attribute = True
return wraps(func)(wrapped)
my_decorator = auto_adapt_to_methods(my_decorator)
def my_decorator2(func):
def wrapped(*args, **kwargs):
# need to ensure that the first arg isn't 'self'
self.assertEqual(args[0], "test")
return "my_decorator2:" + func(*args, **kwargs)
wrapped.my_decorator2_custom_attribute = True
return wraps(func)(wrapped)
my_decorator2 = auto_adapt_to_methods(my_decorator2)
class MyClass(object):
def my_method(self, *args, **kwargs):
return "my_method:%r %r" % (args, kwargs)
my_method = my_decorator2(my_decorator(my_method))
obj = MyClass()
self.assertEqual(obj.my_method("test", 123, name='foo'),
"my_decorator2:my_decorator:my_method:('test', 123) {'name': 'foo'}")
self.assertEqual(obj.my_method.__name__, 'my_method')
self.assertEqual(getattr(obj.my_method, 'my_decorator_custom_attribute', False),
True)
self.assertEqual(getattr(obj.my_method, 'my_decorator2_custom_attribute', False),
True)