1099.1.16
by William Grant
ivle.webapp.base.test: |
1 |
import urllib |
2 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
3 |
from ivle.webapp.base.rest import (JSONRESTView, named_operation, |
4 |
require_permission) |
|
5 |
from ivle.webapp.errors import BadRequest, MethodNotAllowed, Unauthorized |
|
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
6 |
from ivle.webapp.testing import FakeUser, FakeRequest |
7 |
||
1099.1.26
by William Grant
ivle.webapp.base.views#JSONRESTView: Check that methods are available before |
8 |
class JSONRESTViewTestWithoutPUT(JSONRESTView): |
9 |
'''A small JSON REST view for testing purposes, without a PUT method.'''
|
|
1544
by Matt Giuca
Added an argument 'config' to every single get_permissions method throughout the program. All calls to get_permissions pass a config. This is to allow per-site policy configurations on permissions. |
10 |
def get_permissions(self, user, config): |
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
11 |
if user.login == u'fakeuser': |
12 |
return set(['view', 'edit']) |
|
13 |
if user.login == u'otheruser': |
|
14 |
return set(['view']) |
|
15 |
return set() |
|
16 |
||
17 |
@require_permission('view') |
|
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
18 |
def GET(self, req): |
19 |
return {'method': 'get'} |
|
20 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
21 |
@require_permission('edit') |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
22 |
def PATCH(self, req, data): |
23 |
return {'method': 'patch', |
|
24 |
'result': data['result'], 'test': data['test']} |
|
25 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
26 |
@named_operation('view') |
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
27 |
def do_stuff(self, req, what): |
1099.1.16
by William Grant
ivle.webapp.base.test: |
28 |
return {'result': 'Did %s!' % what} |
29 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
30 |
@named_operation('edit') |
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
31 |
def say_something(self, req, thing='nothing'): |
1099.1.27
by William Grant
ivle.webapp.base.views#JSONRESTView: Add support for argument defaults in |
32 |
return {'result': 'Said %s!' % thing} |
33 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
34 |
@named_operation('edit') |
1099.1.52
by William Grant
ivle.webapp.base.rest#RESTView: Remove broken old render() - it should be |
35 |
def do_say_something(self, req, what, thing='nothing'): |
36 |
return {'result': 'Said %s and %s!' % (what, thing)} |
|
37 |
||
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
38 |
@named_operation('view') |
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
39 |
def get_req_method(self, req): |
40 |
return {'method': req.method} |
|
41 |
||
1099.1.26
by William Grant
ivle.webapp.base.views#JSONRESTView: Check that methods are available before |
42 |
class JSONRESTViewTest(JSONRESTViewTestWithoutPUT): |
43 |
'''A small JSON REST view for testing purposes.'''
|
|
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
44 |
@require_permission('edit') |
1099.1.26
by William Grant
ivle.webapp.base.views#JSONRESTView: Check that methods are available before |
45 |
def PUT(self, req, data): |
46 |
return {'method': 'put', |
|
47 |
'result': data['result'], 'test': data['test']} |
|
48 |
||
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
49 |
class TestJSONRESTView: |
50 |
def testGET(self): |
|
51 |
req = FakeRequest() |
|
1500
by William Grant
Unbreak existing tests. |
52 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
53 |
view.render(req) |
54 |
assert req.content_type == 'application/json' |
|
55 |
assert req.response_body == '{"method": "get"}\n' |
|
56 |
||
57 |
def testPUT(self): |
|
58 |
req = FakeRequest() |
|
59 |
req.method = 'PUT' |
|
60 |
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}' |
|
1500
by William Grant
Unbreak existing tests. |
61 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
62 |
view.render(req) |
63 |
assert req.content_type == 'application/json' |
|
64 |
assert req.response_body == \ |
|
65 |
'{"test": "FAI\\ua746ED", "method": "put", "result": 1}\n' |
|
66 |
||
67 |
def testPATCH(self): |
|
68 |
req = FakeRequest() |
|
69 |
req.method = 'PATCH' |
|
70 |
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}' |
|
1500
by William Grant
Unbreak existing tests. |
71 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
72 |
view.render(req) |
73 |
assert req.content_type == 'application/json' |
|
74 |
assert req.response_body == \ |
|
75 |
'{"test": "FAI\\ua746ED", "method": "patch", "result": 1}\n' |
|
76 |
||
77 |
def testEmulatedPATCH(self): |
|
78 |
req = FakeRequest() |
|
79 |
req.method = 'PUT' |
|
80 |
req.headers_in['X-IVLE-Patch-Semantics'] = 'yes' |
|
81 |
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}' |
|
1500
by William Grant
Unbreak existing tests. |
82 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
83 |
view.render(req) |
84 |
assert req.content_type == 'application/json' |
|
85 |
assert req.response_body == \ |
|
86 |
'{"test": "FAI\\ua746ED", "method": "patch", "result": 1}\n' |
|
87 |
||
88 |
def testInvalidMethod(self): |
|
89 |
req = FakeRequest() |
|
90 |
req.method = 'FAKEANDBOGUS' |
|
1500
by William Grant
Unbreak existing tests. |
91 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
92 |
try: |
93 |
view.render(req) |
|
1099.1.26
by William Grant
ivle.webapp.base.views#JSONRESTView: Check that methods are available before |
94 |
except MethodNotAllowed, e: |
95 |
assert e.allowed == ['GET', 'PUT', 'PATCH', 'POST'] |
|
96 |
else: |
|
97 |
raise AssertionError("did not raise MethodNotAllowed") |
|
98 |
||
99 |
def testNoPUTMethod(self): |
|
100 |
req = FakeRequest() |
|
101 |
req.method = 'PUT' |
|
1500
by William Grant
Unbreak existing tests. |
102 |
view = JSONRESTViewTestWithoutPUT(req, None) |
1099.1.26
by William Grant
ivle.webapp.base.views#JSONRESTView: Check that methods are available before |
103 |
try: |
104 |
view.render(req) |
|
105 |
except MethodNotAllowed, e: |
|
106 |
assert e.allowed == ['GET', 'PATCH', 'POST'] |
|
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
107 |
else: |
1099.1.16
by William Grant
ivle.webapp.base.test: |
108 |
raise AssertionError("did not raise MethodNotAllowed") |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
109 |
|
110 |
def testInvalidMethodWithPATCHEmulation(self): |
|
111 |
req = FakeRequest() |
|
112 |
req.method = 'FAKEANDBOGUS' |
|
113 |
req.headers_in['X-IVLE-Patch-Semantics'] = 'yes' |
|
1500
by William Grant
Unbreak existing tests. |
114 |
view = JSONRESTViewTest(req, None) |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
115 |
try: |
116 |
view.render(req) |
|
1099.1.16
by William Grant
ivle.webapp.base.test: |
117 |
except MethodNotAllowed: |
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
118 |
pass
|
119 |
else: |
|
1099.1.16
by William Grant
ivle.webapp.base.test: |
120 |
raise AssertionError("did not raise MethodNotAllowed") |
121 |
||
122 |
def testNamedOperation(self): |
|
123 |
req = FakeRequest() |
|
124 |
req.method = 'POST' |
|
125 |
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff', |
|
126 |
'what': 'blah'}) |
|
1500
by William Grant
Unbreak existing tests. |
127 |
view = JSONRESTViewTest(req, None) |
1099.1.16
by William Grant
ivle.webapp.base.test: |
128 |
view.render(req) |
129 |
assert req.content_type == 'application/json' |
|
130 |
assert req.response_body == '{"result": "Did blah!"}\n' |
|
131 |
||
132 |
def testPOSTWithoutName(self): |
|
133 |
req = FakeRequest() |
|
134 |
req.method = 'POST' |
|
135 |
req.request_body = urllib.urlencode({'what': 'blah'}) |
|
1500
by William Grant
Unbreak existing tests. |
136 |
view = JSONRESTViewTest(req, None) |
1099.1.16
by William Grant
ivle.webapp.base.test: |
137 |
try: |
138 |
view.render(req) |
|
139 |
except BadRequest, e: |
|
140 |
assert e.message == 'No named operation specified.' |
|
141 |
else: |
|
142 |
raise AssertionError("did not raise BadRequest") |
|
143 |
||
144 |
def testNonexistentNamedOperation(self): |
|
145 |
req = FakeRequest() |
|
146 |
req.method = 'POST' |
|
147 |
req.request_body = urllib.urlencode({'ivle.op': 'enoent'}) |
|
1500
by William Grant
Unbreak existing tests. |
148 |
view = JSONRESTViewTest(req, None) |
1099.1.16
by William Grant
ivle.webapp.base.test: |
149 |
try: |
150 |
view.render(req) |
|
151 |
except BadRequest, e: |
|
152 |
assert e.message == 'Invalid named operation.' |
|
153 |
else: |
|
154 |
raise AssertionError("did not raise BadRequest") |
|
155 |
||
156 |
def testDisallowedNamedOperation(self): |
|
157 |
req = FakeRequest() |
|
158 |
req.method = 'POST' |
|
159 |
req.request_body = urllib.urlencode({'ivle.op': 'GET'}) |
|
1500
by William Grant
Unbreak existing tests. |
160 |
view = JSONRESTViewTest(req, None) |
1099.1.16
by William Grant
ivle.webapp.base.test: |
161 |
try: |
162 |
view.render(req) |
|
163 |
except BadRequest, e: |
|
164 |
assert e.message == 'Invalid named operation.' |
|
165 |
else: |
|
166 |
raise AssertionError("did not raise BadRequest") |
|
167 |
||
168 |
def testNamedOperationWithMissingArgs(self): |
|
169 |
req = FakeRequest() |
|
170 |
req.method = 'POST' |
|
171 |
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff', |
|
172 |
'nothing': 'wrong'}) |
|
1500
by William Grant
Unbreak existing tests. |
173 |
view = JSONRESTViewTest(req, None) |
1099.1.16
by William Grant
ivle.webapp.base.test: |
174 |
try: |
175 |
view.render(req) |
|
176 |
except BadRequest, e: |
|
177 |
assert e.message == 'Missing arguments: what' |
|
178 |
else: |
|
1099.1.8
by William Grant
ivle.webapp.testing: Add, with fake request and user. |
179 |
raise AssertionError("did not raise BadRequest") |
1099.1.27
by William Grant
ivle.webapp.base.views#JSONRESTView: Add support for argument defaults in |
180 |
|
181 |
def testNamedOperationWithExtraArgs(self): |
|
182 |
req = FakeRequest() |
|
183 |
req.method = 'POST' |
|
184 |
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff', |
|
185 |
'what': 'blah', |
|
186 |
'toomany': 'args'}) |
|
1500
by William Grant
Unbreak existing tests. |
187 |
view = JSONRESTViewTest(req, None) |
1099.1.27
by William Grant
ivle.webapp.base.views#JSONRESTView: Add support for argument defaults in |
188 |
try: |
189 |
view.render(req) |
|
190 |
except BadRequest, e: |
|
191 |
assert e.message == 'Extra arguments: toomany' |
|
192 |
else: |
|
193 |
raise AssertionError("did not raise BadRequest") |
|
194 |
||
195 |
def testNamedOperationWithDefaultArgs(self): |
|
196 |
req = FakeRequest() |
|
197 |
req.method = 'POST' |
|
198 |
req.request_body = urllib.urlencode({'ivle.op': 'say_something'}) |
|
1500
by William Grant
Unbreak existing tests. |
199 |
view = JSONRESTViewTest(req, None) |
1099.1.27
by William Grant
ivle.webapp.base.views#JSONRESTView: Add support for argument defaults in |
200 |
view.render(req) |
201 |
assert req.content_type == 'application/json' |
|
202 |
assert req.response_body == '{"result": "Said nothing!"}\n' |
|
203 |
||
204 |
def testNamedOperationWithOverriddenDefaultArgs(self): |
|
205 |
req = FakeRequest() |
|
206 |
req.method = 'POST' |
|
207 |
req.request_body = urllib.urlencode({'ivle.op': 'say_something', |
|
208 |
'thing': 'something'}) |
|
1500
by William Grant
Unbreak existing tests. |
209 |
view = JSONRESTViewTest(req, None) |
1099.1.27
by William Grant
ivle.webapp.base.views#JSONRESTView: Add support for argument defaults in |
210 |
view.render(req) |
211 |
assert req.content_type == 'application/json' |
|
212 |
assert req.response_body == '{"result": "Said something!"}\n' |
|
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
213 |
|
1099.1.52
by William Grant
ivle.webapp.base.rest#RESTView: Remove broken old render() - it should be |
214 |
def testNamedOperationWithDefaultAndMissingArgs(self): |
215 |
req = FakeRequest() |
|
216 |
req.method = 'POST' |
|
217 |
req.request_body = urllib.urlencode({'ivle.op': 'do_say_something', |
|
218 |
'thing': 'something'}) |
|
1500
by William Grant
Unbreak existing tests. |
219 |
view = JSONRESTViewTest(req, None) |
1099.1.52
by William Grant
ivle.webapp.base.rest#RESTView: Remove broken old render() - it should be |
220 |
try: |
221 |
view.render(req) |
|
222 |
except BadRequest, e: |
|
223 |
assert e.message == 'Missing arguments: what' |
|
224 |
else: |
|
225 |
raise AssertionError("did not raise BadRequest") |
|
226 |
||
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
227 |
def testNamedOperationUsingRequest(self): |
228 |
req = FakeRequest() |
|
229 |
req.method = 'POST' |
|
230 |
req.request_body = urllib.urlencode({'ivle.op': 'get_req_method'}) |
|
1500
by William Grant
Unbreak existing tests. |
231 |
view = JSONRESTViewTest(req, None) |
1099.1.28
by William Grant
ivle.webapp.base.views#JSONRESTView: Named operations now take the request. |
232 |
view.render(req) |
233 |
assert req.content_type == 'application/json' |
|
234 |
assert req.response_body == '{"method": "POST"}\n' |
|
1099.1.53
by William Grant
ivle.webapp.base.rest#JSONRESTView: Check for bad JSON input, rather than |
235 |
|
236 |
def testInvalidPOSTData(self): |
|
237 |
req = FakeRequest() |
|
238 |
req.method = 'POST' |
|
239 |
req.request_body = 'I am invalid&&&&' |
|
1500
by William Grant
Unbreak existing tests. |
240 |
view = JSONRESTViewTest(req, None) |
1099.1.53
by William Grant
ivle.webapp.base.rest#JSONRESTView: Check for bad JSON input, rather than |
241 |
try: |
242 |
view.render(req) |
|
243 |
except BadRequest, e: |
|
244 |
print e.message |
|
245 |
assert e.message == 'No named operation specified.' |
|
246 |
else: |
|
247 |
raise AssertionError("did not raise BadRequest") |
|
248 |
||
249 |
def testInvalidPATCHData(self): |
|
250 |
req = FakeRequest() |
|
251 |
req.method = 'PATCH' |
|
252 |
req.request_body = 'I am invalid' |
|
1500
by William Grant
Unbreak existing tests. |
253 |
view = JSONRESTViewTest(req, None) |
1099.1.53
by William Grant
ivle.webapp.base.rest#JSONRESTView: Check for bad JSON input, rather than |
254 |
try: |
255 |
view.render(req) |
|
256 |
except BadRequest, e: |
|
257 |
assert e.message == 'Invalid JSON data' |
|
258 |
else: |
|
259 |
raise AssertionError("did not raise BadRequest") |
|
260 |
||
261 |
def testInvalidPUTData(self): |
|
262 |
req = FakeRequest() |
|
263 |
req.method = 'PUT' |
|
264 |
req.request_body = 'I am invalid' |
|
1500
by William Grant
Unbreak existing tests. |
265 |
view = JSONRESTViewTest(req, None) |
1099.1.53
by William Grant
ivle.webapp.base.rest#JSONRESTView: Check for bad JSON input, rather than |
266 |
try: |
267 |
view.render(req) |
|
268 |
except BadRequest, e: |
|
269 |
assert e.message == 'Invalid JSON data' |
|
270 |
else: |
|
271 |
raise AssertionError("did not raise BadRequest") |
|
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
272 |
|
273 |
class TestJSONRESTSecurity: |
|
274 |
def testGoodMethod(self): |
|
275 |
req = FakeRequest() |
|
276 |
req.user.login = u'otheruser' |
|
277 |
req.method = 'GET' |
|
1500
by William Grant
Unbreak existing tests. |
278 |
view = JSONRESTViewTest(req, None) |
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
279 |
view.render(req) |
280 |
assert req.content_type == 'application/json' |
|
281 |
assert req.response_body == '{"method": "get"}\n' |
|
282 |
||
283 |
def testBadMethod(self): |
|
284 |
req = FakeRequest() |
|
285 |
req.user.login = u'otheruser' |
|
286 |
req.method = 'PUT' |
|
1500
by William Grant
Unbreak existing tests. |
287 |
view = JSONRESTViewTest(req, None) |
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
288 |
try: |
289 |
view.render(req) |
|
290 |
except Unauthorized, e: |
|
291 |
pass
|
|
292 |
else: |
|
293 |
raise AssertionError("did not raise Unauthorized") |
|
294 |
||
295 |
def testGoodNamedOperation(self): |
|
296 |
req = FakeRequest() |
|
297 |
req.user.login = u'otheruser' |
|
298 |
req.method = 'POST' |
|
299 |
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff', |
|
300 |
'what': 'blah'}) |
|
1500
by William Grant
Unbreak existing tests. |
301 |
view = JSONRESTViewTest(req, None) |
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
302 |
view.render(req) |
303 |
assert req.content_type == 'application/json' |
|
304 |
assert req.response_body == '{"result": "Did blah!"}\n' |
|
305 |
||
306 |
def testBadNamedOperation(self): |
|
307 |
req = FakeRequest() |
|
308 |
req.user.login = u'otheruser' |
|
309 |
req.method = 'POST' |
|
310 |
req.request_body = urllib.urlencode({'ivle.op': 'say_something'}) |
|
1500
by William Grant
Unbreak existing tests. |
311 |
view = JSONRESTViewTest(req, None) |
1099.1.112
by William Grant
Implement authorization in JSON REST views. Add security declarations to |
312 |
try: |
313 |
view.render(req) |
|
314 |
except Unauthorized, e: |
|
315 |
pass
|
|
316 |
else: |
|
317 |
raise AssertionError("did not raise Unauthorized") |
|
318 |