comparison test/rest_common.py @ 5744:d4de45cde106

Accept header parsing fixes. Now return first acceptable match rather than last. If not acceptable match in accept, 406 error returns list of acceptable types as text string. application/xml is listed in acceptable types only if dicttoxml is installed. Handle q > 1.0 by demoting q factor to 0.0001 making it unusable. Test cases for all this code. XML is commented out as we don't install dicttoxml.py.
author John Rouillard <rouilj@ieee.org>
date Wed, 29 May 2019 22:18:46 -0400
parents 60299cd36670
children fea2b6e54492
comparison
equal deleted inserted replaced
5743:60299cd36670 5744:d4de45cde106
1366 "/rest/notthere/", self.empty_form) 1366 "/rest/notthere/", self.empty_form)
1367 self.assertEqual(self.server.client.response_code, 404) 1367 self.assertEqual(self.server.client.response_code, 404)
1368 1368
1369 del(self.headers) 1369 del(self.headers)
1370 1370
1371 def testAcceptHeaderParsing(self):
1372 # TEST #1
1373 # json highest priority
1374 self.server.client.request.headers.get=self.get_header
1375 headers={"accept": "application/json; version=1,"
1376 "application/xml; q=0.5; version=2,"
1377 "text/plain; q=0.75; version=2"
1378 }
1379 self.headers=headers
1380 results = self.server.dispatch('GET',
1381 "/rest/data/status/1",
1382 self.empty_form)
1383 print(results)
1384 self.assertEqual(self.server.client.response_code, 200)
1385 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1386 "application/json")
1387
1388 # TEST #2
1389 # text highest priority
1390 headers={"accept": "application/json; q=0.5; version=1,"
1391 "application/xml; q=0.25; version=2,"
1392 "text/plain; q=1.0; version=3"
1393 }
1394 self.headers=headers
1395 results = self.server.dispatch('GET',
1396 "/rest/data/status/1",
1397 self.empty_form)
1398 print(results)
1399 self.assertEqual(self.server.client.response_code, 200)
1400 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1401 "application/json")
1402
1403 # TEST #3
1404 # no acceptable type
1405 headers={"accept": "text/plain; q=1.0; version=2"
1406 }
1407 self.headers=headers
1408 results = self.server.dispatch('GET',
1409 "/rest/data/status/1",
1410 self.empty_form)
1411 print(results)
1412 self.assertEqual(self.server.client.response_code, 406)
1413 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1414 "application/json")
1415
1416 # TEST #4
1417 # no accept header, should use default json
1418 headers={}
1419 self.headers=headers
1420 results = self.server.dispatch('GET',
1421 "/rest/data/status/1",
1422 self.empty_form)
1423 print(results)
1424 self.assertEqual(self.server.client.response_code, 200)
1425 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1426 "application/json")
1427
1428 # TEST #5
1429 # wildcard accept header, should use default json
1430 headers={ "accept": "*/*"}
1431 self.headers=headers
1432 results = self.server.dispatch('GET',
1433 "/rest/data/status/1",
1434 self.empty_form)
1435 print(results)
1436 self.assertEqual(self.server.client.response_code, 200)
1437 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1438 "application/json")
1439
1440 # TEST #6
1441 # invalid q factor if not ignored/demoted
1442 # application/json is selected with invalid version
1443 # and errors.
1444 # this ends up choosing */* which triggers json.
1445 self.server.client.request.headers.get=self.get_header
1446 headers={"accept": "application/json; q=1.5; version=99,"
1447 "*/*; q=0.9; version=1,"
1448 "text/plain; q=3.75; version=2"
1449 }
1450 self.headers=headers
1451 results = self.server.dispatch('GET',
1452 "/rest/data/status/1",
1453 self.empty_form)
1454 print(results)
1455 self.assertEqual(self.server.client.response_code, 200)
1456 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1457 "application/json")
1458
1459
1460 '''
1461 # only works if dicttoxml.py is installed.
1462 # not installed for testing
1463 # TEST #7
1464 # xml wins
1465 headers={"accept": "application/json; q=0.5; version=2,"
1466 "application/xml; q=0.75; version=1,"
1467 "text/plain; q=1.0; version=2"
1468 }
1469 self.headers=headers
1470 results = self.server.dispatch('GET',
1471 "/rest/data/status/1",
1472 self.empty_form)
1473 print(results)
1474 self.assertEqual(self.server.client.response_code, 200)
1475 self.assertEqual(self.server.client.additional_headers['Content-Type'],
1476 "application/xml")
1477 '''
1478
1371 def testMethodOverride(self): 1479 def testMethodOverride(self):
1372 # TEST #1 1480 # TEST #1
1373 # Use GET, PUT, PATCH to tunnel DELETE expect error 1481 # Use GET, PUT, PATCH to tunnel DELETE expect error
1374 1482
1375 body=b'{ "order": 5 }' 1483 body=b'{ "order": 5 }'
1406 # DELETE: delete issue 1 via post tunnel 1514 # DELETE: delete issue 1 via post tunnel
1407 self.assertFalse(self.db.status.is_retired("1")) 1515 self.assertFalse(self.db.status.is_retired("1"))
1408 etag = calculate_etag(self.db.status.getnode("1"), 1516 etag = calculate_etag(self.db.status.getnode("1"),
1409 self.db.config['WEB_SECRET_KEY']) 1517 self.db.config['WEB_SECRET_KEY'])
1410 etagb = etag.strip ('"') 1518 etagb = etag.strip ('"')
1411 headers={"accept": "application/json; q=0.75, application/xml; q=1", 1519 headers={"accept": "application/json; q=1.0, application/xml; q=0.75",
1412 "if-match": '"%s"'%etagb, 1520 "if-match": '"%s"'%etagb,
1413 "content-length": 0, 1521 "content-length": 0,
1414 "x-http-method-override": "DElETE" 1522 "x-http-method-override": "DElETE"
1415 } 1523 }
1416 self.headers=headers 1524 self.headers=headers

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