changeset 5591:a25d79e874cb REST-rebased

Added filtering and pagination Adjust unittest to use empty cgi formfield instead of empty dict committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:35 +0100
parents 4d8746c73fdb
children adcb5cbe82bd
files roundup/rest.py test/test_rest.py
diffstat 2 files changed, 56 insertions(+), 15 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
@@ -178,13 +178,47 @@
 
         class_obj = self.db.getclass(class_name)
         class_path = self.base_path + class_name
+
+        # Handle filtering and pagination
+        filter_props = {}
+        page = {
+            'size': None,
+            'index': None
+        }
+        for form_field in input.value:
+            key = form_field.name
+            value = form_field.value
+            if key.startswith("where_"):  # serve the filter purpose
+                key = key[6:]
+                filter_props[key] = [
+                    getattr(self.db, key).lookup(p)
+                    for p in value.split(",")
+                ]
+            elif key.startswith("page_"):  # serve the paging purpose
+                key = key[5:]
+                value = int(value)
+                page[key] = value
+
+        if not filter_props:
+            obj_list = class_obj.list()
+        else:
+            obj_list = class_obj.filter(None, filter_props)
+
+        # extract result from data
         result = [
             {'id': item_id, 'link': class_path + item_id}
-            for item_id in class_obj.list()
+            for item_id in obj_list
             if self.db.security.hasPermission(
                 'View', self.db.getuid(), class_name, itemid=item_id
             )
         ]
+
+        # pagination
+        if page['size'] is not None and page['index'] is not None:
+            page_start = max(page['index'] * page['size'], 0)
+            page_end = min(page_start + page['size'], len(result))
+            result = result[page_start:page_end]
+
         self.client.setHeader("X-Count-Total", str(len(result)))
         return 200, result
 
@@ -807,7 +841,7 @@
                 )(class_name, item_id, uri_split[2], input)
 
         # Format the content type
-        if format_output.lower() == "json":
+        if data_type.lower() == "json":
             self.client.setHeader("Content-Type", "application/json")
             if pretty_output:
                 indent = 4
--- a/test/test_rest.py	Wed Jan 30 10:26:35 2019 +0100
+++ b/test/test_rest.py	Wed Jan 30 10:26:35 2019 +0100
@@ -57,6 +57,7 @@
             '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)
 
@@ -74,19 +75,20 @@
         obtain data for 'joe'
         """
         # Retrieve all three users.
-        results = self.server.get_collection('user', {})
+        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, {})['data']
+        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', {}
+            'user', self.joeid, 'username', self.empty_form
         )
         self.assertEqual(self.dummy_client.response_code, 200)
         self.assertEqual(results['data']['data'], 'joe')
@@ -105,7 +107,7 @@
             'user', self.joeid, 'realname', form
         )
         results = self.server.get_attribute(
-            'user', self.joeid, 'realname', {}
+            'user', self.joeid, 'realname', self.empty_form
         )
         self.assertEqual(self.dummy_client.response_code, 200)
         self.assertEqual(results['data']['data'], 'Joe Doe Doe')
@@ -116,7 +118,7 @@
             cgi.MiniFieldStorage('realname', 'Joe Doe')
         ]
         results = self.server.put_element('user', self.joeid, form)
-        results = self.server.get_element('user', self.joeid, {})
+        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')
 
@@ -137,7 +139,7 @@
         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, {})
+        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')
@@ -154,7 +156,8 @@
         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, {})['data']
+        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')
 
@@ -224,17 +227,18 @@
 
         # remove the title and nosy
         results = self.server.delete_attribute(
-            'issue', issue_id, 'title', {}
+            'issue', issue_id, 'title', self.empty_form
         )
         self.assertEqual(self.dummy_client.response_code, 200)
 
         results = self.server.delete_attribute(
-            'issue', issue_id, 'nosy', {}
+            '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, {})['data']
+        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'], [])
@@ -257,7 +261,8 @@
         self.assertEqual(self.dummy_client.response_code, 200)
 
         # verify the result
-        results = self.server.get_element('issue', issue_id, {})['data']
+        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'])
@@ -280,7 +285,8 @@
         self.assertEqual(self.dummy_client.response_code, 200)
 
         # verify the result
-        results = self.server.get_element('issue', issue_id, {})['data']
+        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)
@@ -304,7 +310,8 @@
         self.assertEqual(self.dummy_client.response_code, 200)
 
         # verify the result
-        results = self.server.get_element('issue', issue_id, {})['data']
+        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)

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