Skip to content

Commit bbc55b8

Browse files
committed
Added rest unit test
Fixed a bug with printing error message Patch operation remove now replace empty list instead of None committer: Ralf Schlatterbeck <[email protected]>
1 parent 367e78f commit bbc55b8

File tree

2 files changed

+286
-2
lines changed

2 files changed

+286
-2
lines changed

roundup/rest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def get_element(self, class_name, item_id, input):
152152
'View', self.db.getuid(), class_name, itemid=item_id
153153
):
154154
raise Unauthorised(
155-
'Permission to view %s item %d denied' % (class_name, item_id)
155+
'Permission to view %s item %s denied' % (class_name, item_id)
156156
)
157157

158158
class_obj = self.db.getclass(class_name)
@@ -379,7 +379,11 @@ def patch_element(self, class_name, item_id, input):
379379
elif op == 'replace':
380380
pass
381381
elif op == 'remove':
382-
props[prop] = None
382+
current_prop = class_obj.get(item_id, prop)
383+
if isinstance(current_prop, list):
384+
props[prop] = []
385+
else:
386+
props[prop] = None
383387
else:
384388
raise UsageError('PATCH Operation %s is not allowed' % op)
385389

test/test_rest.py

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
import unittest, os, shutil, errno, sys, difflib, cgi, re
2+
3+
from xmlrpclib import MultiCall
4+
from roundup.cgi.exceptions import *
5+
from roundup import init, instance, password, hyperdb, date
6+
from roundup.rest import RestfulInstance
7+
from roundup.backends import list_backends
8+
from roundup.hyperdb import String
9+
from roundup.cgi import TranslationService, client
10+
11+
import db_test_base
12+
13+
NEEDS_INSTANCE = 1
14+
15+
class TestCase(unittest.TestCase):
16+
17+
backend = None
18+
19+
def setUp(self):
20+
self.dirname = '_test_rest'
21+
# set up and open a tracker
22+
self.instance = db_test_base.setupTracker(self.dirname, self.backend)
23+
24+
# open the database
25+
self.db = self.instance.open('admin')
26+
27+
# Get user id (user4 maybe). Used later to get data from db.
28+
self.joeid = self.db.user.create(
29+
username='joe',
30+
password=password.Password('random'),
31+
address='[email protected]',
32+
realname='Joe Random',
33+
roles='User'
34+
)
35+
36+
self.db.commit()
37+
self.db.close()
38+
self.db = self.instance.open('joe')
39+
40+
self.db.tx_Source = 'web'
41+
42+
self.db.issue.addprop(tx_Source=hyperdb.String())
43+
self.db.msg.addprop(tx_Source=hyperdb.String())
44+
45+
self.db.post_init()
46+
47+
thisdir = os.path.dirname(__file__)
48+
vars = {}
49+
execfile(os.path.join(thisdir, "tx_Source_detector.py"), vars)
50+
vars['init'](self.db)
51+
52+
env = {
53+
'PATH_INFO': 'http://localhost/rounduptest/rest/',
54+
'HTTP_HOST': 'localhost',
55+
'TRACKER_NAME': 'rounduptest'
56+
}
57+
dummy_client = client.Client(self.instance, None, env, [], None)
58+
59+
self.server = RestfulInstance(dummy_client, self.db)
60+
61+
def tearDown(self):
62+
self.db.close()
63+
try:
64+
shutil.rmtree(self.dirname)
65+
except OSError, error:
66+
if error.errno not in (errno.ENOENT, errno.ESRCH):
67+
raise
68+
69+
def testGet(self):
70+
"""
71+
Retrieve all three users
72+
obtain data for 'joe'
73+
"""
74+
# Retrieve all three users.
75+
code, results = self.server.get_collection('user', {})
76+
self.assertEqual(code, 200)
77+
self.assertEqual(len(results), 3)
78+
79+
# Obtain data for 'joe'.
80+
code, results = self.server.get_element('user', self.joeid, {})
81+
self.assertEqual(code, 200)
82+
self.assertEqual(results['attributes']['username'], 'joe')
83+
self.assertEqual(results['attributes']['realname'], 'Joe Random')
84+
85+
def testPut(self):
86+
"""
87+
Change joe's 'realname'
88+
Check if we can't change admin's detail
89+
"""
90+
# Reset joe's 'realname'.
91+
form = cgi.FieldStorage()
92+
form.list = [
93+
cgi.MiniFieldStorage('realname', 'Joe Doe')
94+
]
95+
code, results = self.server.put_element('user', self.joeid, form)
96+
code, results = self.server.get_element('user', self.joeid, {})
97+
self.assertEqual(code, 200)
98+
self.assertEqual(results['attributes']['realname'], 'Joe Doe')
99+
100+
# check we can't change admin's details
101+
self.assertRaises(
102+
Unauthorised,
103+
self.server.put_element, 'user', '1', form
104+
)
105+
106+
def testPost(self):
107+
"""
108+
Post a new issue with title: foo
109+
Verify the information of the created issue
110+
"""
111+
form = cgi.FieldStorage()
112+
form.list = [
113+
cgi.MiniFieldStorage('title', 'foo')
114+
]
115+
code, results = self.server.post_collection('issue', form)
116+
self.assertEqual(code, 201)
117+
issueid = results['id']
118+
code, results = self.server.get_element('issue', issueid, {})
119+
self.assertEqual(code, 200)
120+
self.assertEqual(results['attributes']['title'], 'foo')
121+
self.assertEqual(self.db.issue.get(issueid, "tx_Source"), 'web')
122+
123+
def testPostFile(self):
124+
"""
125+
Post a new file with content: hello\r\nthere
126+
Verify the information of the created file
127+
"""
128+
form = cgi.FieldStorage()
129+
form.list = [
130+
cgi.MiniFieldStorage('content', 'hello\r\nthere')
131+
]
132+
code, results = self.server.post_collection('file', form)
133+
self.assertEqual(code, 201)
134+
fileid = results['id']
135+
code, results = self.server.get_element('file', fileid, {})
136+
self.assertEqual(code, 200)
137+
self.assertEqual(results['attributes']['content'], 'hello\r\nthere')
138+
139+
def testAuthDeniedPut(self):
140+
"""
141+
Test unauthorized PUT request
142+
"""
143+
# Wrong permissions (caught by roundup security module).
144+
form = cgi.FieldStorage()
145+
form.list = [
146+
cgi.MiniFieldStorage('realname', 'someone')
147+
]
148+
self.assertRaises(
149+
Unauthorised,
150+
self.server.put_element, 'user', '1', form
151+
)
152+
153+
def testAuthDeniedPost(self):
154+
"""
155+
Test unauthorized POST request
156+
"""
157+
form = cgi.FieldStorage()
158+
form.list = [
159+
cgi.MiniFieldStorage('username', 'blah')
160+
]
161+
self.assertRaises(
162+
Unauthorised,
163+
self.server.post_collection, 'user', form
164+
)
165+
166+
def testAuthAllowedPut(self):
167+
"""
168+
Test authorized PUT request
169+
"""
170+
self.db.setCurrentUser('admin')
171+
form = cgi.FieldStorage()
172+
form.list = [
173+
cgi.MiniFieldStorage('realname', 'someone')
174+
]
175+
try:
176+
try:
177+
self.server.put_element('user', '2', form)
178+
except Unauthorised, err:
179+
self.fail('raised %s' % err)
180+
finally:
181+
self.db.setCurrentUser('joe')
182+
183+
def testAuthAllowedPost(self):
184+
"""
185+
Test authorized POST request
186+
"""
187+
self.db.setCurrentUser('admin')
188+
form = cgi.FieldStorage()
189+
form.list = [
190+
cgi.MiniFieldStorage('username', 'blah')
191+
]
192+
try:
193+
try:
194+
self.server.post_collection('user', form)
195+
except Unauthorised, err:
196+
self.fail('raised %s' % err)
197+
finally:
198+
self.db.setCurrentUser('joe')
199+
200+
def testPatchAdd(self):
201+
"""
202+
Test Patch op 'Add'
203+
"""
204+
# create a new issue with userid 1 in the nosy list
205+
issue_id = self.db.issue.create(title='foo', nosy=['1'])
206+
207+
# add userid 2 to the nosy list
208+
form = cgi.FieldStorage()
209+
form.list = [
210+
cgi.MiniFieldStorage('op', 'add'),
211+
cgi.MiniFieldStorage('nosy', '2')
212+
]
213+
code, results = self.server.patch_element('issue', issue_id, form)
214+
self.assertEqual(code, 200)
215+
216+
# verify the result
217+
code, results = self.server.get_element('issue', issue_id, {})
218+
self.assertEqual(code, 200)
219+
self.assertEqual(len(results['attributes']['nosy']), 2)
220+
self.assertListEqual(results['attributes']['nosy'], ['1', '2'])
221+
222+
def testPatchReplace(self):
223+
"""
224+
Test Patch op 'Replace'
225+
"""
226+
# create a new issue with userid 1 in the nosy list and status = 1
227+
issue_id = self.db.issue.create(title='foo', nosy=['1'], status='1')
228+
229+
# replace userid 2 to the nosy list and status = 3
230+
form = cgi.FieldStorage()
231+
form.list = [
232+
cgi.MiniFieldStorage('op', 'replace'),
233+
cgi.MiniFieldStorage('nosy', '2'),
234+
cgi.MiniFieldStorage('status', '3')
235+
]
236+
code, results = self.server.patch_element('issue', issue_id, form)
237+
self.assertEqual(code, 200)
238+
239+
# verify the result
240+
code, results = self.server.get_element('issue', issue_id, {})
241+
self.assertEqual(code, 200)
242+
self.assertEqual(results['attributes']['status'], '3')
243+
self.assertEqual(len(results['attributes']['nosy']), 1)
244+
self.assertListEqual(results['attributes']['nosy'], ['2'])
245+
246+
def testPatchRemoveAll(self):
247+
"""
248+
Test Patch Action 'Remove'
249+
"""
250+
# create a new issue with userid 1 in the nosy list
251+
issue_id = self.db.issue.create(title='foo', nosy=['1', '2'])
252+
253+
# remove the nosy list and the title
254+
form = cgi.FieldStorage()
255+
form.list = [
256+
cgi.MiniFieldStorage('op', 'remove'),
257+
cgi.MiniFieldStorage('nosy', ''),
258+
cgi.MiniFieldStorage('title', '')
259+
]
260+
code, results = self.server.patch_element('issue', issue_id, form)
261+
self.assertEqual(code, 200)
262+
263+
# verify the result
264+
code, results = self.server.get_element('issue', issue_id, {})
265+
self.assertEqual(code, 200)
266+
self.assertEqual(results['attributes']['title'], None)
267+
self.assertEqual(len(results['attributes']['nosy']), 0)
268+
self.assertEqual(results['attributes']['nosy'], [])
269+
270+
def test_suite():
271+
suite = unittest.TestSuite()
272+
for l in list_backends():
273+
dct = dict(backend=l)
274+
subcls = type(TestCase)('TestCase_%s' % l, (TestCase,), dct)
275+
suite.addTest(unittest.makeSuite(subcls))
276+
return suite
277+
278+
if __name__ == '__main__':
279+
runner = unittest.TextTestRunner()
280+
unittest.main(testRunner=runner)

0 commit comments

Comments
 (0)