comparison 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
comparison
equal deleted inserted replaced
6383:e9760702bf0c 6384:66a061e52435
9 skip_requests = lambda func, *args, **kwargs: func 9 skip_requests = lambda func, *args, **kwargs: func
10 except ImportError: 10 except ImportError:
11 from .pytest_patcher import mark_class 11 from .pytest_patcher import mark_class
12 skip_requests = mark_class(pytest.mark.skip( 12 skip_requests = mark_class(pytest.mark.skip(
13 reason='Skipping liveserver tests: requests library not available')) 13 reason='Skipping liveserver tests: requests library not available'))
14 14
15
15 @skip_requests 16 @skip_requests
16 class SimpleTest(LiveServerTestCase): 17 class SimpleTest(LiveServerTestCase):
17 port_range = (9001, 9010) # default is (8080, 8090) 18 # have chicken and egg issue here. Need to encode the base_url
19 # in the config file but we don't know it until after
20 # the server is started nd has read the config.ini.
21 # so only allow one port number
22 port_range = (9001, 9001) # default is (8080, 8090)
18 23
19 dirname = '_test_instance' 24 dirname = '_test_instance'
20 backend = 'anydbm' 25 backend = 'anydbm'
21 26
22 @classmethod 27 @classmethod
30 # set up and open a tracker 35 # set up and open a tracker
31 cls.instance = db_test_base.setupTracker(cls.dirname, cls.backend) 36 cls.instance = db_test_base.setupTracker(cls.dirname, cls.backend)
32 37
33 # open the database 38 # open the database
34 cls.db = cls.instance.open('admin') 39 cls.db = cls.instance.open('admin')
40
41 # set the url the test instance will run at.
42 cls.db.config['TRACKER_WEB'] = "http://localhost:9001/"
43 cls.db.config.save()
35 44
36 cls.db.commit() 45 cls.db.commit()
37 cls.db.close() 46 cls.db.close()
38 47
39 @classmethod 48 @classmethod
54 63
55 def test_start_page(self): 64 def test_start_page(self):
56 """ simple test that verifies that the server can serve a start page. 65 """ simple test that verifies that the server can serve a start page.
57 """ 66 """
58 f = requests.get(self.url_base()) 67 f = requests.get(self.url_base())
68 self.assertEqual(f.status_code, 200)
59 self.assertTrue(b'Roundup' in f.content) 69 self.assertTrue(b'Roundup' in f.content)
60 self.assertTrue(b'Creator' in f.content) 70 self.assertTrue(b'Creator' in f.content)
71
72
73 def disable_test_http_options(self):
74 """ options returns an unimplemented error for this case."""
75 '''note this currently triggers an assertion failure in the
76 python wsgi handler, so disable while investigating'''
77
78 # do not send content-type header for options
79 f = requests.options(self.url_base() + '/',
80 headers = {'content-type': ""})
81 # options is not implemented for the non-rest interface.
82 self.assertEqual(f.status_code, 501)
83
84 def test_rest_endpoint_root_options(self):
85 # use basic auth for rest endpoint
86 f = requests.options(self.url_base() + '/rest',
87 auth=('admin', 'sekrit'),
88 headers = {'content-type': ""})
89 print(f.status_code)
90 print(f.headers)
91
92 self.assertEqual(f.status_code, 204)
93 expected = { 'Content-Type': 'application/json',
94 'Access-Control-Allow-Origin': '*',
95 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
96 'Allow': 'OPTIONS, GET',
97 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
98 }
99
100 # use dict comprehension to remove fields like date,
101 # content-length etc. from f.headers.
102 self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
103
104 def test_rest_endpoint_data_options(self):
105 # use basic auth for rest endpoint
106 f = requests.options(self.url_base() + '/rest/data',
107 auth=('admin', 'sekrit'),
108 headers = {'content-type': ""}
109 )
110 print(f.status_code)
111 print(f.headers)
112
113 self.assertEqual(f.status_code, 204)
114 expected = { 'Content-Type': 'application/json',
115 'Access-Control-Allow-Origin': '*',
116 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
117 'Allow': 'OPTIONS, GET',
118 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
119 }
120
121 # use dict comprehension to remove fields like date,
122 # content-length etc. from f.headers.
123 self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
124
125 def test_rest_endpoint_collection_options(self):
126 # use basic auth for rest endpoint
127 f = requests.options(self.url_base() + '/rest/data/user',
128 auth=('admin', 'sekrit'),
129 headers = {'content-type': ""})
130 print(f.status_code)
131 print(f.headers)
132
133 self.assertEqual(f.status_code, 204)
134 expected = { 'Content-Type': 'application/json',
135 'Access-Control-Allow-Origin': '*',
136 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
137 'Allow': 'OPTIONS, GET, POST',
138 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
139 }
140
141 # use dict comprehension to remove fields like date,
142 # content-length etc. from f.headers.
143 self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
144
145
146 def test_rest_endpoint_item_options(self):
147
148 f = requests.options(self.url_base() + '/rest/data/user/1',
149 auth=('admin', 'sekrit'),
150 headers = {'content-type': ""})
151 print(f.status_code)
152 print(f.headers)
153
154 self.assertEqual(f.status_code, 204)
155 expected = { 'Content-Type': 'application/json',
156 'Access-Control-Allow-Origin': '*',
157 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
158 'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH',
159 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
160 }
161
162 # use dict comprehension to remove fields like date,
163 # content-length etc. from f.headers.
164 self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
165
166 def test_rest_endpoint_element_options(self):
167 # use basic auth for rest endpoint
168 f = requests.options(self.url_base() + '/rest/data/user/1/username',
169 auth=('admin', 'sekrit'),
170 headers = {'content-type': ""})
171 print(f.status_code)
172 print(f.headers)
173
174 self.assertEqual(f.status_code, 204)
175 expected = { 'Content-Type': 'application/json',
176 'Access-Control-Allow-Origin': '*',
177 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override',
178 'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH',
179 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH',
180 }
181
182 # use dict comprehension to remove fields like date,
183 # content-length etc. from f.headers.
184 self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected)
185
186
187

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