3
from nose.tools import assert_equal
5
from ivle.webapp.base.rest import (JSONRESTView, read_operation,
6
require_permission, write_operation)
7
from ivle.webapp.errors import BadRequest, MethodNotAllowed, Unauthorized
1
from ivle.webapp.base.views import RESTView, JSONRESTView
2
from ivle.webapp.errors import BadRequest
8
3
from ivle.webapp.testing import FakeUser, FakeRequest
10
class JSONRESTViewTestWithoutPUT(JSONRESTView):
11
'''A small JSON REST view for testing purposes, without a PUT method.'''
12
def get_permissions(self, user, config):
13
if user.login == u'fakeuser':
14
return set(['view', 'edit'])
15
if user.login == u'otheruser':
19
@require_permission('view')
5
class JSONRESTViewTest(JSONRESTView):
6
'''A small JSON REST view for testing purposes.'''
21
8
return {'method': 'get'}
23
@require_permission('edit')
10
def PUT(self, req, data):
11
return {'method': 'put',
12
'result': data['result'], 'test': data['test']}
24
14
def PATCH(self, req, data):
25
15
return {'method': 'patch',
26
16
'result': data['result'], 'test': data['test']}
28
@write_operation('view')
29
def do_stuff(self, req, what):
30
return {'result': 'Did %s!' % what}
32
@read_operation('edit')
33
def say_something(self, req, thing='nothing'):
34
return {'result': 'Said %s!' % thing}
36
@write_operation('edit')
37
def do_say_something(self, req, what, thing='nothing'):
38
return {'result': 'Said %s and %s!' % (what, thing)}
40
@read_operation('view')
41
def get_req_method(self, req):
42
return {'method': req.method}
44
class JSONRESTViewTest(JSONRESTViewTestWithoutPUT):
45
'''A small JSON REST view for testing purposes.'''
46
@require_permission('edit')
47
def PUT(self, req, data):
48
return {'method': 'put',
49
'result': data['result'], 'test': data['test']}
51
18
class TestJSONRESTView:
53
20
req = FakeRequest()
54
view = JSONRESTViewTest(req, None)
21
view = JSONRESTViewTest(req)
56
23
assert req.content_type == 'application/json'
57
24
assert req.response_body == '{"method": "get"}\n'
90
57
def testInvalidMethod(self):
91
58
req = FakeRequest()
92
59
req.method = 'FAKEANDBOGUS'
93
view = JSONRESTViewTest(req, None)
96
except MethodNotAllowed, e:
97
assert e.allowed == ['GET', 'PUT', 'PATCH', 'POST']
99
raise AssertionError("did not raise MethodNotAllowed")
101
def testNoPUTMethod(self):
104
view = JSONRESTViewTestWithoutPUT(req, None)
107
except MethodNotAllowed, e:
108
assert e.allowed == ['GET', 'PATCH', 'POST']
110
raise AssertionError("did not raise MethodNotAllowed")
60
view = JSONRESTViewTest(req)
66
raise AssertionError("did not raise BadRequest")
112
68
def testInvalidMethodWithPATCHEmulation(self):
113
69
req = FakeRequest()
114
70
req.method = 'FAKEANDBOGUS'
115
71
req.headers_in['X-IVLE-Patch-Semantics'] = 'yes'
116
view = JSONRESTViewTest(req, None)
119
except MethodNotAllowed:
122
raise AssertionError("did not raise MethodNotAllowed")
124
def testNamedOperation(self):
127
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
129
view = JSONRESTViewTest(req, None)
131
assert req.content_type == 'application/json'
132
assert req.response_body == '{"result": "Did blah!"}\n'
134
def testPOSTWithoutName(self):
137
req.request_body = urllib.urlencode({'what': 'blah'})
138
view = JSONRESTViewTest(req, None)
141
except BadRequest, e:
142
assert e.message == 'No named operation specified.'
144
raise AssertionError("did not raise BadRequest")
146
def testNonexistentNamedOperation(self):
149
req.request_body = urllib.urlencode({'ivle.op': 'enoent'})
150
view = JSONRESTViewTest(req, None)
153
except BadRequest, e:
154
assert e.message == 'Invalid named operation.'
156
raise AssertionError("did not raise BadRequest")
158
def testDisallowedNamedOperation(self):
161
req.request_body = urllib.urlencode({'ivle.op': 'GET'})
162
view = JSONRESTViewTest(req, None)
165
except BadRequest, e:
166
assert e.message == 'Invalid named operation.'
168
raise AssertionError("did not raise BadRequest")
170
def testNamedOperationWithMissingArgs(self):
173
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
175
view = JSONRESTViewTest(req, None)
178
except BadRequest, e:
179
assert e.message == 'Missing arguments: what'
181
raise AssertionError("did not raise BadRequest")
183
def testNamedOperationWithExtraArgs(self):
186
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
189
view = JSONRESTViewTest(req, None)
192
except BadRequest, e:
193
assert e.message == 'Extra arguments: toomany'
195
raise AssertionError("did not raise BadRequest")
197
def testNamedOperationWithDefaultArgs(self):
200
req.request_body = urllib.urlencode({'ivle.op': 'say_something'})
201
view = JSONRESTViewTest(req, None)
203
assert req.content_type == 'application/json'
204
assert req.response_body == '{"result": "Said nothing!"}\n'
206
def testNamedOperationWithOverriddenDefaultArgs(self):
209
req.request_body = urllib.urlencode({'ivle.op': 'say_something',
210
'thing': 'something'})
211
view = JSONRESTViewTest(req, None)
213
assert req.content_type == 'application/json'
214
assert req.response_body == '{"result": "Said something!"}\n'
216
def testNamedOperationWithDefaultAndMissingArgs(self):
219
req.request_body = urllib.urlencode({'ivle.op': 'do_say_something',
220
'thing': 'something'})
221
view = JSONRESTViewTest(req, None)
224
except BadRequest, e:
225
assert e.message == 'Missing arguments: what'
227
raise AssertionError("did not raise BadRequest")
229
def testNamedOperationUsingRequest(self):
232
req.request_body = urllib.urlencode({'ivle.op': 'get_req_method'})
233
view = JSONRESTViewTest(req, None)
235
assert req.content_type == 'application/json'
236
assert req.response_body == '{"method": "POST"}\n'
238
def testGETNamedOperation(self):
241
req.unparsed_uri = '/?' + urllib.urlencode(
242
{'ivle.op': 'say_something'})
243
view = JSONRESTViewTest(req, None)
245
assert req.content_type == 'application/json'
246
assert req.response_body == '{"result": "Said nothing!"}\n'
248
def testGETNamedOperationDoesNotFindWriteOperation(self):
251
req.unparsed_uri = '/?' + urllib.urlencode(
252
{'ivle.op': 'do_stuff', 'what': 'something'})
253
view = JSONRESTViewTest(req, None)
256
except BadRequest, e:
257
assert e.message == 'POST required for write operation.'
259
raise AssertionError("did not raise BadRequest")
261
def testInvalidPOSTData(self):
264
req.request_body = 'I am invalid&&&&'
265
view = JSONRESTViewTest(req, None)
268
except BadRequest, e:
270
assert e.message == 'No named operation specified.'
272
raise AssertionError("did not raise BadRequest")
274
def testInvalidPATCHData(self):
277
req.request_body = 'I am invalid'
278
view = JSONRESTViewTest(req, None)
281
except BadRequest, e:
282
assert e.message == 'Invalid JSON data'
284
raise AssertionError("did not raise BadRequest")
286
def testInvalidPUTData(self):
289
req.request_body = 'I am invalid'
290
view = JSONRESTViewTest(req, None)
293
except BadRequest, e:
294
assert e.message == 'Invalid JSON data'
296
raise AssertionError("did not raise BadRequest")
298
class TestJSONRESTSecurity:
299
def testGoodMethod(self):
301
req.user.login = u'otheruser'
303
view = JSONRESTViewTest(req, None)
305
assert req.content_type == 'application/json'
306
assert req.response_body == '{"method": "get"}\n'
308
def testBadMethod(self):
310
req.user.login = u'otheruser'
312
view = JSONRESTViewTest(req, None)
315
except Unauthorized, e:
318
raise AssertionError("did not raise Unauthorized")
320
def testGoodNamedOperation(self):
322
req.user.login = u'otheruser'
324
req.request_body = urllib.urlencode({'ivle.op': 'do_stuff',
326
view = JSONRESTViewTest(req, None)
328
assert req.content_type == 'application/json'
329
assert req.response_body == '{"result": "Did blah!"}\n'
331
def testBadNamedOperation(self):
333
req.user.login = u'otheruser'
335
req.request_body = urllib.urlencode({'ivle.op': 'say_something'})
336
view = JSONRESTViewTest(req, None)
339
except Unauthorized, e:
342
raise AssertionError("did not raise Unauthorized")
72
view = JSONRESTViewTest(req)
78
raise AssertionError("did not raise BadRequest")