3
from ivle.webapp.base.rest import (JSONRESTView, named_operation,
5
from ivle.webapp.errors import BadRequest, MethodNotAllowed, Unauthorized
6
from ivle.webapp.testing import FakeUser, FakeRequest
8
class JSONRESTViewTestWithoutPUT(JSONRESTView):
9
'''A small JSON REST view for testing purposes, without a PUT method.'''
10
def get_permissions(self, user):
11
if user.login == u'fakeuser':
12
return set(['view', 'edit'])
13
if user.login == u'otheruser':
17
@require_permission('view')
19
return {'method': 'get'}
21
@require_permission('edit')
22
def PATCH(self, req, data):
23
return {'method': 'patch',
24
'result': data['result'], 'test': data['test']}
26
@named_operation('view')
27
def do_stuff(self, req, what):
28
return {'result': 'Did %s!' % what}
30
@named_operation('edit')
31
def say_something(self, req, thing='nothing'):
32
return {'result': 'Said %s!' % thing}
34
@named_operation('edit')
35
def do_say_something(self, req, what, thing='nothing'):
36
return {'result': 'Said %s and %s!' % (what, thing)}
38
@named_operation('view')
39
def get_req_method(self, req):
40
return {'method': req.method}
42
class JSONRESTViewTest(JSONRESTViewTestWithoutPUT):
43
'''A small JSON REST view for testing purposes.'''
44
@require_permission('edit')
45
def PUT(self, req, data):
46
return {'method': 'put',
47
'result': data['result'], 'test': data['test']}
49
class TestJSONRESTView:
52
view = JSONRESTViewTest(req)
54
assert req.content_type == 'application/json'
55
assert req.response_body == '{"method": "get"}\n'
60
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}'
61
view = JSONRESTViewTest(req)
63
assert req.content_type == 'application/json'
64
assert req.response_body == \
65
'{"test": "FAI\\ua746ED", "method": "put", "result": 1}\n'
70
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}'
71
view = JSONRESTViewTest(req)
73
assert req.content_type == 'application/json'
74
assert req.response_body == \
75
'{"test": "FAI\\ua746ED", "method": "patch", "result": 1}\n'
77
def testEmulatedPATCH(self):
80
req.headers_in['X-IVLE-Patch-Semantics'] = 'yes'
81
req.request_body = '{"test": "FAI\\uA746ED", "result": 1}'
82
view = JSONRESTViewTest(req)
84
assert req.content_type == 'application/json'
85
assert req.response_body == \
86
'{"test": "FAI\\ua746ED", "method": "patch", "result": 1}\n'
88
def testInvalidMethod(self):
90
req.method = 'FAKEANDBOGUS'
91
view = JSONRESTViewTest(req)
94
except MethodNotAllowed, e:
95
assert e.allowed == ['GET', 'PUT', 'PATCH', 'POST']
97
raise AssertionError("did not raise MethodNotAllowed")
99
def testNoPUTMethod(self):
102
view = JSONRESTViewTestWithoutPUT(req)
105
except MethodNotAllowed, e:
106
assert e.allowed == ['GET', 'PATCH', 'POST']
108
raise AssertionError("did not raise MethodNotAllowed")
110
def testInvalidMethodWithPATCHEmulation(self):
112
req.method = 'FAKEANDBOGUS'
113
req.headers_in['X-IVLE-Patch-Semantics'] = 'yes'
114
view = JSONRESTViewTest(req)
117
except MethodNotAllowed:
120
raise AssertionError("did not raise MethodNotAllowed")
122
def testNamedOperation(self):
125
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
127
view = JSONRESTViewTest(req)
129
assert req.content_type == 'application/json'
130
assert req.response_body == '{"result": "Did blah!"}\n'
132
def testPOSTWithoutName(self):
135
req.request_body = urllib.urlencode({'what': 'blah'})
136
view = JSONRESTViewTest(req)
139
except BadRequest, e:
140
assert e.message == 'No named operation specified.'
142
raise AssertionError("did not raise BadRequest")
144
def testNonexistentNamedOperation(self):
147
req.request_body = urllib.urlencode({'ivle.op': 'enoent'})
148
view = JSONRESTViewTest(req)
151
except BadRequest, e:
152
assert e.message == 'Invalid named operation.'
154
raise AssertionError("did not raise BadRequest")
156
def testDisallowedNamedOperation(self):
159
req.request_body = urllib.urlencode({'ivle.op': 'GET'})
160
view = JSONRESTViewTest(req)
163
except BadRequest, e:
164
assert e.message == 'Invalid named operation.'
166
raise AssertionError("did not raise BadRequest")
168
def testNamedOperationWithMissingArgs(self):
171
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
173
view = JSONRESTViewTest(req)
176
except BadRequest, e:
177
assert e.message == 'Missing arguments: what'
179
raise AssertionError("did not raise BadRequest")
181
def testNamedOperationWithExtraArgs(self):
184
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
187
view = JSONRESTViewTest(req)
190
except BadRequest, e:
191
assert e.message == 'Extra arguments: toomany'
193
raise AssertionError("did not raise BadRequest")
195
def testNamedOperationWithDefaultArgs(self):
198
req.request_body = urllib.urlencode({'ivle.op': 'say_something'})
199
view = JSONRESTViewTest(req)
201
assert req.content_type == 'application/json'
202
assert req.response_body == '{"result": "Said nothing!"}\n'
204
def testNamedOperationWithOverriddenDefaultArgs(self):
207
req.request_body = urllib.urlencode({'ivle.op': 'say_something',
208
'thing': 'something'})
209
view = JSONRESTViewTest(req)
211
assert req.content_type == 'application/json'
212
assert req.response_body == '{"result": "Said something!"}\n'
214
def testNamedOperationWithDefaultAndMissingArgs(self):
217
req.request_body = urllib.urlencode({'ivle.op': 'do_say_something',
218
'thing': 'something'})
219
view = JSONRESTViewTest(req)
222
except BadRequest, e:
223
assert e.message == 'Missing arguments: what'
225
raise AssertionError("did not raise BadRequest")
227
def testNamedOperationUsingRequest(self):
230
req.request_body = urllib.urlencode({'ivle.op': 'get_req_method'})
231
view = JSONRESTViewTest(req)
233
assert req.content_type == 'application/json'
234
assert req.response_body == '{"method": "POST"}\n'
236
def testInvalidPOSTData(self):
239
req.request_body = 'I am invalid&&&&'
240
view = JSONRESTViewTest(req)
243
except BadRequest, e:
245
assert e.message == 'No named operation specified.'
247
raise AssertionError("did not raise BadRequest")
249
def testInvalidPATCHData(self):
252
req.request_body = 'I am invalid'
253
view = JSONRESTViewTest(req)
256
except BadRequest, e:
257
assert e.message == 'Invalid JSON data'
259
raise AssertionError("did not raise BadRequest")
261
def testInvalidPUTData(self):
264
req.request_body = 'I am invalid'
265
view = JSONRESTViewTest(req)
268
except BadRequest, e:
269
assert e.message == 'Invalid JSON data'
271
raise AssertionError("did not raise BadRequest")
273
class TestJSONRESTSecurity:
274
def testGoodMethod(self):
276
req.user.login = u'otheruser'
278
view = JSONRESTViewTest(req)
280
assert req.content_type == 'application/json'
281
assert req.response_body == '{"method": "get"}\n'
283
def testBadMethod(self):
285
req.user.login = u'otheruser'
287
view = JSONRESTViewTest(req)
290
except Unauthorized, e:
293
raise AssertionError("did not raise Unauthorized")
295
def testGoodNamedOperation(self):
297
req.user.login = u'otheruser'
299
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
301
view = JSONRESTViewTest(req)
303
assert req.content_type == 'application/json'
304
assert req.response_body == '{"result": "Did blah!"}\n'
306
def testBadNamedOperation(self):
308
req.user.login = u'otheruser'
310
req.request_body = urllib.urlencode({'ivle.op': 'say_something'})
311
view = JSONRESTViewTest(req)
314
except Unauthorized, e:
317
raise AssertionError("did not raise Unauthorized")