Mercurial > p > roundup > code
diff test/rest_common.py @ 5606:5fc476d4e34c
Merge REST API changes
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Wed, 30 Jan 2019 18:11:02 +0100 |
| parents | ed02a1e0aa5d |
| children | 1c4adab65faf |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/rest_common.py Wed Jan 30 18:11:02 2019 +0100 @@ -0,0 +1,520 @@ +import unittest +import os +import shutil +import errno + +from roundup.cgi.exceptions import * +from roundup import password, hyperdb +from roundup.rest import RestfulInstance +from roundup.backends import list_backends +from roundup.cgi import client +import random + +from .db_test_base import setupTracker + +NEEDS_INSTANCE = 1 + + +class TestCase(): + + backend = None + + def setUp(self): + self.dirname = '_test_rest' + # set up and open a tracker + self.instance = setupTracker(self.dirname, self.backend) + + # open the database + self.db = self.instance.open('admin') + + # Get user id (user4 maybe). Used later to get data from db. + self.joeid = self.db.user.create( + username='joe', + password=password.Password('random'), + address='random@home.org', + realname='Joe Random', + roles='User' + ) + + self.db.commit() + self.db.close() + self.db = self.instance.open('joe') + # Allow joe to retire + p = self.db.security.addPermission(name='Retire', klass='issue') + self.db.security.addPermissionToRole('User', p) + + self.db.tx_Source = 'web' + + self.db.issue.addprop(tx_Source=hyperdb.String()) + self.db.msg.addprop(tx_Source=hyperdb.String()) + + self.db.post_init() + + thisdir = os.path.dirname(__file__) + vars = {} + with open(os.path.join(thisdir, "tx_Source_detector.py")) as f: + code = compile(f.read(), "tx_Source_detector.py", "exec") + exec(code, vars) + vars['init'](self.db) + + env = { + 'PATH_INFO': 'http://localhost/rounduptest/rest/', + 'HTTP_HOST': 'localhost', + 'TRACKER_NAME': 'rounduptest' + } + self.dummy_client = client.Client(self.instance, None, env, [], None) + self.empty_form = cgi.FieldStorage() + + self.server = RestfulInstance(self.dummy_client, self.db) + + def tearDown(self): + self.db.close() + try: + shutil.rmtree(self.dirname) + except OSError as error: + if error.errno not in (errno.ENOENT, errno.ESRCH): + raise + + def testGet(self): + """ + Retrieve all three users + obtain data for 'joe' + """ + # Retrieve all three users. + results = self.server.get_collection('user', self.empty_form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['data']), 3) + + # Obtain data for 'joe'. + results = self.server.get_element('user', self.joeid, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['attributes']['username'], 'joe') + self.assertEqual(results['attributes']['realname'], 'Joe Random') + + # Obtain data for 'joe'. + results = self.server.get_attribute( + 'user', self.joeid, 'username', self.empty_form + ) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['data']['data'], 'joe') + + def testFilter(self): + """ + Retrieve all three users + obtain data for 'joe' + """ + # create sample data + try: + self.db.status.create(name='open') + except ValueError: + pass + try: + self.db.status.create(name='closed') + except ValueError: + pass + try: + self.db.priority.create(name='normal') + except ValueError: + pass + try: + self.db.priority.create(name='critical') + except ValueError: + pass + self.db.issue.create( + title='foo4', + status=self.db.status.lookup('closed'), + priority=self.db.priority.lookup('critical') + ) + self.db.issue.create( + title='foo1', + status=self.db.status.lookup('open'), + priority=self.db.priority.lookup('normal') + ) + issue_open_norm = self.db.issue.create( + title='foo2', + status=self.db.status.lookup('open'), + priority=self.db.priority.lookup('normal') + ) + issue_closed_norm = self.db.issue.create( + title='foo3', + status=self.db.status.lookup('closed'), + priority=self.db.priority.lookup('normal') + ) + issue_closed_crit = self.db.issue.create( + title='foo4', + status=self.db.status.lookup('closed'), + priority=self.db.priority.lookup('critical') + ) + issue_open_crit = self.db.issue.create( + title='foo5', + status=self.db.status.lookup('open'), + priority=self.db.priority.lookup('critical') + ) + base_path = self.dummy_client.env['PATH_INFO'] + 'data/issue/' + + # Retrieve all issue status=open + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('where_status', 'open') + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertIn(get_obj(base_path, issue_open_norm), results['data']) + self.assertIn(get_obj(base_path, issue_open_crit), results['data']) + self.assertNotIn( + get_obj(base_path, issue_closed_norm), results['data'] + ) + + # Retrieve all issue status=closed and priority=critical + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('where_status', 'closed'), + cgi.MiniFieldStorage('where_priority', 'critical') + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertIn(get_obj(base_path, issue_closed_crit), results['data']) + self.assertNotIn(get_obj(base_path, issue_open_crit), results['data']) + self.assertNotIn( + get_obj(base_path, issue_closed_norm), results['data'] + ) + + # Retrieve all issue status=closed and priority=normal,critical + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('where_status', 'closed'), + cgi.MiniFieldStorage('where_priority', 'normal,critical') + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertIn(get_obj(base_path, issue_closed_crit), results['data']) + self.assertIn(get_obj(base_path, issue_closed_norm), results['data']) + self.assertNotIn(get_obj(base_path, issue_open_crit), results['data']) + self.assertNotIn(get_obj(base_path, issue_open_norm), results['data']) + + def testPagination(self): + """ + Retrieve all three users + obtain data for 'joe' + """ + # create sample data + for i in range(0, random.randint(5, 10)): + self.db.issue.create(title='foo' + str(i)) + + # Retrieving all the issues + results = self.server.get_collection('issue', self.empty_form) + self.assertEqual(self.dummy_client.response_code, 200) + total_length = len(results['data']) + + # Pagination will be 70% of the total result + page_size = total_length * 70 // 100 + page_zero_expected = page_size + page_one_expected = total_length - page_zero_expected + + # Retrieve page 0 + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('page_size', page_size), + cgi.MiniFieldStorage('page_index', 0) + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['data']), page_zero_expected) + + # Retrieve page 1 + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('page_size', page_size), + cgi.MiniFieldStorage('page_index', 1) + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['data']), page_one_expected) + + # Retrieve page 2 + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('page_size', page_size), + cgi.MiniFieldStorage('page_index', 2) + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['data']), 0) + + def testPut(self): + """ + Change joe's 'realname' + Check if we can't change admin's detail + """ + # change Joe's realname via attribute uri + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('data', 'Joe Doe Doe') + ] + results = self.server.put_attribute( + 'user', self.joeid, 'realname', form + ) + results = self.server.get_attribute( + 'user', self.joeid, 'realname', self.empty_form + ) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['data']['data'], 'Joe Doe Doe') + + # Reset joe's 'realname'. + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('realname', 'Joe Doe') + ] + results = self.server.put_element('user', self.joeid, form) + results = self.server.get_element('user', self.joeid, self.empty_form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['data']['attributes']['realname'], 'Joe Doe') + + # check we can't change admin's details + results = self.server.put_element('user', '1', form) + self.assertEqual(self.dummy_client.response_code, 403) + self.assertEqual(results['error']['status'], 403) + + def testPost(self): + """ + Post a new issue with title: foo + Verify the information of the created issue + """ + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('title', 'foo') + ] + results = self.server.post_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 201) + issueid = results['data']['id'] + results = self.server.get_element('issue', issueid, self.empty_form) + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['data']['attributes']['title'], 'foo') + self.assertEqual(self.db.issue.get(issueid, "tx_Source"), 'web') + + def testPostFile(self): + """ + Post a new file with content: hello\r\nthere + Verify the information of the created file + """ + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('content', 'hello\r\nthere') + ] + results = self.server.post_collection('file', form) + self.assertEqual(self.dummy_client.response_code, 201) + fileid = results['data']['id'] + results = self.server.get_element('file', fileid, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['attributes']['content'], 'hello\r\nthere') + + def testAuthDeniedPut(self): + """ + Test unauthorized PUT request + """ + # Wrong permissions (caught by roundup security module). + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('realname', 'someone') + ] + results = self.server.put_element('user', '1', form) + self.assertEqual(self.dummy_client.response_code, 403) + self.assertEqual(results['error']['status'], 403) + + def testAuthDeniedPost(self): + """ + Test unauthorized POST request + """ + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('username', 'blah') + ] + results = self.server.post_collection('user', form) + self.assertEqual(self.dummy_client.response_code, 403) + self.assertEqual(results['error']['status'], 403) + + def testAuthAllowedPut(self): + """ + Test authorized PUT request + """ + self.db.setCurrentUser('admin') + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('realname', 'someone') + ] + try: + self.server.put_element('user', '2', form) + except Unauthorised as err: + self.fail('raised %s' % err) + finally: + self.db.setCurrentUser('joe') + + def testAuthAllowedPost(self): + """ + Test authorized POST request + """ + self.db.setCurrentUser('admin') + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('username', 'blah') + ] + try: + self.server.post_collection('user', form) + except Unauthorised as err: + self.fail('raised %s' % err) + finally: + self.db.setCurrentUser('joe') + + def testDeleteAttributeUri(self): + """ + Test Delete an attribute + """ + # create a new issue with userid 1 in the nosy list + issue_id = self.db.issue.create(title='foo', nosy=['1']) + + # remove the title and nosy + results = self.server.delete_attribute( + 'issue', issue_id, 'title', self.empty_form + ) + self.assertEqual(self.dummy_client.response_code, 200) + + results = self.server.delete_attribute( + 'issue', issue_id, 'nosy', self.empty_form + ) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + results = self.server.get_element('issue', issue_id, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['attributes']['nosy']), 0) + self.assertListEqual(results['attributes']['nosy'], []) + self.assertEqual(results['attributes']['title'], None) + + def testPatchAdd(self): + """ + Test Patch op 'Add' + """ + # create a new issue with userid 1 in the nosy list + issue_id = self.db.issue.create(title='foo', nosy=['1']) + + # add userid 2 to the nosy list + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('op', 'add'), + cgi.MiniFieldStorage('nosy', '2') + ] + results = self.server.patch_element('issue', issue_id, form) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + results = self.server.get_element('issue', issue_id, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['attributes']['nosy']), 2) + self.assertListEqual(results['attributes']['nosy'], ['1', '2']) + + def testPatchReplace(self): + """ + Test Patch op 'Replace' + """ + # create a new issue with userid 1 in the nosy list and status = 1 + issue_id = self.db.issue.create(title='foo', nosy=['1'], status='1') + + # replace userid 2 to the nosy list and status = 3 + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('op', 'replace'), + cgi.MiniFieldStorage('nosy', '2'), + cgi.MiniFieldStorage('status', '3') + ] + results = self.server.patch_element('issue', issue_id, form) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + results = self.server.get_element('issue', issue_id, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['attributes']['status'], '3') + self.assertEqual(len(results['attributes']['nosy']), 1) + self.assertListEqual(results['attributes']['nosy'], ['2']) + + def testPatchRemoveAll(self): + """ + Test Patch Action 'Remove' + """ + # create a new issue with userid 1 and 2 in the nosy list + issue_id = self.db.issue.create(title='foo', nosy=['1', '2']) + + # remove the nosy list and the title + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('op', 'remove'), + cgi.MiniFieldStorage('nosy', ''), + cgi.MiniFieldStorage('title', '') + ] + results = self.server.patch_element('issue', issue_id, form) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + results = self.server.get_element('issue', issue_id, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(results['attributes']['title'], None) + self.assertEqual(len(results['attributes']['nosy']), 0) + self.assertEqual(results['attributes']['nosy'], []) + + def testPatchAction(self): + """ + Test Patch Action 'Action' + """ + # create a new issue with userid 1 and 2 in the nosy list + issue_id = self.db.issue.create(title='foo') + + # execute action retire + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('op', 'action'), + cgi.MiniFieldStorage('action_name', 'retire') + ] + results = self.server.patch_element('issue', issue_id, form) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + self.assertTrue(self.db.issue.is_retired(issue_id)) + + def testPatchRemove(self): + """ + Test Patch Action 'Remove' only some element from a list + """ + # create a new issue with userid 1, 2, 3 in the nosy list + issue_id = self.db.issue.create(title='foo', nosy=['1', '2', '3']) + + # remove the nosy list and the title + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('op', 'remove'), + cgi.MiniFieldStorage('nosy', '1, 2'), + ] + results = self.server.patch_element('issue', issue_id, form) + self.assertEqual(self.dummy_client.response_code, 200) + + # verify the result + results = self.server.get_element('issue', issue_id, self.empty_form) + results = results['data'] + self.assertEqual(self.dummy_client.response_code, 200) + self.assertEqual(len(results['attributes']['nosy']), 1) + self.assertEqual(results['attributes']['nosy'], ['3']) + + +def get_obj(path, id): + return { + 'id': id, + 'link': path + id + } + +if __name__ == '__main__': + runner = unittest.TextTestRunner() + unittest.main(testRunner=runner)
