diff test/test_liveserver.py @ 6384:66a061e52435

Test options in rest interface against live server; rest doc update Add OPTIONS verb routing for /rest and /rest/data Document that there must not be a content-type header for OPTIONS or GET. Set TRACKER_WEB option in config.in to match where the server is running. Add testing for OPTIONS verb against all rest endpoint types.
author John Rouillard <rouilj@ieee.org>
date Wed, 21 Apr 2021 00:48:28 -0400
parents e9760702bf0c
children 8c43129f29ca
line wrap: on
line diff
--- a/test/test_liveserver.py	Tue Apr 20 14:16:58 2021 -0400
+++ b/test/test_liveserver.py	Wed Apr 21 00:48:28 2021 -0400
@@ -11,10 +11,15 @@
     from .pytest_patcher import mark_class
     skip_requests = mark_class(pytest.mark.skip(
         reason='Skipping liveserver tests: requests library not available'))
-    
+
+ 
 @skip_requests
 class SimpleTest(LiveServerTestCase):
-    port_range = (9001, 9010)  # default is (8080, 8090)
+    # have chicken and egg issue here. Need to encode the base_url
+    # in the config file but we don't know it until after
+    # the server is started nd has read the config.ini.
+    # so only allow one port number
+    port_range = (9001, 9001)  # default is (8080, 8090)
 
     dirname = '_test_instance'
     backend = 'anydbm'
@@ -33,6 +38,10 @@
         # open the database
         cls.db = cls.instance.open('admin')
 
+        # set the url the test instance will run at.
+        cls.db.config['TRACKER_WEB'] = "http://localhost:9001/"
+        cls.db.config.save()
+
         cls.db.commit()
         cls.db.close()
 
@@ -56,5 +65,123 @@
         """ simple test that verifies that the server can serve a start page.
         """
         f = requests.get(self.url_base())
+        self.assertEqual(f.status_code, 200)
         self.assertTrue(b'Roundup' in f.content)
         self.assertTrue(b'Creator' in f.content)
+
+
+    def disable_test_http_options(self):
+        """ options returns an unimplemented error for this case."""
+        '''note this currently triggers an assertion failure in the
+           python wsgi handler, so disable while investigating'''
+        
+        # do not send content-type header for options
+        f = requests.options(self.url_base() + '/',
+                             headers = {'content-type': ""})
+        # options is not implemented for the non-rest interface.
+        self.assertEqual(f.status_code, 501)
+
+    def test_rest_endpoint_root_options(self):
+        # use basic auth for rest endpoint
+        f = requests.options(self.url_base() + '/rest',
+                             auth=('admin', 'sekrit'),
+                             headers = {'content-type': ""})
+        print(f.status_code)
+        print(f.headers)
+
+        self.assertEqual(f.status_code, 204)
+        expected = { 'Content-Type': 'application/json',
+                     'Access-Control-Allow-Origin': '*',
+                     'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
+                     'Allow': 'OPTIONS, GET',
+                     'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
+        }
+
+        # use dict comprehension to remove fields like date,
+        # content-length etc. from f.headers.
+        self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
+
+    def test_rest_endpoint_data_options(self):
+        # use basic auth for rest endpoint
+        f = requests.options(self.url_base() + '/rest/data',
+                             auth=('admin', 'sekrit'),
+                             headers = {'content-type': ""}
+        )
+        print(f.status_code)
+        print(f.headers)
+
+        self.assertEqual(f.status_code, 204)
+        expected = { 'Content-Type': 'application/json',
+                     'Access-Control-Allow-Origin': '*',
+                     'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
+                     'Allow': 'OPTIONS, GET',
+                     'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
+        }
+
+        # use dict comprehension to remove fields like date,
+        # content-length etc. from f.headers.
+        self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
+
+    def test_rest_endpoint_collection_options(self):
+        # use basic auth for rest endpoint
+        f = requests.options(self.url_base() + '/rest/data/user',
+                             auth=('admin', 'sekrit'),
+                             headers = {'content-type': ""})
+        print(f.status_code)
+        print(f.headers)
+
+        self.assertEqual(f.status_code, 204)
+        expected = { 'Content-Type': 'application/json',
+                     'Access-Control-Allow-Origin': '*',
+                     'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
+                     'Allow': 'OPTIONS, GET, POST',
+                     'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
+        }
+
+        # use dict comprehension to remove fields like date,
+        # content-length etc. from f.headers.
+        self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
+
+
+    def test_rest_endpoint_item_options(self):
+
+        f = requests.options(self.url_base() + '/rest/data/user/1',
+                             auth=('admin', 'sekrit'),
+                             headers = {'content-type': ""})
+        print(f.status_code)
+        print(f.headers)
+
+        self.assertEqual(f.status_code, 204)
+        expected = { 'Content-Type': 'application/json',
+                     'Access-Control-Allow-Origin': '*',
+                     'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
+                     'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH',
+                     'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
+        }
+
+        # use dict comprehension to remove fields like date,
+        # content-length etc. from f.headers.
+        self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
+
+    def test_rest_endpoint_element_options(self):
+        # use basic auth for rest endpoint
+        f = requests.options(self.url_base() + '/rest/data/user/1/username',
+                             auth=('admin', 'sekrit'),
+                             headers = {'content-type': ""})
+        print(f.status_code)
+        print(f.headers)
+
+        self.assertEqual(f.status_code, 204)
+        expected = { 'Content-Type': 'application/json',
+                     'Access-Control-Allow-Origin': '*',
+                     'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
+                     'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH',
+                     'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
+        }
+
+        # use dict comprehension to remove fields like date,
+        # content-length etc. from f.headers.
+        self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
+
+
+

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