diff options
| author | Barry Warsaw | 2017-02-06 15:30:01 +0000 |
|---|---|---|
| committer | Barry Warsaw | 2017-02-06 15:30:01 +0000 |
| commit | 03e04a93efa312bfec58dd267959d401e9bcf22b (patch) | |
| tree | db590d461c1e9c956c1f562f826d8ba0ddf405b3 | |
| parent | a75a718fa9073a51df8ce4deafe8a4851818b0a7 (diff) | |
| parent | 26e9f870a3d6aea1c7ff4d576d9b38e3b4d5bbbc (diff) | |
| download | mailman-03e04a93efa312bfec58dd267959d401e9bcf22b.tar.gz mailman-03e04a93efa312bfec58dd267959d401e9bcf22b.tar.zst mailman-03e04a93efa312bfec58dd267959d401e9bcf22b.zip | |
| -rw-r--r-- | setup.py | 1 | ||||
| -rw-r--r-- | src/mailman/rest/docs/basic.rst | 15 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_addresses.py | 112 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_bans.py | 24 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_basic.py | 7 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_domains.py | 26 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_header_matches.py | 6 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_listconf.py | 74 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_lists.py | 191 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_membership.py | 131 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_moderation.py | 105 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_queues.py | 8 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_root.py | 73 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_uids.py | 2 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_users.py | 96 | ||||
| -rw-r--r-- | src/mailman/runners/tests/test_rest.py | 7 | ||||
| -rw-r--r-- | src/mailman/testing/documentation.py | 13 | ||||
| -rw-r--r-- | src/mailman/testing/helpers.py | 34 |
18 files changed, 454 insertions, 471 deletions
@@ -111,7 +111,6 @@ case second `m'. Any other spelling is incorrect.""", 'flufl.bounce', 'flufl.i18n', 'flufl.lock', - 'httplib2', 'lazr.config', 'passlib', 'requests', diff --git a/src/mailman/rest/docs/basic.rst b/src/mailman/rest/docs/basic.rst index e1a712980..1f8084ecd 100644 --- a/src/mailman/rest/docs/basic.rst +++ b/src/mailman/rest/docs/basic.rst @@ -9,17 +9,14 @@ credentials, and the version of the API you wish to speak to. Credentials =========== -When the `Authorization` header contains the proper credentials, the request +If you include the proper basic authorization credentials, the request succeeds. - >>> from httplib2 import Http - >>> headers = { - ... 'Content-Type': 'application/x-www-form-urlencode', - ... 'Authorization': 'Basic cmVzdGFkbWluOnJlc3RwYXNz', - ... } - >>> url = 'http://localhost:9001/3.0/system/versions' - >>> response, content = Http().request(url, 'GET', None, headers) - >>> print(response.status) + >>> import requests + >>> response = requests.get( + ... 'http://localhost:9001/3.0/system/versions', + ... auth=('restadmin', 'restpass')) + >>> print(response.status_code) 200 diff --git a/src/mailman/rest/tests/test_addresses.py b/src/mailman/rest/tests/test_addresses.py index d70ad5c84..2f9774799 100644 --- a/src/mailman/rest/tests/test_addresses.py +++ b/src/mailman/rest/tests/test_addresses.py @@ -59,9 +59,9 @@ class TestAddresses(unittest.TestCase): def test_membership_of_address_with_no_user(self): with transaction(): getUtility(IUserManager).create_address('anne@example.com') - response, content = call_api( + json, content = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/memberships') - self.assertEqual(response['total_size'], 0) + self.assertEqual(json['total_size'], 0) def test_verify_a_missing_address(self): # POSTing to the 'verify' sub-resource returns a 404. @@ -84,9 +84,9 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = getUtility(IUserManager).create_address('anne@example.com') anne.verified_on = verified_on - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/verify', {}) - self.assertEqual(content['status'], '204') + self.assertEqual(response.status_code, 204) self.assertEqual(anne.verified_on, verified_on) def test_unverify_already_unverified(self): @@ -95,9 +95,9 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = getUtility(IUserManager).create_address('anne@example.com') self.assertEqual(anne.verified_on, None) - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/unverify', {}) - self.assertEqual(content['status'], '204') + self.assertEqual(response.status_code, 204) self.assertEqual(anne.verified_on, None) def test_verify_bad_request(self): @@ -125,15 +125,15 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): anne = user_manager.create_user('anne@example.com') - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com/addresses', { 'email': 'anne.person@example.org', }) self.assertIn('anne.person@example.org', [addr.email for addr in anne.addresses]) - self.assertEqual(content['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual( - content['location'], + response.headers['location'], 'http://localhost:9001/3.0/addresses/anne.person@example.org') # The address has no display name. anne_person = user_manager.get_address('anne.person@example.org') @@ -144,16 +144,16 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): anne = user_manager.create_user('anne@example.com') - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com/addresses', { 'email': 'anne.person@example.org', 'display_name': 'Ann E Person', }) self.assertIn('anne.person@example.org', [addr.email for addr in anne.addresses]) - self.assertEqual(content['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual( - content['location'], + response.headers['location'], 'http://localhost:9001/3.0/addresses/anne.person@example.org') # The address has no display name. anne_person = user_manager.get_address('anne.person@example.org') @@ -169,22 +169,22 @@ class TestAddresses(unittest.TestCase): 'email': 'anne@example.com', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Address belongs to other user') + self.assertEqual(cm.exception.reason, 'Address belongs to other user') def test_add_unlinked_address_to_user(self): user_manager = getUtility(IUserManager) with transaction(): anne = user_manager.create_user('anne.person@example.com') user_manager.create_address('anne@example.com') - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne.person@example.com/addresses', { 'email': 'anne@example.com', }) self.assertIn('anne@example.com', [address.email for address in anne.addresses]) - self.assertEqual(content['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual( - content['location'], + response.headers['location'], 'http://localhost:9001/3.0/addresses/anne@example.com') # The address has no display name. anne_person = user_manager.get_address('anne@example.com') @@ -195,16 +195,16 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne.person@example.com') user_manager.create_address('anne@example.com') - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne.person@example.com/addresses', { 'email': 'anne@example.com', 'display_name': 'Anne Person', }) self.assertIn('anne@example.com', [address.email for address in anne.addresses]) - self.assertEqual(content['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual( - content['location'], + response.headers['location'], 'http://localhost:9001/3.0/addresses/anne@example.com') # Even though a display_name was given in the POST data, because the # address already existed, it still has no display name. @@ -218,16 +218,16 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne@example.com') user_manager.create_user('bart@example.com') - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com/addresses', { 'email': 'bart@example.com', 'absorb_existing': True, }) self.assertIn('bart@example.com', [address.email for address in anne.addresses]) - self.assertEqual(content['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual( - content['location'], + response.headers['location'], 'http://localhost:9001/3.0/addresses/bart@example.com') def test_invalid_address_bad_request(self): @@ -240,7 +240,7 @@ class TestAddresses(unittest.TestCase): 'email': 'invalid_address_string' }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Invalid email address') + self.assertEqual(cm.exception.reason, 'Invalid email address') def test_empty_address_bad_request(self): # The address is required. @@ -251,7 +251,7 @@ class TestAddresses(unittest.TestCase): 'http://localhost:9001/3.0/users/anne@example.com/addresses', {}) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Missing parameters: email') + self.assertEqual(cm.exception.reason, 'Missing parameters: email') def test_get_addresses_of_missing_user(self): # There is no user associated with the given address. @@ -274,9 +274,9 @@ class TestAddresses(unittest.TestCase): # JSON representation. with transaction(): getUtility(IUserManager).create_user('anne@example.com') - json, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com') - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(json['user'], 'http://localhost:9001/3.0/users/1') def test_address_without_user(self): @@ -284,9 +284,9 @@ class TestAddresses(unittest.TestCase): # with no linked user. with transaction(): getUtility(IUserManager).create_address('anne@example.com') - json, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com') - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertNotIn('user', json) def test_user_subresource_on_unlinked_address(self): @@ -305,15 +305,15 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): user_manager.create_user('anne@example.com', 'Anne') - json, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user') - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(json['user_id'], 1) self.assertEqual(json['display_name'], 'Anne') user_resource = json['self_link'] self.assertEqual(user_resource, 'http://localhost:9001/3.0/users/1') # The self_link points to the correct user. - json, headers = call_api(user_resource) + json, response = call_api(user_resource) self.assertEqual(json['user_id'], 1) self.assertEqual(json['display_name'], 'Anne') self.assertEqual(json['self_link'], user_resource) @@ -325,11 +325,11 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne.person@example.org', 'Anne') anne_addr = user_manager.create_address('anne@example.com') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', { 'user_id': anne.user_id.int, }) - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(anne_addr.user, anne) self.assertEqual(sorted([a.email for a in anne.addresses]), ['anne.person@example.org', 'anne@example.com']) @@ -340,18 +340,18 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): anne_addr = user_manager.create_address('anne@example.com') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', { 'display_name': 'Anne', }) - self.assertEqual(headers['status'], '201') + self.assertEqual(response.status_code, 201) anne = user_manager.get_user('anne@example.com') self.assertIsNotNone(anne) self.assertEqual(anne.display_name, 'Anne') self.assertEqual([a.email for a in anne.addresses], ['anne@example.com']) self.assertEqual(anne_addr.user, anne) - self.assertEqual(headers['location'], + self.assertEqual(response.headers['location'], 'http://localhost:9001/3.0/users/1') def test_user_subresource_post_conflict(self): @@ -373,7 +373,7 @@ class TestAddresses(unittest.TestCase): with transaction(): getUtility(IUserManager).create_address('anne@example.com') with self.assertRaises(HTTPError) as cm: - json, headers = call_api( + call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', { 'display_name': 'Anne', 'auto_create': 0, @@ -390,7 +390,7 @@ class TestAddresses(unittest.TestCase): 'user_id': 2, }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'No user with ID 2') + self.assertEqual(cm.exception.reason, 'No user with ID 2') def test_user_subresource_unlink(self): # By DELETEing the usr subresource, you can unlink a user from an @@ -398,10 +398,10 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): user_manager.create_user('anne@example.com') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', method='DELETE') - self.assertEqual(headers['status'], '204') + self.assertEqual(response.status_code, 204) anne_addr = user_manager.get_address('anne@example.com') self.assertIsNone(anne_addr.user, 'The address is still linked') self.assertIsNone(user_manager.get_user('anne@example.com')) @@ -412,7 +412,7 @@ class TestAddresses(unittest.TestCase): with transaction(): user_manager.create_address('anne@example.com') with self.assertRaises(HTTPError) as cm: - response, headers = call_api( + call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', method='DELETE') self.assertEqual(cm.exception.code, 404) @@ -424,11 +424,11 @@ class TestAddresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne@example.com', 'Anne') bart = user_manager.create_user(display_name='Bart') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', { 'user_id': bart.user_id.int, }, method='PUT') - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(anne.addresses, []) self.assertEqual([address.email for address in bart.addresses], ['anne@example.com']) @@ -440,11 +440,11 @@ class TestAddresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): anne = user_manager.create_user('anne@example.com', 'Anne') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/addresses/anne@example.com/user', { 'email': 'anne.person@example.org', }, method='PUT') - self.assertEqual(headers['status'], '201') + self.assertEqual(response.status_code, 201) self.assertEqual(anne.addresses, []) anne_person = user_manager.get_user('anne.person@example.org') self.assertIsNotNone(anne_person) @@ -459,7 +459,7 @@ class TestAddresses(unittest.TestCase): # DELETEing an address through the REST API that doesn't exist returns # a 404 error. with self.assertRaises(HTTPError) as cm: - response, headers = call_api( + call_api( 'http://localhost:9001/3.0/addresses/anne@example.com', method='DELETE') self.assertEqual(cm.exception.code, 404) @@ -512,10 +512,10 @@ class TestAPI31Addresses(unittest.TestCase): user_manager = getUtility(IUserManager) with transaction(): user_manager.create_user('anne@example.com', 'Anne') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/addresses/anne@example.com') self.assertEqual( - response['user'], + json['user'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') def test_addresses_user_ids_are_hex(self): @@ -525,8 +525,8 @@ class TestAPI31Addresses(unittest.TestCase): user_manager.create_user('anne@example.com', 'Anne') with transaction(): user_manager.create_user('bart@example.com', 'Bart') - response, headers = call_api('http://localhost:9001/3.1/addresses') - entries = response['entries'] + json, response = call_api('http://localhost:9001/3.1/addresses') + entries = json['entries'] self.assertEqual( entries[0]['user'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') @@ -542,11 +542,11 @@ class TestAPI31Addresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne.person@example.org', 'Anne') anne_addr = user_manager.create_address('anne@example.com') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/addresses/anne@example.com/user', { 'user_id': anne.user_id.hex, }) - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(anne_addr.user, anne) self.assertEqual(sorted([a.email for a in anne.addresses]), ['anne.person@example.org', 'anne@example.com']) @@ -566,7 +566,7 @@ class TestAPI31Addresses(unittest.TestCase): }) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: user_id') + 'Cannot convert parameters: user_id') def test_user_subresource_put(self): # By PUTing to the 'user' resource, you can change the user that an @@ -575,11 +575,11 @@ class TestAPI31Addresses(unittest.TestCase): with transaction(): anne = user_manager.create_user('anne@example.com', 'Anne') bart = user_manager.create_user(display_name='Bart') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/addresses/anne@example.com/user', { 'user_id': bart.user_id.hex, }, method='PUT') - self.assertEqual(headers['status'], '200') + self.assertEqual(response.status_code, 200) self.assertEqual(anne.addresses, []) self.assertEqual([address.email for address in bart.addresses], ['anne@example.com']) @@ -601,4 +601,4 @@ class TestAPI31Addresses(unittest.TestCase): }, method='PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: user_id') + 'Cannot convert parameters: user_id') diff --git a/src/mailman/rest/tests/test_bans.py b/src/mailman/rest/tests/test_bans.py index 877f6692c..8866bd80b 100644 --- a/src/mailman/rest/tests/test_bans.py +++ b/src/mailman/rest/tests/test_bans.py @@ -40,7 +40,7 @@ class TestBans(unittest.TestCase): '/bans/notbanned@example.com') self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'Email is not banned: notbanned@example.com') + 'Email is not banned: notbanned@example.com') def test_delete_missing_banned_address(self): with self.assertRaises(HTTPError) as cm: @@ -49,7 +49,7 @@ class TestBans(unittest.TestCase): method='DELETE') self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'Email is not banned: notbanned@example.com') + 'Email is not banned: notbanned@example.com') def test_not_found_after_unbanning(self): manager = IBanManager(self._mlist) @@ -57,30 +57,30 @@ class TestBans(unittest.TestCase): manager.ban('banned@example.com') url = ('http://localhost:9001/3.0/lists/ant.example.com' '/bans/banned@example.com') - response, content = call_api(url) - self.assertEqual(response['email'], 'banned@example.com') - response, content = call_api(url, method='DELETE') - self.assertEqual(content.status, 204) + json, response = call_api(url) + self.assertEqual(json['email'], 'banned@example.com') + json, response = call_api(url, method='DELETE') + self.assertEqual(response.status_code, 204) with self.assertRaises(HTTPError) as cm: call_api(url) self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'Email is not banned: banned@example.com') + 'Email is not banned: banned@example.com') def test_not_found_after_unbanning_global(self): manager = IBanManager(None) with transaction(): manager.ban('banned@example.com') url = ('http://localhost:9001/3.0/bans/banned@example.com') - response, content = call_api(url) - self.assertEqual(response['email'], 'banned@example.com') - response, content = call_api(url, method='DELETE') - self.assertEqual(content.status, 204) + json, response = call_api(url) + self.assertEqual(json['email'], 'banned@example.com') + json, response = call_api(url, method='DELETE') + self.assertEqual(response.status_code, 204) with self.assertRaises(HTTPError) as cm: call_api(url) self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'Email is not banned: banned@example.com') + 'Email is not banned: banned@example.com') def test_ban_missing_mailing_list(self): with self.assertRaises(HTTPError) as cm: diff --git a/src/mailman/rest/tests/test_basic.py b/src/mailman/rest/tests/test_basic.py index 2799c6f83..16ec2f5a3 100644 --- a/src/mailman/rest/tests/test_basic.py +++ b/src/mailman/rest/tests/test_basic.py @@ -27,6 +27,7 @@ from mailman.database.transaction import transaction from mailman.testing.helpers import call_api from mailman.testing.layers import RESTLayer from urllib.error import HTTPError +from urllib.request import urlopen class TestBasicREST(unittest.TestCase): @@ -39,7 +40,7 @@ class TestBasicREST(unittest.TestCase): self._mlist = create_list('test@example.com') def test_comma_fields(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test@example.com/config', dict(description='A description with , to check stuff'), method='PATCH') @@ -50,6 +51,8 @@ class TestBasicREST(unittest.TestCase): def test_send_error(self): # GL#288 working around Python bug #28548. The improperly encoded # space in the URL breaks error reporting due to default HTTP/0.9. + # Use urllib.request since requests will encode the URL, defeating the + # purpose of this test (i.e. we want the literal space, not %20). with self.assertRaises(HTTPError) as cm: - call_api('http://localhost:9001/3.0/lists/test @example.com') + urlopen('http://localhost:9001/3.0/lists/test @example.com') self.assertEqual(cm.exception.code, 400) diff --git a/src/mailman/rest/tests/test_domains.py b/src/mailman/rest/tests/test_domains.py index bbbd54ef3..3bacf7a72 100644 --- a/src/mailman/rest/tests/test_domains.py +++ b/src/mailman/rest/tests/test_domains.py @@ -46,7 +46,7 @@ class TestDomains(unittest.TestCase): ) content, response = call_api( 'http://localhost:9001/3.0/domains', data, method="POST") - self.assertEqual(response.status, 201) + self.assertEqual(response.status_code, 201) def test_patch_domain_description(self): # Patch the example.com description. @@ -55,7 +55,7 @@ class TestDomains(unittest.TestCase): 'http://localhost:9001/3.0/domains/example.com', data, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Check the result. domain = getUtility(IDomainManager).get('example.com') self.assertEqual(domain.description, 'Patched example domain') @@ -67,7 +67,7 @@ class TestDomains(unittest.TestCase): 'http://localhost:9001/3.0/domains/example.com', data, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Check the result. domain = getUtility(IDomainManager).get('example.com') self.assertEqual( @@ -81,7 +81,7 @@ class TestDomains(unittest.TestCase): 'http://localhost:9001/3.0/domains/example.com', data, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Check the result. domain = getUtility(IDomainManager).get('example.com') self.assertEqual( @@ -106,7 +106,7 @@ class TestDomains(unittest.TestCase): owner='anne@example.com', ), method='POST') - self.assertEqual(response.status, 201) + self.assertEqual(response.status_code, 201) # The domain has the expected owner. domain = getUtility(IDomainManager).get('example.net') self.assertEqual( @@ -132,7 +132,7 @@ class TestDomains(unittest.TestCase): create_list('ant@example.com') content, response = call_api( 'http://localhost:9001/3.0/domains/example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertIsNone(getUtility(IListManager).get('ant@example.com')) def test_missing_domain(self): @@ -161,7 +161,7 @@ class TestDomains(unittest.TestCase): content, response = call_api( 'http://localhost:9001/3.0/domains/example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) with self.assertRaises(HTTPError) as cm: call_api('http://localhost:9001/3.0/domains/example.com', method='DELETE') @@ -255,7 +255,7 @@ class TestDomainTemplates(unittest.TestCase): ) resource, response = call_api( 'http://localhost:9001/3.1/domains/example.com/uris') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) self.assertEqual(resource['start'], 0) self.assertEqual(resource['total_size'], 2) self.assertEqual( @@ -283,7 +283,7 @@ class TestDomainTemplates(unittest.TestCase): 'list:user:notice:welcome': 'http://example.org/welcome', 'list:user:notice:goodbye': 'http://example.org/goodbye', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', 'example.com') self.assertEqual(template.uri, 'http://example.org/welcome') @@ -302,7 +302,7 @@ class TestDomainTemplates(unittest.TestCase): 'password': 'some password', 'username': 'anne.person', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', 'example.com') self.assertEqual(template.uri, 'http://example.org/welcome') @@ -350,7 +350,7 @@ class TestDomainTemplates(unittest.TestCase): 'password': 'some password', 'username': 'anne.person', }, method='PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:member:digest:footer', 'example.com') self.assertIsNone(template) @@ -387,7 +387,7 @@ class TestDomainTemplates(unittest.TestCase): resource, response = call_api( 'http://localhost:9001/3.1/domains/example.com/uris', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertIsNone( manager.raw('list:user:notice:welcome', 'example.com')) self.assertIsNone( @@ -401,7 +401,7 @@ class TestDomainTemplates(unittest.TestCase): resource, response = call_api( 'http://localhost:9001/3.1/domains/example.com/uris' '/list:user:notice:welcome') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) self.assertEqual(resource, { 'http_etag': '"8884a0b3d675b4cb9899a7825daac9db88b70bed"', 'self_link': ('http://localhost:9001/3.1/domains/example.com' diff --git a/src/mailman/rest/tests/test_header_matches.py b/src/mailman/rest/tests/test_header_matches.py index 892d258b0..a02b15f2e 100644 --- a/src/mailman/rest/tests/test_header_matches.py +++ b/src/mailman/rest/tests/test_header_matches.py @@ -40,7 +40,7 @@ class TestHeaderMatches(unittest.TestCase): '/header-matches/0') self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'No header match at this position: 0') + 'No header match at this position: 0') def test_delete_missing_header_match(self): with self.assertRaises(HTTPError) as cm: @@ -49,7 +49,7 @@ class TestHeaderMatches(unittest.TestCase): method='DELETE') self.assertEqual(cm.exception.code, 404) self.assertEqual(cm.exception.reason, - b'No header match at this position: 0') + 'No header match at this position: 0') def test_add_duplicate(self): header_matches = IHeaderMatchList(self._mlist) @@ -63,7 +63,7 @@ class TestHeaderMatches(unittest.TestCase): }) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'This header match already exists') + 'This header match already exists') def test_header_match_on_missing_list(self): with self.assertRaises(HTTPError) as cm: diff --git a/src/mailman/rest/tests/test_listconf.py b/src/mailman/rest/tests/test_listconf.py index c5dc93ff9..06c138fee 100644 --- a/src/mailman/rest/tests/test_listconf.py +++ b/src/mailman/rest/tests/test_listconf.py @@ -96,35 +96,35 @@ class TestConfiguration(unittest.TestCase): call_api( 'http://localhost:9001/3.0/lists/ant.example.com/config/bogus') self.assertEqual(cm.exception.code, 404) - self.assertEqual(cm.exception.reason, b'Unknown attribute: bogus') + self.assertEqual(cm.exception.reason, 'Unknown attribute: bogus') def test_put_configuration(self): # When using PUT, all writable attributes must be included. - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com/config', RESOURCE, 'PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual(self._mlist.display_name, 'Fnords') # All three acceptable aliases were set. self.assertEqual(set(IAcceptableAliasSet(self._mlist).aliases), set(RESOURCE['acceptable_aliases'])) def test_put_attribute(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com' '/config/reply_to_address') - self.assertEqual(resource['reply_to_address'], '') - resource, response = call_api( + self.assertEqual(json['reply_to_address'], '') + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com' '/config/reply_to_address', dict(reply_to_address='bar@ant.example.com'), 'PUT') - self.assertEqual(response.status, 204) - resource, response = call_api( + self.assertEqual(response.status_code, 204) + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com' '/config/reply_to_address') - self.assertEqual(resource['reply_to_address'], 'bar@ant.example.com') + self.assertEqual(json['reply_to_address'], 'bar@ant.example.com') def test_put_extra_attribute(self): bogus_resource = RESOURCE.copy() @@ -135,22 +135,22 @@ class TestConfiguration(unittest.TestCase): bogus_resource, 'PUT') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Unexpected parameters: bogus') + self.assertEqual(cm.exception.reason, 'Unexpected parameters: bogus') def test_put_attribute_mismatch(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com' '/config/reply_to_address') - self.assertEqual(resource['reply_to_address'], '') + self.assertEqual(json['reply_to_address'], '') with self.assertRaises(HTTPError) as cm: - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com' '/config/reply_to_address', dict(display_name='bar@ant.example.com'), 'PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Unexpected parameters: display_name') + 'Unexpected parameters: display_name') def test_put_attribute_double(self): with self.assertRaises(HTTPError) as cm: @@ -162,7 +162,7 @@ class TestConfiguration(unittest.TestCase): 'PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Unexpected parameters: display_name') + 'Unexpected parameters: display_name') def test_put_read_only_attribute(self): with self.assertRaises(HTTPError) as cm: @@ -171,8 +171,7 @@ class TestConfiguration(unittest.TestCase): dict(mail_host='foo.example.com'), 'PUT') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, - b'Read-only attribute: mail_host') + self.assertEqual(cm.exception.reason, 'Read-only attribute: mail_host') def test_put_missing_attribute(self): with self.assertRaises(HTTPError) as cm: @@ -181,7 +180,7 @@ class TestConfiguration(unittest.TestCase): dict(bogus='no matter'), 'PUT') self.assertEqual(cm.exception.code, 404) - self.assertEqual(cm.exception.reason, b'Unknown attribute: bogus') + self.assertEqual(cm.exception.reason, 'Unknown attribute: bogus') def test_patch_subscription_policy(self): # The new subscription_policy value can be patched. @@ -195,7 +194,7 @@ class TestConfiguration(unittest.TestCase): 'http://localhost:9001/3.0/lists/ant.example.com/config', dict( subscription_policy='confirm_then_moderate'), method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # And now we verify that it has the requested setting. self.assertEqual(self._mlist.subscription_policy, SubscriptionPolicy.confirm_then_moderate) @@ -209,7 +208,7 @@ class TestConfiguration(unittest.TestCase): reply_to_address='foo'), 'PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Expected 1 attribute, got 2') + self.assertEqual(cm.exception.reason, 'Expected 1 attribute, got 2') def test_unknown_patch_attribute(self): with self.assertRaises(HTTPError) as cm: @@ -217,7 +216,7 @@ class TestConfiguration(unittest.TestCase): dict(bogus=1), 'PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Unknown attribute: bogus') + self.assertEqual(cm.exception.reason, 'Unknown attribute: bogus') def test_read_only_patch_attribute(self): with self.assertRaises(HTTPError) as cm: @@ -226,8 +225,7 @@ class TestConfiguration(unittest.TestCase): dict(mail_host='foo.example.com'), 'PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, - b'Read-only attribute: mail_host') + self.assertEqual(cm.exception.reason, 'Read-only attribute: mail_host') def test_patch_missing_attribute(self): with self.assertRaises(HTTPError) as cm: @@ -236,7 +234,7 @@ class TestConfiguration(unittest.TestCase): dict(bogus='no matter'), 'PATCH') self.assertEqual(cm.exception.code, 404) - self.assertEqual(cm.exception.reason, b'Unknown attribute: bogus') + self.assertEqual(cm.exception.reason, 'Unknown attribute: bogus') def test_patch_bad_value(self): with self.assertRaises(HTTPError) as cm: @@ -247,7 +245,7 @@ class TestConfiguration(unittest.TestCase): 'PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: archive_policy') + 'Cannot convert parameters: archive_policy') def test_bad_pipeline_name(self): with self.assertRaises(HTTPError) as cm: @@ -258,7 +256,7 @@ class TestConfiguration(unittest.TestCase): 'PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: posting_pipeline') + 'Cannot convert parameters: posting_pipeline') def test_get_digest_send_periodic(self): with transaction(): @@ -276,7 +274,7 @@ class TestConfiguration(unittest.TestCase): '/digest_send_periodic', dict(digest_send_periodic=True), 'PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertTrue(self._mlist.digest_send_periodic) def test_put_digest_send_periodic(self): @@ -287,7 +285,7 @@ class TestConfiguration(unittest.TestCase): '/digest_send_periodic', dict(digest_send_periodic=True), 'PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertTrue(self._mlist.digest_send_periodic) def test_get_digest_volume_frequency(self): @@ -306,7 +304,7 @@ class TestConfiguration(unittest.TestCase): '/digest_volume_frequency', dict(digest_volume_frequency='monthly'), 'PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual(self._mlist.digest_volume_frequency, DigestFrequency.monthly) @@ -318,7 +316,7 @@ class TestConfiguration(unittest.TestCase): '/digest_volume_frequency', dict(digest_volume_frequency='monthly'), 'PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual(self._mlist.digest_volume_frequency, DigestFrequency.monthly) @@ -333,7 +331,7 @@ class TestConfiguration(unittest.TestCase): 'PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: digest_volume_frequency') + 'Cannot convert parameters: digest_volume_frequency') def test_bad_put_digest_volume_frequency(self): with transaction(): @@ -346,7 +344,7 @@ class TestConfiguration(unittest.TestCase): 'PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: digest_volume_frequency') + 'Cannot convert parameters: digest_volume_frequency') def test_get_digests_enabled(self): with transaction(): @@ -364,7 +362,7 @@ class TestConfiguration(unittest.TestCase): '/digests_enabled', dict(digests_enabled=True), 'PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertTrue(self._mlist.digests_enabled) def test_put_digests_enabled(self): @@ -375,7 +373,7 @@ class TestConfiguration(unittest.TestCase): '/digests_enabled', dict(digests_enabled=True), 'PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertTrue(self._mlist.digests_enabled) def test_get_goodbye_message_uri(self): @@ -394,7 +392,7 @@ class TestConfiguration(unittest.TestCase): 'http://localhost:9001/3.0/lists/ant.example.com/config', dict(goodbye_message_uri='mailman:///salutation.txt'), 'PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual( getUtility(ITemplateManager).raw( 'user:ack:goodbye', self._mlist.list_id).uri, @@ -406,7 +404,7 @@ class TestConfiguration(unittest.TestCase): '/goodbye_message_uri', dict(goodbye_message_uri='mailman:///salutation.txt'), 'PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual( getUtility(ITemplateManager).raw( 'user:ack:goodbye', self._mlist.list_id).uri, @@ -424,7 +422,7 @@ class TestConfiguration(unittest.TestCase): '/goodbye_message_uri', dict(goodbye_message_uri='mailman:///salutation.txt'), 'PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual( manager.raw('user:ack:goodbye', self._mlist.list_id).uri, 'mailman:///salutation.txt') @@ -453,7 +451,7 @@ class TestConfiguration(unittest.TestCase): 'PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: description') + 'Cannot convert parameters: description') def test_patch_info(self): with transaction(): diff --git a/src/mailman/rest/tests/test_lists.py b/src/mailman/rest/tests/test_lists.py index 2481bedcd..7bb7bd333 100644 --- a/src/mailman/rest/tests/test_lists.py +++ b/src/mailman/rest/tests/test_lists.py @@ -86,20 +86,20 @@ class TestLists(unittest.TestCase): def test_member_count_with_no_members(self): # The list initially has 0 members. - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test@example.com') - self.assertEqual(response.status, 200) - self.assertEqual(resource['member_count'], 0) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['member_count'], 0) def test_member_count_with_one_member(self): # Add a member to a list and check that the resource reflects this. with transaction(): anne = self._usermanager.create_address('anne@example.com') self._mlist.subscribe(anne) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test@example.com') - self.assertEqual(response.status, 200) - self.assertEqual(resource['member_count'], 1) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['member_count'], 1) def test_member_count_with_two_members(self): # Add two members to a list and check that the resource reflects this. @@ -108,10 +108,10 @@ class TestLists(unittest.TestCase): self._mlist.subscribe(anne) bart = self._usermanager.create_address('bar@example.com') self._mlist.subscribe(bart) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test@example.com') - self.assertEqual(response.status, 200) - self.assertEqual(resource['member_count'], 2) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['member_count'], 2) def test_query_for_lists_in_missing_domain(self): # You cannot ask all the mailing lists in a non-existent domain. @@ -127,7 +127,7 @@ class TestLists(unittest.TestCase): }) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Domain does not exist: no-domain.example.org') + 'Domain does not exist: no-domain.example.org') def test_cannot_create_duplicate_list(self): # You cannot create a list that already exists. @@ -139,7 +139,7 @@ class TestLists(unittest.TestCase): 'fqdn_listname': 'ant@example.com', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Mailing list exists') + self.assertEqual(cm.exception.reason, 'Mailing list exists') def test_cannot_delete_missing_list(self): # You cannot delete a list that does not exist. @@ -167,14 +167,14 @@ class TestLists(unittest.TestCase): bart = self._usermanager.create_address('bart@example.com') self._mlist.subscribe(anne) self._mlist.subscribe(bart) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test@example.com/roster/member') - self.assertEqual(resource['start'], 0) - self.assertEqual(resource['total_size'], 2) - member = resource['entries'][0] + self.assertEqual(json['start'], 0) + self.assertEqual(json['total_size'], 2) + member = json['entries'][0] self.assertEqual(member['email'], 'anne@example.com') self.assertEqual(member['role'], 'member') - member = resource['entries'][1] + member = json['entries'][1] self.assertEqual(member['email'], 'bart@example.com') self.assertEqual(member['role'], 'member') @@ -222,19 +222,20 @@ class TestLists(unittest.TestCase): self._mlist.subscribe(aperson) self._mlist.subscribe(bperson) self._mlist.subscribe(cperson) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test.example.com' '/roster/member', { 'emails': ['aperson@example.com', 'bperson@example.com', ]}, 'DELETE') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Remove variable data. - resource.pop('http_etag') - self.assertEqual(resource, {'aperson@example.com': True, - 'bperson@example.com': True, - }) + json.pop('http_etag') + self.assertEqual(json, { + 'aperson@example.com': True, + 'bperson@example.com': True, + }) def test_list_mass_unsubscribe_all_fail(self): with transaction(): @@ -244,19 +245,20 @@ class TestLists(unittest.TestCase): self._mlist.subscribe(aperson) self._mlist.subscribe(bperson) self._mlist.subscribe(cperson) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test.example.com' '/roster/member', { 'emails': ['yperson@example.com', 'zperson@example.com', ]}, 'DELETE') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Remove variable data. - resource.pop('http_etag') - self.assertEqual(resource, {'yperson@example.com': False, - 'zperson@example.com': False, - }) + json.pop('http_etag') + self.assertEqual(json, { + 'yperson@example.com': False, + 'zperson@example.com': False, + }) def test_list_mass_unsubscribe_mixed_success(self): with transaction(): @@ -266,19 +268,20 @@ class TestLists(unittest.TestCase): self._mlist.subscribe(aperson) self._mlist.subscribe(bperson) self._mlist.subscribe(cperson) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test.example.com' '/roster/member', { 'emails': ['aperson@example.com', 'zperson@example.com', ]}, 'DELETE') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Remove variable data. - resource.pop('http_etag') - self.assertEqual(resource, {'aperson@example.com': True, - 'zperson@example.com': False, - }) + json.pop('http_etag') + self.assertEqual(json, { + 'aperson@example.com': True, + 'zperson@example.com': False, + }) def test_list_mass_unsubscribe_with_duplicates(self): with transaction(): @@ -288,7 +291,7 @@ class TestLists(unittest.TestCase): self._mlist.subscribe(aperson) self._mlist.subscribe(bperson) self._mlist.subscribe(cperson) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/test.example.com' '/roster/member', { 'emails': ['aperson@example.com', @@ -297,13 +300,14 @@ class TestLists(unittest.TestCase): 'zperson@example.com', ]}, 'DELETE') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Remove variable data. - resource.pop('http_etag') - self.assertEqual(resource, {'aperson@example.com': True, - 'bperson@example.com': True, - 'zperson@example.com': False, - }) + json.pop('http_etag') + self.assertEqual(json, { + 'aperson@example.com': True, + 'bperson@example.com': True, + 'zperson@example.com': False, + }) def test_list_mass_unsubscribe_bogus_list(self): with self.assertRaises(HTTPError) as cm: @@ -318,7 +322,7 @@ class TestLists(unittest.TestCase): '/roster/member', None, 'DELETE') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Missing parameters: emails') + self.assertEqual(cm.exception.reason, 'Missing parameters: emails') class TestListArchivers(unittest.TestCase): @@ -331,12 +335,12 @@ class TestListArchivers(unittest.TestCase): self._mlist = create_list('ant@example.com') def test_archiver_statuses(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com/archivers') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Remove the variable data. - resource.pop('http_etag') - self.assertEqual(resource, { + json.pop('http_etag') + self.assertEqual(json, { 'mail-archive': True, 'mhonarc': True, }) @@ -358,7 +362,7 @@ class TestListArchivers(unittest.TestCase): method='PUT') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Unexpected parameters: bogus-archiver') + 'Unexpected parameters: bogus-archiver') def test_patch_bogus_archiver(self): # You cannot PATCH on an archiver the list doesn't know about. @@ -370,7 +374,7 @@ class TestListArchivers(unittest.TestCase): method='PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Unexpected parameters: bogus-archiver') + 'Unexpected parameters: bogus-archiver') def test_put_incomplete_statuses(self): # PUT requires the full resource representation. This one forgets to @@ -382,8 +386,7 @@ class TestListArchivers(unittest.TestCase): }, method='PUT') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, - b'Missing parameters: mhonarc') + self.assertEqual(cm.exception.reason, 'Missing parameters: mhonarc') def test_patch_bogus_status(self): # Archiver statuses must be interpretable as booleans. @@ -395,7 +398,7 @@ class TestListArchivers(unittest.TestCase): }, method='PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Invalid boolean value: sure') + self.assertEqual(cm.exception.reason, 'Invalid boolean value: sure') class TestListPagination(unittest.TestCase): @@ -419,36 +422,36 @@ class TestListPagination(unittest.TestCase): create_list('fly@example.com') def test_first_page(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/domains/example.com/lists' '?count=1&page=1') # There are 6 total lists, but only the first one in the page. - self.assertEqual(resource['total_size'], 6) - self.assertEqual(resource['start'], 0) - self.assertEqual(len(resource['entries']), 1) - entry = resource['entries'][0] + self.assertEqual(json['total_size'], 6) + self.assertEqual(json['start'], 0) + self.assertEqual(len(json['entries']), 1) + entry = json['entries'][0] self.assertEqual(entry['fqdn_listname'], 'ant@example.com') def test_second_page(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/domains/example.com/lists' '?count=1&page=2') # There are 6 total lists, but only the first one in the page. - self.assertEqual(resource['total_size'], 6) - self.assertEqual(resource['start'], 1) - self.assertEqual(len(resource['entries']), 1) - entry = resource['entries'][0] + self.assertEqual(json['total_size'], 6) + self.assertEqual(json['start'], 1) + self.assertEqual(len(json['entries']), 1) + entry = json['entries'][0] self.assertEqual(entry['fqdn_listname'], 'bee@example.com') def test_last_page(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/domains/example.com/lists' '?count=1&page=6') # There are 6 total lists, but only the first one in the page. - self.assertEqual(resource['total_size'], 6) - self.assertEqual(resource['start'], 5) - self.assertEqual(len(resource['entries']), 1) - entry = resource['entries'][0] + self.assertEqual(json['total_size'], 6) + self.assertEqual(json['start'], 5) + self.assertEqual(len(json['entries']), 1) + entry = json['entries'][0] self.assertEqual(entry['fqdn_listname'], 'fly@example.com') def test_zeroth_page(self): @@ -469,13 +472,13 @@ class TestListPagination(unittest.TestCase): def test_past_last_page(self): # The 7th page doesn't exist so the collection is empty. - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/domains/example.com/lists' '?count=1&page=7') # There are 6 total lists, but only the first one in the page. - self.assertEqual(resource['total_size'], 6) - self.assertEqual(resource['start'], 6) - self.assertNotIn('entries', resource) + self.assertEqual(json['total_size'], 6) + self.assertEqual(json['start'], 6) + self.assertNotIn('entries', json) class TestListDigests(unittest.TestCase): @@ -498,15 +501,15 @@ class TestListDigests(unittest.TestCase): self.assertEqual(cm.exception.code, 404) def test_post_nothing_to_do(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com/digest', {}) - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) def test_post_something_to_do(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com/digest', dict( bump=True)) - self.assertEqual(response.status, 202) + self.assertEqual(response.status_code, 202) def test_post_bad_request(self): with self.assertRaises(HTTPError) as cm: @@ -514,7 +517,7 @@ class TestListDigests(unittest.TestCase): 'http://localhost:9001/3.0/lists/ant.example.com/digest', dict( bogus=True)) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Unexpected parameters: bogus') + self.assertEqual(cm.exception.reason, 'Unexpected parameters: bogus') def test_bump_before_send(self): with transaction(): @@ -530,11 +533,11 @@ Subject: message 1 """) config.handlers['to-digest'].process(self._mlist, msg, {}) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant.example.com/digest', dict( send=True, bump=True)) - self.assertEqual(response.status, 202) + self.assertEqual(response.status_code, 202) make_testable_runner(DigestRunner, 'digest').run() # The volume is 8 and the digest number is 2 because a digest was sent # after the volume/number was bumped. @@ -588,15 +591,15 @@ class TestListTemplates(unittest.TestCase): 'http://example.com/goodbye', 'a user', 'the password', ) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris') - self.assertEqual(response.status, 200) - self.assertEqual(resource['start'], 0) - self.assertEqual(resource['total_size'], 2) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['start'], 0) + self.assertEqual(json['total_size'], 2) self.assertEqual( - resource['self_link'], + json['self_link'], 'http://localhost:9001/3.1/lists/ant.example.com/uris') - self.assertEqual(resource['entries'], [ + self.assertEqual(json['entries'], [ {'http_etag': '"6612187ed6604ce54a57405fd66742557391ed4a"', 'name': 'list:user:notice:goodbye', 'password': 'the password', @@ -613,12 +616,12 @@ class TestListTemplates(unittest.TestCase): }]) def test_patch_uris(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris', { 'list:user:notice:welcome': 'http://example.org/welcome', 'list:user:notice:goodbye': 'http://example.org/goodbye', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', 'ant.example.com') self.assertEqual(template.uri, 'http://example.org/welcome') @@ -630,14 +633,14 @@ class TestListTemplates(unittest.TestCase): self.assertEqual(template.password, '') def test_patch_uris_with_credentials(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris', { 'list:user:notice:welcome': 'http://example.org/welcome', 'list:user:notice:goodbye': 'http://example.org/goodbye', 'password': 'some password', 'username': 'anne.person', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', 'ant.example.com') self.assertEqual(template.uri, 'http://example.org/welcome') @@ -659,7 +662,7 @@ class TestListTemplates(unittest.TestCase): self.assertEqual(cm.exception.code, 400) def test_put_all_uris(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris', { 'list:admin:action:post': '', 'list:admin:action:subscribe': '', @@ -684,7 +687,7 @@ class TestListTemplates(unittest.TestCase): 'password': 'some password', 'username': 'anne.person', }, method='PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:member:digest:footer', 'ant.example.com') self.assertIsNone(template) @@ -718,10 +721,10 @@ class TestListTemplates(unittest.TestCase): 'http://example.com/goodbye', 'a user', 'the password', ) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertIsNone( manager.raw('list:user:notice:welcome', 'ant.example.com')) self.assertIsNone( @@ -732,11 +735,11 @@ class TestListTemplates(unittest.TestCase): getUtility(ITemplateManager).set( 'list:user:notice:welcome', 'ant.example.com', 'http://example.com/welcome') - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/uris' '/list:user:notice:welcome') - self.assertEqual(response.status, 200) - self.assertEqual(resource, { + self.assertEqual(response.status_code, 200) + self.assertEqual(json, { 'http_etag': '"36f8bef800cfd278f097c61c5892a34c0650f4aa"', 'self_link': ('http://localhost:9001/3.1/lists/ant.example.com' '/uris/list:user:notice:welcome'), diff --git a/src/mailman/rest/tests/test_membership.py b/src/mailman/rest/tests/test_membership.py index d5251ca9d..6b4f5195a 100644 --- a/src/mailman/rest/tests/test_membership.py +++ b/src/mailman/rest/tests/test_membership.py @@ -53,7 +53,7 @@ class TestMembership(unittest.TestCase): 'subscriber': 'nobody@example.com', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'No such list') + self.assertEqual(cm.exception.reason, 'No such list') def test_try_to_leave_missing_list(self): # A user tries to leave a non-existent list. @@ -74,11 +74,11 @@ class TestMembership(unittest.TestCase): anne = self._usermanager.create_address('anne@example.com') self._mlist.subscribe(anne) url = 'http://localhost:9001/3.0/members/1' - content, response = call_api(url, method='DELETE') + json, response = call_api(url, method='DELETE') # For a successful DELETE, the response code is 204 and there is no # content. - self.assertEqual(content, None) - self.assertEqual(response.status, 204) + self.assertEqual(json, None) + self.assertEqual(response.status_code, 204) with self.assertRaises(HTTPError) as cm: call_api(url, method='DELETE') self.assertEqual(cm.exception.code, 404) @@ -96,7 +96,7 @@ class TestMembership(unittest.TestCase): 'pre_approved': True, }) self.assertEqual(cm.exception.code, 409) - self.assertEqual(cm.exception.reason, b'Member already subscribed') + self.assertEqual(cm.exception.reason, 'Member already subscribed') def test_subscribe_user_without_preferred_address(self): with transaction(): @@ -111,7 +111,7 @@ class TestMembership(unittest.TestCase): 'pre_approved': True, }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'User has no preferred address') + self.assertEqual(cm.exception.reason, 'User has no preferred address') def test_subscribe_bogus_user_by_uid(self): with self.assertRaises(HTTPError) as cm: @@ -123,7 +123,7 @@ class TestMembership(unittest.TestCase): 'pre_approved': True, }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'No such user') + self.assertEqual(cm.exception.reason, 'No such user') def test_add_member_with_mixed_case_email(self): # LP: #1425359 - Mailman is case-perserving, case-insensitive. This @@ -141,7 +141,7 @@ class TestMembership(unittest.TestCase): 'pre_approved': True, }) self.assertEqual(cm.exception.code, 409) - self.assertEqual(cm.exception.reason, b'Member already subscribed') + self.assertEqual(cm.exception.reason, 'Member already subscribed') def test_add_member_with_lower_case_email(self): # LP: #1425359 - Mailman is case-perserving, case-insensitive. This @@ -159,7 +159,7 @@ class TestMembership(unittest.TestCase): 'pre_approved': True, }) self.assertEqual(cm.exception.code, 409) - self.assertEqual(cm.exception.reason, b'Member already subscribed') + self.assertEqual(cm.exception.reason, 'Member already subscribed') def test_join_with_invalid_delivery_mode(self): with self.assertRaises(HTTPError) as cm: @@ -171,10 +171,10 @@ class TestMembership(unittest.TestCase): }) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: delivery_mode') + 'Cannot convert parameters: delivery_mode') def test_join_email_contains_slash(self): - content, response = call_api('http://localhost:9001/3.0/members', { + json, response = call_api('http://localhost:9001/3.0/members', { 'list_id': 'test.example.com', 'subscriber': 'hugh/person@example.com', 'display_name': 'Hugh Person', @@ -182,9 +182,9 @@ class TestMembership(unittest.TestCase): 'pre_confirmed': True, 'pre_approved': True, }) - self.assertEqual(content, None) - self.assertEqual(response.status, 201) - self.assertEqual(response['location'], + self.assertEqual(json, None) + self.assertEqual(response.status_code, 201) + self.assertEqual(response.headers['location'], 'http://localhost:9001/3.0/members/1') # Reset any current transaction. config.db.abort() @@ -197,10 +197,10 @@ class TestMembership(unittest.TestCase): anne = self._usermanager.create_user('anne@example.com') set_preferred(anne) self._mlist.subscribe(anne) - content, response = call_api('http://localhost:9001/3.0/members') - self.assertEqual(response.status, 200) - self.assertEqual(int(content['total_size']), 1) - entry_0 = content['entries'][0] + json, response = call_api('http://localhost:9001/3.0/members') + self.assertEqual(response.status_code, 200) + self.assertEqual(int(json['total_size']), 1) + entry_0 = json['entries'][0] self.assertEqual(entry_0['self_link'], 'http://localhost:9001/3.0/members/1') self.assertEqual(entry_0['role'], 'member') @@ -231,7 +231,7 @@ class TestMembership(unittest.TestCase): }) self.assertEqual(cm.exception.code, 409) self.assertEqual(cm.exception.reason, - b'Subscription request already pending') + 'Subscription request already pending') def test_duplicate_other_pending_subscription(self): # Issue #199 - a member's subscription is already pending and they try @@ -255,7 +255,7 @@ class TestMembership(unittest.TestCase): }) self.assertEqual(cm.exception.code, 409) self.assertEqual(cm.exception.reason, - b'Subscription request already pending') + 'Subscription request already pending') def test_member_changes_preferred_address(self): with transaction(): @@ -263,9 +263,9 @@ class TestMembership(unittest.TestCase): set_preferred(anne) self._mlist.subscribe(anne) # Take a look at Anne's current membership. - content, response = call_api('http://localhost:9001/3.0/members') - self.assertEqual(int(content['total_size']), 1) - entry_0 = content['entries'][0] + json, response = call_api('http://localhost:9001/3.0/members') + self.assertEqual(int(json['total_size']), 1) + entry_0 = json['entries'][0] self.assertEqual(entry_0['email'], 'anne@example.com') self.assertEqual( entry_0['address'], @@ -277,9 +277,9 @@ class TestMembership(unittest.TestCase): new_preferred.verified_on = now() anne.preferred_address = new_preferred # Take another look at Anne's current membership. - content, response = call_api('http://localhost:9001/3.0/members') - self.assertEqual(int(content['total_size']), 1) - entry_0 = content['entries'][0] + json, response = call_api('http://localhost:9001/3.0/members') + self.assertEqual(int(json['total_size']), 1) + entry_0 = json['entries'][0] self.assertEqual(entry_0['email'], 'aperson@example.com') self.assertEqual( entry_0['address'], @@ -307,7 +307,7 @@ class TestMembership(unittest.TestCase): 'address': 'bogus@example.com', }, method='PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Address not registered') + self.assertEqual(cm.exception.reason, 'Address not registered') def test_patch_membership_with_unverified_address(self): # Try to change a subscription address to one that is not yet verified. @@ -319,7 +319,7 @@ class TestMembership(unittest.TestCase): 'address': 'anne.person@example.com', }, method='PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Unverified address') + self.assertEqual(cm.exception.reason, 'Unverified address') def test_patch_membership_of_preferred_address(self): # Try to change a subscription to an address when the user is @@ -334,7 +334,7 @@ class TestMembership(unittest.TestCase): }, method='PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Address is not controlled by user') + 'Address is not controlled by user') def test_patch_member_bogus_attribute(self): # /members/<id> PATCH 'bogus' returns 400 @@ -346,7 +346,7 @@ class TestMembership(unittest.TestCase): 'powers': 'super', }, method='PATCH') self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Unexpected parameters: powers') + self.assertEqual(cm.exception.reason, 'Unexpected parameters: powers') def test_member_all_without_preferences(self): # /members/<id>/all should return a 404 when it isn't trailed by @@ -366,7 +366,7 @@ class TestMembership(unittest.TestCase): }, method='PATCH') self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'Cannot convert parameters: moderation_action') + 'Cannot convert parameters: moderation_action') def test_bad_preferences_url(self): with transaction(): @@ -388,10 +388,10 @@ class TestMembership(unittest.TestCase): def test_delete_other_role(self): with transaction(): subscribe(self._mlist, 'Anne', MemberRole.moderator) - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.0/members/1', method='DELETE') - self.assertEqual(headers.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual(len(list(self._mlist.moderators.members)), 0) def test_banned_member_tries_to_join(self): @@ -404,7 +404,7 @@ class TestMembership(unittest.TestCase): 'subscriber': 'anne@example.com', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Membership is banned') + self.assertEqual(cm.exception.reason, 'Membership is banned') def test_globally_banned_member_tries_to_join(self): # A user tries to join a list they are banned from. @@ -416,7 +416,7 @@ class TestMembership(unittest.TestCase): 'subscriber': 'anne@example.com', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Membership is banned') + self.assertEqual(cm.exception.reason, 'Membership is banned') class CustomLayer(ConfigLayer): @@ -475,13 +475,13 @@ Message-ID: <alpha> Some text. """) # Now use the REST API to try to find the nonmember. - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/members/find', { # 'list_id': 'test.example.com', 'role': 'nonmember', }) - self.assertEqual(response['total_size'], 1) - nonmember = response['entries'][0] + self.assertEqual(json['total_size'], 1) + nonmember = json['entries'][0] self.assertEqual(nonmember['role'], 'nonmember') self.assertEqual(nonmember['email'], 'nonmember@example.com') self.assertEqual( @@ -506,13 +506,13 @@ Message-ID: <alpha> Some text. """) # Now use the REST API to try to find the nonmember. - response, content = call_api( + json, response = call_api( 'http://localhost:9001/3.0/members/find', { # 'list_id': 'test.example.com', 'role': 'nonmember', }) - self.assertEqual(response['total_size'], 1) - nonmember = response['entries'][0] + self.assertEqual(json['total_size'], 1) + nonmember = json['entries'][0] self.assertEqual(nonmember['role'], 'nonmember') self.assertEqual(nonmember['email'], 'nonmember@example.com') self.assertEqual( @@ -535,8 +535,8 @@ class TestAPI31Members(unittest.TestCase): with transaction(): subscribe(self._mlist, 'Anne') subscribe(self._mlist, 'Bart') - response, headers = call_api('http://localhost:9001/3.1/members') - entries = response['entries'] + json, response = call_api('http://localhost:9001/3.1/members') + entries = json['entries'] self.assertEqual(len(entries), 2) self.assertEqual( entries[0]['self_link'], @@ -560,37 +560,38 @@ class TestAPI31Members(unittest.TestCase): def test_get_member_id_by_hex(self): with transaction(): subscribe(self._mlist, 'Anne') - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/members/00000000000000000000000000000001') self.assertEqual( - response['member_id'], + json['member_id'], '00000000000000000000000000000001') self.assertEqual( - response['self_link'], + json['self_link'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001') self.assertEqual( - response['user'], + json['user'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') self.assertEqual( - response['address'], + json['address'], 'http://localhost:9001/3.1/addresses/aperson@example.com') def test_get_list_member_id_by_email(self): with transaction(): subscribe(self._mlist, 'Anne', email="aperson@example.com") - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/lists/ant.example.com/member' '/aperson@example.com') - self.assertEqual(response['member_id'], - '00000000000000000000000000000001') self.assertEqual( - response['self_link'], + json['member_id'], + '00000000000000000000000000000001') + self.assertEqual( + json['self_link'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001') self.assertEqual( - response['user'], + json['user'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') self.assertEqual( - response['address'], + json['address'], 'http://localhost:9001/3.1/addresses/aperson@example.com') def test_cannot_get_member_id_by_int(self): @@ -604,26 +605,26 @@ class TestAPI31Members(unittest.TestCase): with transaction(): member = subscribe(self._mlist, 'Anne') member.preferences.delivery_mode = DeliveryMode.summary_digests - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/members' '/00000000000000000000000000000001/preferences') - self.assertEqual(response['delivery_mode'], 'summary_digests') + self.assertEqual(json['delivery_mode'], 'summary_digests') def test_all_preferences(self): with transaction(): member = subscribe(self._mlist, 'Anne') member.preferences.delivery_mode = DeliveryMode.summary_digests - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/members' '/00000000000000000000000000000001/all/preferences') - self.assertEqual(response['delivery_mode'], 'summary_digests') + self.assertEqual(json['delivery_mode'], 'summary_digests') def test_create_new_membership_by_hex(self): with transaction(): user = getUtility(IUserManager).create_user('anne@example.com') set_preferred(user) # Subscribe the user to the mailing list by hex UUID. - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/members', { 'list_id': 'ant.example.com', 'subscriber': '00000000000000000000000000000001', @@ -631,9 +632,9 @@ class TestAPI31Members(unittest.TestCase): 'pre_confirmed': True, 'pre_approved': True, }) - self.assertEqual(headers.status, 201) + self.assertEqual(response.status_code, 201) self.assertEqual( - headers['location'], + response.headers['location'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001' ) @@ -642,15 +643,15 @@ class TestAPI31Members(unittest.TestCase): user = getUtility(IUserManager).create_user('anne@example.com') set_preferred(user) # Subscribe the user to the mailing list by hex UUID. - response, headers = call_api( + json, response = call_api( 'http://localhost:9001/3.1/members', { 'list_id': 'ant.example.com', 'subscriber': '00000000000000000000000000000001', 'role': 'owner', }) - self.assertEqual(headers.status, 201) + self.assertEqual(response.status_code, 201) self.assertEqual( - headers['location'], + response.headers['location'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001' ) @@ -686,4 +687,4 @@ class TestAPI31Members(unittest.TestCase): self.assertEqual(cm.exception.code, 400) self.assertEqual( cm.exception.reason, - b'anne@example.com is already an owner of ant@example.com') + 'anne@example.com is already an owner of ant@example.com') diff --git a/src/mailman/rest/tests/test_moderation.py b/src/mailman/rest/tests/test_moderation.py index 3d3b234c7..0a9bb2608 100644 --- a/src/mailman/rest/tests/test_moderation.py +++ b/src/mailman/rest/tests/test_moderation.py @@ -96,7 +96,7 @@ Something else. call_api(url.format(held_id), {'action': 'bogus'}) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.msg, - b'Cannot convert parameters: action') + 'Cannot convert parameters: action') def test_discard(self): # Discarding a message removes it from the moderation queue. @@ -104,8 +104,8 @@ Something else. held_id = hold_message(self._mlist, self._msg) url = 'http://localhost:9001/3.0/lists/ant@example.com/held/{}'.format( held_id) - content, response = call_api(url, dict(action='discard')) - self.assertEqual(response.status, 204) + json, response = call_api(url, dict(action='discard')) + self.assertEqual(response.status_code, 204) # Now it's gone. with self.assertRaises(HTTPError) as cm: call_api(url, dict(action='discard')) @@ -115,11 +115,11 @@ Something else. # We can view all the held requests. with transaction(): held_id = hold_message(self._mlist, self._msg) - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/held') - self.assertEqual(response.status, 200) - self.assertEqual(content['total_size'], 1) - self.assertEqual(content['entries'][0]['request_id'], held_id) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['total_size'], 1) + self.assertEqual(json['entries'][0]['request_id'], held_id) def test_cant_get_other_lists_holds(self): # Issue #161: It was possible to moderate a held message for another @@ -187,7 +187,7 @@ class TestSubscriptionModeration(unittest.TestCase): )) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.msg, - b'Cannot convert parameters: action') + 'Cannot convert parameters: action') def test_list_held_requests(self): # We can view all the held requests. @@ -199,13 +199,13 @@ class TestSubscriptionModeration(unittest.TestCase): token_2, token_owner, member = self._registrar.register(self._bart) self.assertIsNotNone(token_2) self.assertIsNone(member) - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/requests') - self.assertEqual(response.status, 200) - self.assertEqual(content['total_size'], 2) - tokens = set(json['token'] for json in content['entries']) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['total_size'], 2) + tokens = set(entry['token'] for entry in json['entries']) self.assertEqual(tokens, {token_1, token_2}) - emails = set(json['email'] for json in content['entries']) + emails = set(entry['email'] for entry in json['entries']) self.assertEqual(emails, {'anne@example.com', 'bart@example.com'}) def test_view_malformed_held_message(self): @@ -219,11 +219,11 @@ class TestSubscriptionModeration(unittest.TestCase): hold_message(self._mlist, msg) # Now trying to access held messages from REST API should not give # 500 server error if one of the messages can't be parsed properly. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/held') - self.assertEqual(response.status, 200) - self.assertEqual(len(content['entries']), 1) - self.assertEqual(content['entries'][0]['msg'], + self.assertEqual(response.status_code, 200) + self.assertEqual(len(json['entries']), 1) + self.assertEqual(json['entries'][0]['msg'], 'This message is defective') def test_individual_request(self): @@ -234,11 +234,11 @@ class TestSubscriptionModeration(unittest.TestCase): self.assertIsNotNone(token) self.assertIsNone(member) url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token)) - self.assertEqual(response.status, 200) - self.assertEqual(content['token'], token) - self.assertEqual(content['token_owner'], token_owner.name) - self.assertEqual(content['email'], 'anne@example.com') + json, response = call_api(url.format(token)) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['token'], token) + self.assertEqual(json['token_owner'], token_owner.name) + self.assertEqual(json['email'], 'anne@example.com') def test_accept(self): # POST to the request to accept it. @@ -247,10 +247,10 @@ class TestSubscriptionModeration(unittest.TestCase): # Anne's subscription request got held. self.assertIsNone(member) url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='accept', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is a member. self.assertEqual( self._mlist.members.get_member('anne@example.com').address, @@ -275,7 +275,7 @@ class TestSubscriptionModeration(unittest.TestCase): action='accept', )) self.assertEqual(cm.exception.code, 409) - self.assertEqual(cm.exception.reason, b'Already subscribed') + self.assertEqual(cm.exception.reason, 'Already subscribed') def test_accept_bad_token(self): # Try to accept a request with a bogus token. @@ -290,9 +290,9 @@ class TestSubscriptionModeration(unittest.TestCase): # more requests to handle. # # We start with nothing in the queue. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/requests') - self.assertEqual(content['total_size'], 0) + self.assertEqual(json['total_size'], 0) # Anne tries to subscribe to a list that only requests moderator # approval. with transaction(): @@ -302,20 +302,20 @@ class TestSubscriptionModeration(unittest.TestCase): pre_verified=True, pre_confirmed=True) # There's now one request in the queue, and it's waiting on moderator # approval. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/requests') - self.assertEqual(content['total_size'], 1) - json = content['entries'][0] - self.assertEqual(json['token_owner'], 'moderator') - self.assertEqual(json['email'], 'anne@example.com') + self.assertEqual(json['total_size'], 1) + entry = json['entries'][0] + self.assertEqual(entry['token_owner'], 'moderator') + self.assertEqual(entry['email'], 'anne@example.com') # The moderator approves the request. url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), {'action': 'accept'}) - self.assertEqual(response.status, 204) + json, response = call_api(url.format(token), {'action': 'accept'}) + self.assertEqual(response.status_code, 204) # And now the request queue is empty. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/lists/ant@example.com/requests') - self.assertEqual(content['total_size'], 0) + self.assertEqual(json['total_size'], 0) def test_discard(self): # POST to the request to discard it. @@ -324,10 +324,10 @@ class TestSubscriptionModeration(unittest.TestCase): # Anne's subscription request got held. self.assertIsNone(member) url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='discard', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is not a member. self.assertIsNone(self._mlist.members.get_member('anne@example.com')) # The request URL no longer exists. @@ -344,22 +344,22 @@ class TestSubscriptionModeration(unittest.TestCase): # Anne's subscription request got held. self.assertIsNone(member) url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='defer', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is not a member. self.assertIsNone(self._mlist.members.get_member('anne@example.com')) # The request URL still exists. - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='defer', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # And now we can accept it. - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='accept', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is a member. self.assertEqual( self._mlist.members.get_member('anne@example.com').address, @@ -390,10 +390,10 @@ class TestSubscriptionModeration(unittest.TestCase): # confirmation message sent to Anne. get_queue_messages('virgin') url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='reject', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is not a member. self.assertIsNone(self._mlist.members.get_member('anne@example.com')) # The request URL no longer exists. @@ -429,17 +429,17 @@ class TestSubscriptionModeration(unittest.TestCase): # confirmation message sent to Anne. get_queue_messages('virgin') url = 'http://localhost:9001/3.0/lists/ant@example.com/requests/{}' - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='hold', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Anne is not a member. self.assertIsNone(self._mlist.members.get_member('anne@example.com')) # The request URL still exists. - content, response = call_api(url.format(token), dict( + json, response = call_api(url.format(token), dict( action='defer', )) - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) def test_subscribe_other_role_with_no_preferred_address(self): with transaction(): @@ -451,8 +451,7 @@ class TestSubscriptionModeration(unittest.TestCase): 'role': 'moderator', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, - b'User without preferred address') + self.assertEqual(cm.exception.reason, 'User without preferred address') def test_subscribe_other_role_banned_email_address(self): bans = IBanManager(self._mlist) @@ -465,4 +464,4 @@ class TestSubscriptionModeration(unittest.TestCase): 'role': 'moderator', }) self.assertEqual(cm.exception.code, 400) - self.assertEqual(cm.exception.reason, b'Membership is banned') + self.assertEqual(cm.exception.reason, 'Membership is banned') diff --git a/src/mailman/rest/tests/test_queues.py b/src/mailman/rest/tests/test_queues.py index 7a5a7e134..b6668bdff 100644 --- a/src/mailman/rest/tests/test_queues.py +++ b/src/mailman/rest/tests/test_queues.py @@ -65,8 +65,8 @@ class TestQueues(unittest.TestCase): content, response = call_api('http://localhost:9001/3.0/queues/bad', { 'list_id': 'test.example.com', 'text': TEXT}) - self.assertEqual(response.status, 201) - location = response['location'] + self.assertEqual(response.status_code, 201) + location = response.headers['location'] filebase = location.split('/')[-1] # The message is in the 'bad' queue. content, response = call_api('http://localhost:9001/3.0/queues/bad') @@ -94,9 +94,9 @@ class TestQueues(unittest.TestCase): content, response = call_api('http://localhost:9001/3.0/queues/bad', { 'list_id': 'test.example.com', 'text': TEXT}) - location = response['location'] + location = response.headers['location'] self.assertEqual(len(config.switchboards['bad'].files), 1) # Delete the file through REST. content, response = call_api(location, method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertEqual(len(config.switchboards['bad'].files), 0) diff --git a/src/mailman/rest/tests/test_root.py b/src/mailman/rest/tests/test_root.py index dd6808efc..cb16caeeb 100644 --- a/src/mailman/rest/tests/test_root.py +++ b/src/mailman/rest/tests/test_root.py @@ -18,11 +18,9 @@ """REST root object tests.""" import os -import json +import requests import unittest -from base64 import b64encode -from httplib2 import Http from mailman.config import config from mailman.core.system import system from mailman.database.transaction import transaction @@ -94,32 +92,21 @@ class TestRoot(unittest.TestCase): def test_no_basic_auth(self): # If Basic Auth credentials are missing, it is a 401 error. - url = 'http://localhost:9001/3.0/system' - headers = { - 'Content-Type': 'application/x-www-form-urlencode', - } - response, raw_content = Http().request(url, 'GET', None, headers) - self.assertEqual(response.status, 401) - content = json.loads(raw_content.decode('utf-8')) - self.assertEqual(content['title'], '401 Unauthorized') - self.assertEqual(content['description'], - 'REST API authorization failed') + response = requests.get('http://localhost:9001/3.0/system') + self.assertEqual(response.status_code, 401) + json = response.json() + self.assertEqual(json['title'], '401 Unauthorized') + self.assertEqual(json['description'], 'REST API authorization failed') def test_unauthorized(self): # Bad Basic Auth credentials results in a 401 error. - userpass = b64encode(b'baduser:badpass') - auth = 'Basic {}'.format(userpass.decode('ascii')) - url = 'http://localhost:9001/3.0/system' - headers = { - 'Content-Type': 'application/x-www-form-urlencode', - 'Authorization': auth, - } - response, raw_content = Http().request(url, 'GET', None, headers) - self.assertEqual(response.status, 401) - content = json.loads(raw_content.decode('utf-8')) - self.assertEqual(content['title'], '401 Unauthorized') - self.assertEqual(content['description'], - 'REST API authorization failed') + response = requests.get( + 'http://localhost:9001/3.0/system', + auth=('baduser', 'badpass')) + self.assertEqual(response.status_code, 401) + json = response.json() + self.assertEqual(json['title'], '401 Unauthorized') + self.assertEqual(json['description'], 'REST API authorization failed') def test_reserved_bad_subpath(self): # Only <api>/reserved/uids/orphans is a defined resource. DELETEing @@ -203,15 +190,15 @@ class TestSiteTemplates(unittest.TestCase): 'http://example.com/goodbye', 'a user', 'the password', ) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris') - self.assertEqual(response.status, 200) - self.assertEqual(resource['start'], 0) - self.assertEqual(resource['total_size'], 2) + self.assertEqual(response.status_code, 200) + self.assertEqual(json['start'], 0) + self.assertEqual(json['total_size'], 2) self.assertEqual( - resource['self_link'], + json['self_link'], 'http://localhost:9001/3.1/uris') - self.assertEqual(resource['entries'], [ + self.assertEqual(json['entries'], [ {'http_etag': '"063fd6635a6035a4b7e939a304fcbd16571aa662"', 'name': 'list:user:notice:goodbye', 'password': 'the password', @@ -228,12 +215,12 @@ class TestSiteTemplates(unittest.TestCase): }]) def test_patch_uris(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris', { 'list:user:notice:welcome': 'http://example.org/welcome', 'list:user:notice:goodbye': 'http://example.org/goodbye', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', None) self.assertEqual(template.uri, 'http://example.org/welcome') @@ -245,14 +232,14 @@ class TestSiteTemplates(unittest.TestCase): self.assertEqual(template.password, '') def test_patch_uris_with_credentials(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris', { 'list:user:notice:welcome': 'http://example.org/welcome', 'list:user:notice:goodbye': 'http://example.org/goodbye', 'password': 'some password', 'username': 'anne.person', }, method='PATCH') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:user:notice:welcome', None) self.assertEqual(template.uri, 'http://example.org/welcome') @@ -274,7 +261,7 @@ class TestSiteTemplates(unittest.TestCase): self.assertEqual(cm.exception.code, 400) def test_put_all_uris(self): - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris', { 'domain:admin:notice:new-list': '', 'list:admin:action:post': '', @@ -300,7 +287,7 @@ class TestSiteTemplates(unittest.TestCase): 'password': 'some password', 'username': 'anne.person', }, method='PUT') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) manager = getUtility(ITemplateManager) template = manager.raw('list:member:digest:footer', None) self.assertIsNone(template) @@ -334,10 +321,10 @@ class TestSiteTemplates(unittest.TestCase): 'http://example.com/goodbye', 'a user', 'the password', ) - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) self.assertIsNone(manager.raw('list:user:notice:welcome', None)) self.assertIsNone(manager.raw('list:user:notice:goodbye', None)) @@ -346,10 +333,10 @@ class TestSiteTemplates(unittest.TestCase): getUtility(ITemplateManager).set( 'list:user:notice:welcome', None, 'http://example.com/welcome') - resource, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/uris/list:user:notice:welcome') - self.assertEqual(response.status, 200) - self.assertEqual(resource, { + self.assertEqual(response.status_code, 200) + self.assertEqual(json, { 'http_etag': '"86e360d83197561d50826ad6d15e9c30923b82d6"', 'self_link': ('http://localhost:9001/3.1' '/uris/list:user:notice:welcome'), diff --git a/src/mailman/rest/tests/test_uids.py b/src/mailman/rest/tests/test_uids.py index 79f5b73b3..c2a4fcf1c 100644 --- a/src/mailman/rest/tests/test_uids.py +++ b/src/mailman/rest/tests/test_uids.py @@ -64,7 +64,7 @@ class TestUIDs(unittest.TestCase): content, response = call_api( 'http://localhost:9001/3.0/reserved/uids/orphans', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Now there are no uids in the table. config.db.abort() self.assertEqual(UID.get_total_uid_count(), 0) diff --git a/src/mailman/rest/tests/test_users.py b/src/mailman/rest/tests/test_users.py index 60d748a6f..97f4b76d2 100644 --- a/src/mailman/rest/tests/test_users.py +++ b/src/mailman/rest/tests/test_users.py @@ -104,10 +104,10 @@ class TestUsers(unittest.TestCase): anne = getUtility(IUserManager).create_user( 'anne@example.com', 'Anne Person') user_id = anne.user_id - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) with self.assertRaises(HTTPError) as cm: call_api('http://localhost:9001/3.0/users/anne@example.com', method='DELETE') @@ -124,14 +124,14 @@ class TestUsers(unittest.TestCase): 'anne@example.com', 'Anne Person') user_id = anne.user_id # You can still GET the user record. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com') - self.assertEqual(response.status, 200) + self.assertEqual(response.status_code, 200) # Delete the user. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # The user record can no longer be retrieved. with self.assertRaises(HTTPError) as cm: call_api('http://localhost:9001/3.0/users/anne@example.com') @@ -152,7 +152,7 @@ class TestUsers(unittest.TestCase): }) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'User already exists: anne@example.com') + 'User already exists: anne@example.com') def test_addresses_of_missing_user_id(self): # Trying to get the /addresses of a missing user id results in error. @@ -218,29 +218,29 @@ class TestUsers(unittest.TestCase): def test_create_user_twice(self): # LP: #1418280. No additional users should be created when an address # that already exists is given. - content, response = call_api('http://localhost:9001/3.0/users') - self.assertEqual(content['total_size'], 0) + json, response = call_api('http://localhost:9001/3.0/users') + self.assertEqual(json['total_size'], 0) # Create the user. call_api('http://localhost:9001/3.0/users', dict( email='anne@example.com')) # There is now one user. - content, response = call_api('http://localhost:9001/3.0/users') - self.assertEqual(content['total_size'], 1) + json, response = call_api('http://localhost:9001/3.0/users') + self.assertEqual(json['total_size'], 1) # Trying to create the user with the same address results in an error. with self.assertRaises(HTTPError) as cm: call_api('http://localhost:9001/3.0/users', dict( email='anne@example.com')) self.assertEqual(cm.exception.code, 400) self.assertEqual(cm.exception.reason, - b'User already exists: anne@example.com') + 'User already exists: anne@example.com') # But at least no new users was created. - content, response = call_api('http://localhost:9001/3.0/users') - self.assertEqual(content['total_size'], 1) + json, response = call_api('http://localhost:9001/3.0/users') + self.assertEqual(json['total_size'], 1) def test_create_server_owner_false(self): # Issue #136: Creating a user with is_server_owner=no should create # user who is not a server owner. - content, response = call_api('http://localhost:9001/3.0/users', dict( + json, response = call_api('http://localhost:9001/3.0/users', dict( email='anne@example.com', is_server_owner='no')) anne = getUtility(IUserManager).get_user('anne@example.com') @@ -249,7 +249,7 @@ class TestUsers(unittest.TestCase): def test_create_server_owner_true(self): # Issue #136: Creating a user with is_server_owner=yes should create a # new server owner user. - content, response = call_api('http://localhost:9001/3.0/users', dict( + json, response = call_api('http://localhost:9001/3.0/users', dict( email='anne@example.com', is_server_owner='yes')) anne = getUtility(IUserManager).get_user('anne@example.com') @@ -274,10 +274,10 @@ class TestUsers(unittest.TestCase): id=anne.preferences.id) self.assertEqual(preferences.count(), 1) # Delete the user via REST. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # The user's preference has been deleted. with transaction(): preferences = config.db.store.query(Preferences).filter_by( @@ -288,10 +288,10 @@ class TestUsers(unittest.TestCase): with transaction(): user = getUtility(IUserManager).create_user('anne@example.com') user.preferences.delivery_mode = DeliveryMode.summary_digests - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/1/preferences') self.assertEqual( - content['self_link'], + json['self_link'], 'http://localhost:9001/3.0/users/1/preferences') @@ -309,11 +309,11 @@ class TestLogin(unittest.TestCase): def test_login_with_cleartext_password(self): # A user can log in with the correct clear text password. - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com/login', { 'cleartext_password': 'abc123', }, method='POST') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # But the user cannot log in with an incorrect password. with self.assertRaises(HTTPError) as cm: call_api( @@ -420,14 +420,14 @@ class TestLP1074374(unittest.TestCase): self.mlist.subscribe(address) call_api('http://localhost:9001/3.0/users/anne@example.com', method='DELETE') - content, response = call_api('http://localhost:9001/3.0/addresses') + json, response = call_api('http://localhost:9001/3.0/addresses') # There are no addresses, and thus no entries in the returned JSON. - self.assertNotIn('entries', content) - self.assertEqual(content['total_size'], 0) + self.assertNotIn('entries', json) + self.assertEqual(json['total_size'], 0) # There are also no members. - content, response = call_api('http://localhost:9001/3.0/members') - self.assertNotIn('entries', content) - self.assertEqual(content['total_size'], 0) + json, response = call_api('http://localhost:9001/3.0/members') + self.assertNotIn('entries', json) + self.assertEqual(json['total_size'], 0) # Now we can create a new user record for Anne, and subscribe her to # the mailing list, this time all through the API. call_api('http://localhost:9001/3.0/users', dict( @@ -440,17 +440,17 @@ class TestLP1074374(unittest.TestCase): pre_verified=True, pre_confirmed=True, pre_approved=True)) # This is not the Anne you're looking for. (IOW, the new Anne is a # different user). - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com') - self.assertNotEqual(user_id, content['user_id']) + self.assertNotEqual(user_id, json['user_id']) # Anne has an address record. - content, response = call_api('http://localhost:9001/3.0/addresses') - self.assertEqual(content['total_size'], 1) - self.assertEqual(content['entries'][0]['email'], 'anne@example.com') + json, response = call_api('http://localhost:9001/3.0/addresses') + self.assertEqual(json['total_size'], 1) + self.assertEqual(json['entries'][0]['email'], 'anne@example.com') # Anne is also a member of the mailing list. - content, response = call_api('http://localhost:9001/3.0/members') - self.assertEqual(content['total_size'], 1) - member = content['entries'][0] + json, response = call_api('http://localhost:9001/3.0/members') + self.assertEqual(json['total_size'], 1) + member = json['entries'][0] self.assertEqual( member['address'], 'http://localhost:9001/3.0/addresses/anne@example.com') @@ -493,10 +493,10 @@ class TestLP1419519(unittest.TestCase): 'a09@example.com', 'anne@example.com', ]) - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.0/users/anne@example.com', method='DELETE') - self.assertEqual(response.status, 204) + self.assertEqual(response.status_code, 204) # Now there should be no addresses in the database. config.db.abort() emails = sorted(address.email for address in self.manager.addresses) @@ -511,12 +511,12 @@ class TestAPI31Users(unittest.TestCase): def test_get_user(self): with transaction(): getUtility(IUserManager).create_user('anne@example.com') - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/users/00000000000000000000000000000001') self.assertEqual( - content['user_id'], '00000000000000000000000000000001') + json['user_id'], '00000000000000000000000000000001') self.assertEqual( - content['self_link'], + json['self_link'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') def test_cannot_get_user_by_int(self): @@ -531,8 +531,8 @@ class TestAPI31Users(unittest.TestCase): with transaction(): user_manager.create_user('anne@example.com') user_manager.create_user('bart@example.com') - content, response = call_api('http://localhost:9001/3.1/users') - entries = content['entries'] + json, response = call_api('http://localhost:9001/3.1/users') + entries = json['entries'] self.assertEqual(len(entries), 2) self.assertEqual( entries[0]['user_id'], '00000000000000000000000000000001') @@ -546,23 +546,23 @@ class TestAPI31Users(unittest.TestCase): 'http://localhost:9001/3.1/users/00000000000000000000000000000002') def test_create_user(self): - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/users', { 'email': 'anne@example.com', }) - self.assertEqual(response.status, 201) + self.assertEqual(response.status_code, 201) self.assertEqual( - response['location'], + response.headers['location'], 'http://localhost:9001/3.1/users/00000000000000000000000000000001') def test_preferences_self_link(self): with transaction(): user = getUtility(IUserManager).create_user('anne@example.com') user.preferences.delivery_mode = DeliveryMode.summary_digests - content, response = call_api( + json, response = call_api( 'http://localhost:9001/3.1/users' '/00000000000000000000000000000001/preferences') self.assertEqual( - content['self_link'], + json['self_link'], 'http://localhost:9001/3.1/users' '/00000000000000000000000000000001/preferences') diff --git a/src/mailman/runners/tests/test_rest.py b/src/mailman/runners/tests/test_rest.py index 4bd71d990..470ede240 100644 --- a/src/mailman/runners/tests/test_rest.py +++ b/src/mailman/runners/tests/test_rest.py @@ -38,6 +38,7 @@ class TestRESTRunner(unittest.TestCase): wait_for_webservice() # This should not raise an exception. The best way to assert this is # to ensure that the response is valid. - response, json = call_api('http://localhost:9001/3.0/system') - self.assertEqual(json['content-location'], - 'http://localhost:9001/3.0/system') + json, response = call_api('http://localhost:9001/3.0/system/versions') + self.assertEqual( + json['self_link'], + 'http://localhost:9001/3.0/system/versions') diff --git a/src/mailman/testing/documentation.py b/src/mailman/testing/documentation.py index 33678a7d0..fc75e7a93 100644 --- a/src/mailman/testing/documentation.py +++ b/src/mailman/testing/documentation.py @@ -92,8 +92,17 @@ def call_http(url, data=None, method=None, username=None, password=None): """ content, response = call_api(url, data, method, username, password) if content is None: - for header in sorted(response): - print('{}: {}'.format(header, response[header])) + # We used to use httplib2 here, which included the status code in the + # response headers in the `status` key. requests doesn't do this, but + # the doctests expect it so for backward compatibility, include the + # status code in the printed response. + headers = dict(status=response.status_code) + headers.update({ + field.lower(): response.headers[field] + for field in response.headers + }) + for field in sorted(headers): + print('{}: {}'.format(field, headers[field])) return None return content diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index 53a985298..af844d214 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -19,7 +19,6 @@ import os import sys -import json import time import uuid import shutil @@ -30,10 +29,8 @@ import smtplib import datetime import threading -from base64 import b64encode from contextlib import contextmanager, suppress from email import message_from_string -from httplib2 import Http from lazr.config import as_timedelta from mailman.bin.master import Loop as Master from mailman.config import config @@ -46,9 +43,9 @@ from mailman.interfaces.usermanager import IUserManager from mailman.runners.digest import DigestRunner from mailman.utilities.mailbox import Mailbox from public import public +from requests import request from unittest import mock from urllib.error import HTTPError -from urllib.parse import urlencode from zope import event from zope.component import getUtility @@ -295,35 +292,24 @@ def call_api(url, data=None, method=None, username=None, password=None): :rtype: 2-tuple of (dict, response) :raises HTTPError: when a non-2xx return code is received. """ - headers = {} - if data is not None: - data = urlencode(data, doseq=True) - headers['Content-Type'] = 'application/x-www-form-urlencoded' if method is None: if data is None: method = 'GET' else: method = 'POST' method = method.upper() - if method in ('POST', 'PUT', 'PATCH') and data is None: - data = urlencode({}, doseq=True) - basic_auth = '{0}:{1}'.format( + basic_auth = ( (config.webservice.admin_user if username is None else username), (config.webservice.admin_pass if password is None else password)) - # b64encode() requires a bytes, but the header value must be str. Do the - # necessary conversion dances. - token = b64encode(basic_auth.encode('utf-8')).decode('ascii') - headers['Authorization'] = 'Basic ' + token - response, content = Http().request(url, method, data, headers) - # If we did not get a 2xx status code, make this look like a urllib2 - # exception, for backward compatibility with existing doctests. - if response.status // 100 != 2: - raise HTTPError(url, response.status, content, response, None) - if len(content) == 0: + response = request(method, url, data=data, auth=basic_auth) + # For backward compatibility with existing doctests, turn non-2xx response + # codes into a urllib.error exceptions. + if response.status_code // 100 != 2: + raise HTTPError( + url, response.status_code, response.text, response, None) + if len(response.content) == 0: return None, response - # XXX Workaround http://bugs.python.org/issue10038 - content = content.decode('utf-8') - return json.loads(content), response + return response.json(), response @public |
