changeset 5583:c65d98a16780 REST-rebased

Added rest unit test Fixed a bug with printing error message Patch operation remove now replace empty list instead of None committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:35 +0100
parents 519b7fd8c8c3
children 53098db851f2
files roundup/rest.py test/test_rest.py
diffstat 2 files changed, 286 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/roundup/rest.py	Wed Jan 30 10:26:35 2019 +0100
+++ b/roundup/rest.py	Wed Jan 30 10:26:35 2019 +0100
@@ -152,7 +152,7 @@
             'View', self.db.getuid(), class_name, itemid=item_id
         ):
             raise Unauthorised(
-                'Permission to view %s item %d denied' % (class_name, item_id)
+                'Permission to view %s item %s denied' % (class_name, item_id)
             )
 
         class_obj = self.db.getclass(class_name)
@@ -379,7 +379,11 @@
             elif op == 'replace':
                 pass
             elif op == 'remove':
-                props[prop] = None
+                current_prop = class_obj.get(item_id, prop)
+                if isinstance(current_prop, list):
+                    props[prop] = []
+                else:
+                    props[prop] = None
             else:
                 raise UsageError('PATCH Operation %s is not allowed' % op)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test_rest.py	Wed Jan 30 10:26:35 2019 +0100
@@ -0,0 +1,280 @@
+import unittest, os, shutil, errno, sys, difflib, cgi, re
+
+from xmlrpclib import MultiCall
+from roundup.cgi.exceptions import *
+from roundup import init, instance, password, hyperdb, date
+from roundup.rest import RestfulInstance
+from roundup.backends import list_backends
+from roundup.hyperdb import String
+from roundup.cgi import TranslationService, client
+
+import db_test_base
+
+NEEDS_INSTANCE = 1
+
+class TestCase(unittest.TestCase):
+
+    backend = None
+
+    def setUp(self):
+        self.dirname = '_test_rest'
+        # set up and open a tracker
+        self.instance = db_test_base.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')
+
+        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 = {}
+        execfile(os.path.join(thisdir, "tx_Source_detector.py"), vars)
+        vars['init'](self.db)
+
+        env = {
+            'PATH_INFO': 'http://localhost/rounduptest/rest/',
+            'HTTP_HOST': 'localhost',
+            'TRACKER_NAME': 'rounduptest'
+        }
+        dummy_client = client.Client(self.instance, None, env, [], None)
+
+        self.server = RestfulInstance(dummy_client, self.db)
+
+    def tearDown(self):
+        self.db.close()
+        try:
+            shutil.rmtree(self.dirname)
+        except OSError, 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.
+        code, results = self.server.get_collection('user', {})
+        self.assertEqual(code, 200)
+        self.assertEqual(len(results), 3)
+
+        # Obtain data for 'joe'.
+        code, results = self.server.get_element('user', self.joeid, {})
+        self.assertEqual(code, 200)
+        self.assertEqual(results['attributes']['username'], 'joe')
+        self.assertEqual(results['attributes']['realname'], 'Joe Random')
+
+    def testPut(self):
+        """
+        Change joe's 'realname'
+        Check if we can't change admin's detail
+        """
+        # Reset joe's 'realname'.
+        form = cgi.FieldStorage()
+        form.list = [
+            cgi.MiniFieldStorage('realname', 'Joe Doe')
+        ]
+        code, results = self.server.put_element('user', self.joeid, form)
+        code, results = self.server.get_element('user', self.joeid, {})
+        self.assertEqual(code, 200)
+        self.assertEqual(results['attributes']['realname'], 'Joe Doe')
+
+        # check we can't change admin's details
+        self.assertRaises(
+            Unauthorised,
+            self.server.put_element, 'user', '1', form
+        )
+
+    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')
+        ]
+        code, results = self.server.post_collection('issue', form)
+        self.assertEqual(code, 201)
+        issueid = results['id']
+        code, results = self.server.get_element('issue', issueid, {})
+        self.assertEqual(code, 200)
+        self.assertEqual(results['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')
+        ]
+        code, results = self.server.post_collection('file', form)
+        self.assertEqual(code, 201)
+        fileid = results['id']
+        code, results = self.server.get_element('file', fileid, {})
+        self.assertEqual(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')
+        ]
+        self.assertRaises(
+            Unauthorised,
+            self.server.put_element, 'user', '1', form
+        )
+
+    def testAuthDeniedPost(self):
+        """
+        Test unauthorized POST request
+        """
+        form = cgi.FieldStorage()
+        form.list = [
+            cgi.MiniFieldStorage('username', 'blah')
+        ]
+        self.assertRaises(
+            Unauthorised,
+            self.server.post_collection, 'user', form
+        )
+
+    def testAuthAllowedPut(self):
+        """
+        Test authorized PUT request
+        """
+        self.db.setCurrentUser('admin')
+        form = cgi.FieldStorage()
+        form.list = [
+            cgi.MiniFieldStorage('realname', 'someone')
+        ]
+        try:
+            try:
+                self.server.put_element('user', '2', form)
+            except Unauthorised, 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:
+            try:
+                self.server.post_collection('user', form)
+            except Unauthorised, err:
+                self.fail('raised %s' % err)
+        finally:
+            self.db.setCurrentUser('joe')
+
+    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')
+        ]
+        code, results = self.server.patch_element('issue', issue_id, form)
+        self.assertEqual(code, 200)
+
+        # verify the result
+        code, results = self.server.get_element('issue', issue_id, {})
+        self.assertEqual(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')
+        ]
+        code, results = self.server.patch_element('issue', issue_id, form)
+        self.assertEqual(code, 200)
+
+        # verify the result
+        code, results = self.server.get_element('issue', issue_id, {})
+        self.assertEqual(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 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', '')
+        ]
+        code, results = self.server.patch_element('issue', issue_id, form)
+        self.assertEqual(code, 200)
+
+        # verify the result
+        code, results = self.server.get_element('issue', issue_id, {})
+        self.assertEqual(code, 200)
+        self.assertEqual(results['attributes']['title'], None)
+        self.assertEqual(len(results['attributes']['nosy']), 0)
+        self.assertEqual(results['attributes']['nosy'], [])
+
+def test_suite():
+    suite = unittest.TestSuite()
+    for l in list_backends():
+        dct = dict(backend=l)
+        subcls = type(TestCase)('TestCase_%s' % l, (TestCase,), dct)
+        suite.addTest(unittest.makeSuite(subcls))
+    return suite
+
+if __name__ == '__main__':
+    runner = unittest.TextTestRunner()
+    unittest.main(testRunner=runner)

Roundup Issue Tracker: http://roundup-tracker.org/