comparison test/rest_common.py @ 5651:a02ef29b4242

Fix REST tests for Python 3. FieldStorage requires a file storing bytes not strings. With dispatch returning bytes (as required to work end-to-end), tests of the dispatch method that use its return value must handle decoding it.
author Joseph Myers <jsm@polyomino.org.uk>
date Sun, 17 Mar 2019 16:41:49 +0000
parents e8ca7072c629
children 207e0f5d551c
comparison
equal deleted inserted replaced
5650:e8ca7072c629 5651:a02ef29b4242
6 from roundup.cgi.exceptions import * 6 from roundup.cgi.exceptions import *
7 from roundup import password, hyperdb 7 from roundup import password, hyperdb
8 from roundup.rest import RestfulInstance, calculate_etag 8 from roundup.rest import RestfulInstance, calculate_etag
9 from roundup.backends import list_backends 9 from roundup.backends import list_backends
10 from roundup.cgi import client 10 from roundup.cgi import client
11 from roundup.anypy.strings import b2s, s2b
11 import random 12 import random
12 13
13 from .db_test_base import setupTracker 14 from .db_test_base import setupTracker
14 15
15 from .mocknull import MockNull 16 from .mocknull import MockNull
16 17
17 from io import StringIO 18 from io import BytesIO
18 import json 19 import json
19 20
20 NEEDS_INSTANCE = 1 21 NEEDS_INSTANCE = 1
21 22
22 23
407 """ 408 """
408 # Set joe's 'realname' using json data. 409 # Set joe's 'realname' using json data.
409 # simulate: /rest/data/user/<id>/realname 410 # simulate: /rest/data/user/<id>/realname
410 # use etag in header 411 # use etag in header
411 etag = calculate_etag(self.db.user.getnode(self.joeid)) 412 etag = calculate_etag(self.db.user.getnode(self.joeid))
412 body=u'{ "data": "Joe Doe 1" }' 413 body=b'{ "data": "Joe Doe 1" }'
413 env = { "CONTENT_TYPE": "application/json", 414 env = { "CONTENT_TYPE": "application/json",
414 "CONTENT_LENGTH": len(body), 415 "CONTENT_LENGTH": len(body),
415 "REQUEST_METHOD": "PUT" 416 "REQUEST_METHOD": "PUT"
416 } 417 }
417 headers={"accept": "application/json", 418 headers={"accept": "application/json",
420 } 421 }
421 self.headers=headers 422 self.headers=headers
422 # we need to generate a FieldStorage the looks like 423 # we need to generate a FieldStorage the looks like
423 # FieldStorage(None, None, 'string') rather than 424 # FieldStorage(None, None, 'string') rather than
424 # FieldStorage(None, None, []) 425 # FieldStorage(None, None, [])
425 body_file=StringIO(body) # FieldStorage needs a file 426 body_file=BytesIO(body) # FieldStorage needs a file
426 form = cgi.FieldStorage(body_file, 427 form = cgi.FieldStorage(body_file,
427 headers=headers, 428 headers=headers,
428 environ=env) 429 environ=env)
429 self.server.client.request.headers.get=self.get_header 430 self.server.client.request.headers.get=self.get_header
430 results = self.server.dispatch('PUT', 431 results = self.server.dispatch('PUT',
440 441
441 # Set joe's 'realname' using json data. 442 # Set joe's 'realname' using json data.
442 # simulate: /rest/data/user/<id>/realname 443 # simulate: /rest/data/user/<id>/realname
443 # use etag in payload 444 # use etag in payload
444 etag = calculate_etag(self.db.user.getnode(self.joeid)) 445 etag = calculate_etag(self.db.user.getnode(self.joeid))
445 body=u'{ "@etag": "%s", "data": "Joe Doe 2" }'%etag 446 body=s2b('{ "@etag": "%s", "data": "Joe Doe 2" }'%etag)
446 env = { "CONTENT_TYPE": "application/json", 447 env = { "CONTENT_TYPE": "application/json",
447 "CONTENT_LENGTH": len(body), 448 "CONTENT_LENGTH": len(body),
448 "REQUEST_METHOD": "PUT" 449 "REQUEST_METHOD": "PUT"
449 } 450 }
450 headers={"accept": "application/json", 451 headers={"accept": "application/json",
451 "content-type": env['CONTENT_TYPE'] 452 "content-type": env['CONTENT_TYPE']
452 } 453 }
453 self.headers=headers 454 self.headers=headers
454 body_file=StringIO(body) # FieldStorage needs a file 455 body_file=BytesIO(body) # FieldStorage needs a file
455 form = cgi.FieldStorage(body_file, 456 form = cgi.FieldStorage(body_file,
456 headers=headers, 457 headers=headers,
457 environ=env) 458 environ=env)
458 self.server.client.request.headers.get=self.get_header 459 self.server.client.request.headers.get=self.get_header
459 results = self.server.dispatch('PUT', 460 results = self.server.dispatch('PUT',
490 self.assertEqual(self.dummy_client.response_code, 200) 491 self.assertEqual(self.dummy_client.response_code, 200)
491 results = self.server.dispatch('GET', 492 results = self.server.dispatch('GET',
492 "/rest/data/user/%s/realname"%self.joeid, 493 "/rest/data/user/%s/realname"%self.joeid,
493 self.empty_form) 494 self.empty_form)
494 self.assertEqual(self.dummy_client.response_code, 200) 495 self.assertEqual(self.dummy_client.response_code, 200)
495 json_dict = json.loads(results) 496 json_dict = json.loads(b2s(results))
496 497
497 self.assertEqual(json_dict['data']['data'], 'Joe Doe') 498 self.assertEqual(json_dict['data']['data'], 'Joe Doe')
498 self.assertEqual(json_dict['data']['link'], 499 self.assertEqual(json_dict['data']['link'],
499 "http://tracker.example/cgi-bin/" 500 "http://tracker.example/cgi-bin/"
500 "roundup.cgi/bugs/rest/data/user/3/realname") 501 "roundup.cgi/bugs/rest/data/user/3/realname")
508 stored_results = self.server.get_element('user', self.joeid, 509 stored_results = self.server.get_element('user', self.joeid,
509 self.empty_form) 510 self.empty_form)
510 self.assertEqual(self.dummy_client.response_code, 200) 511 self.assertEqual(self.dummy_client.response_code, 200)
511 512
512 etag = calculate_etag(self.db.user.getnode(self.joeid)) 513 etag = calculate_etag(self.db.user.getnode(self.joeid))
513 body=u'{ "address": "demo2@example.com", "@etag": "%s"}'%etag 514 body=s2b('{ "address": "demo2@example.com", "@etag": "%s"}'%etag)
514 env = { "CONTENT_TYPE": "application/json", 515 env = { "CONTENT_TYPE": "application/json",
515 "CONTENT_LENGTH": len(body), 516 "CONTENT_LENGTH": len(body),
516 "REQUEST_METHOD": "PATCH" 517 "REQUEST_METHOD": "PATCH"
517 } 518 }
518 headers={"accept": "application/json", 519 headers={"accept": "application/json",
519 "content-type": env['CONTENT_TYPE'] 520 "content-type": env['CONTENT_TYPE']
520 } 521 }
521 self.headers=headers 522 self.headers=headers
522 body_file=StringIO(body) # FieldStorage needs a file 523 body_file=BytesIO(body) # FieldStorage needs a file
523 form = cgi.FieldStorage(body_file, 524 form = cgi.FieldStorage(body_file,
524 headers=headers, 525 headers=headers,
525 environ=env) 526 environ=env)
526 self.server.client.request.headers.get=self.get_header 527 self.server.client.request.headers.get=self.get_header
527 results = self.server.dispatch('PATCH', 528 results = self.server.dispatch('PATCH',
534 self.assertEqual(results['data']['attributes']['address'], 535 self.assertEqual(results['data']['attributes']['address'],
535 'demo2@example.com') 536 'demo2@example.com')
536 537
537 # and set it back 538 # and set it back
538 etag = calculate_etag(self.db.user.getnode(self.joeid)) 539 etag = calculate_etag(self.db.user.getnode(self.joeid))
539 body=u'{ "address": "%s", "@etag": "%s"}'%( 540 body=s2b('{ "address": "%s", "@etag": "%s"}'%(
540 stored_results['data']['attributes']['address'], 541 stored_results['data']['attributes']['address'],
541 etag) 542 etag))
542 # reuse env and headers from prior test. 543 # reuse env and headers from prior test.
543 body_file=StringIO(body) # FieldStorage needs a file 544 body_file=BytesIO(body) # FieldStorage needs a file
544 form = cgi.FieldStorage(body_file, 545 form = cgi.FieldStorage(body_file,
545 headers=headers, 546 headers=headers,
546 environ=env) 547 environ=env)
547 self.server.client.request.headers.get=self.get_header 548 self.server.client.request.headers.get=self.get_header
548 results = self.server.dispatch('PATCH', 549 results = self.server.dispatch('PATCH',
555 self.assertEqual(results['data']['attributes']['address'], 556 self.assertEqual(results['data']['attributes']['address'],
556 'random@home.org') 557 'random@home.org')
557 del(self.headers) 558 del(self.headers)
558 559
559 # POST to create new issue 560 # POST to create new issue
560 body=u'{ "title": "foo bar", "priority": "critical" }' 561 body=b'{ "title": "foo bar", "priority": "critical" }'
561 562
562 env = { "CONTENT_TYPE": "application/json", 563 env = { "CONTENT_TYPE": "application/json",
563 "CONTENT_LENGTH": len(body), 564 "CONTENT_LENGTH": len(body),
564 "REQUEST_METHOD": "POST" 565 "REQUEST_METHOD": "POST"
565 } 566 }
566 headers={"accept": "application/json", 567 headers={"accept": "application/json",
567 "content-type": env['CONTENT_TYPE'] 568 "content-type": env['CONTENT_TYPE']
568 } 569 }
569 self.headers=headers 570 self.headers=headers
570 body_file=StringIO(body) # FieldStorage needs a file 571 body_file=BytesIO(body) # FieldStorage needs a file
571 form = cgi.FieldStorage(body_file, 572 form = cgi.FieldStorage(body_file,
572 headers=headers, 573 headers=headers,
573 environ=env) 574 environ=env)
574 self.server.client.request.headers.get=self.get_header 575 self.server.client.request.headers.get=self.get_header
575 results = self.server.dispatch('POST', 576 results = self.server.dispatch('POST',
576 "/rest/data/issue", 577 "/rest/data/issue",
577 form) 578 form)
578 579
579 self.assertEqual(self.server.client.response_code, 201) 580 self.assertEqual(self.server.client.response_code, 201)
580 json_dict = json.loads(results) 581 json_dict = json.loads(b2s(results))
581 issue_id=json_dict['data']['id'] 582 issue_id=json_dict['data']['id']
582 results = self.server.get_element('issue', 583 results = self.server.get_element('issue',
583 str(issue_id), # must be a string not unicode 584 str(issue_id), # must be a string not unicode
584 self.empty_form) 585 self.empty_form)
585 self.assertEqual(self.dummy_client.response_code, 200) 586 self.assertEqual(self.dummy_client.response_code, 200)

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