def test_base_api_uri_used_instead_of_default(self): # Requests to the default BASE_API_URI will noticeably fail by raising an # AssertionError. Requests to the new URL will respond HTTP 200. new_base_api_uri = 'http://example.com/api/v1/' # If any error is raised by the server, the test suite will never exit when # using Python 3. This strange technique is used to raise the errors # outside of the mocked server environment. errors_in_server = [] def server_response(request, uri, headers): try: self.assertEqual(uri, new_base_api_uri) except AssertionError as e: errors_in_server.append(e) return (200, headers, "") hp.register_uri(hp.GET, Client.BASE_API_URI, body=server_response) hp.register_uri(hp.GET, new_base_api_uri, body=server_response) client2 = Client(api_key, api_secret, new_base_api_uri) self.assertEqual(client2._get().status_code, 200) client = Client(api_key, api_secret) with self.assertRaises(AssertionError): client._get() if errors_in_server: raise errors_in_server.pop()
def test_auth_succeeds_with_bytes_and_unicode(self): api_key = 'key' api_secret = 'secret' self.assertIsInstance(api_key, six.text_type) # Unicode self.assertIsInstance(api_secret, six.text_type) # Unicode client = Client(api_key, api_secret) self.assertEqual(client._get('test').status_code, 200) api_key = api_key.encode('utf-8') api_secret = api_secret.encode('utf-8') self.assertIsInstance(api_key, six.binary_type) # Bytes self.assertIsInstance(api_secret, six.binary_type) # Bytes client = Client(api_key, api_secret) self.assertEqual(client._get('test').status_code, 200)
def test_response_handling(self): client = Client(api_key, api_secret) # Check that 2XX responses always return the response error_response = { 'errors': [{ 'id': 'fakeid', 'message': 'some error message', }], 'data': mock_item, } error_str = json.dumps(error_response) for code in [200, 201, 204]: hp.register_uri(hp.GET, re.compile('.*' + str(code) + '$'), lambda r, u, h: (code, h, error_str)) response = client._get(str(code)) self.assertEqual(response.status_code, code) # Check that when the error data is in the response, that's what is used. import pycoinbase.wallet.error for eid, eclass in six.iteritems( pycoinbase.wallet.error._error_id_to_class): error_response = { 'errors': [{ 'id': eid, 'message': 'some message', }], 'data': mock_item, } error_str = json.dumps(error_response) hp.reset() hp.register_uri(hp.GET, re.compile('.*test$'), lambda r, u, h: (400, h, error_str)) with self.assertRaises(eclass): client._get('test') # Check that when the error data is missing, the status code is used # instead. error_response = {'data': mock_item} for code, eclass in six.iteritems( pycoinbase.wallet.error._status_code_to_class): hp.reset() hp.register_uri( hp.GET, re.compile('.*test$'), lambda r, u, h: (code, h, json.dumps(error_response))) with self.assertRaises(eclass): client._get('test') # Check that when the response code / error id is unrecognized, a generic # APIError is returned hp.reset() hp.register_uri(hp.GET, re.compile('.*test$'), lambda r, u, h: (418, h, '{}')) with self.assertRaises(APIError): client._get('test')
def test_request_includes_auth_headers(self): client = Client(api_key, api_secret) def server_response(request, uri, response_headers): keys = [ 'CB-VERSION', 'CB-ACCESS-KEY', 'CB-ACCESS-SIGN', 'CB-ACCESS-TIMESTAMP', 'Accept', 'Content-Type', 'User-Agent' ] for key in keys: self.assertIn(key, request.headers) self.assertNotEqual(request.headers[key], '') return 200, response_headers, '{}' hp.register_uri(hp.GET, re.compile('.*test$'), server_response) self.assertEqual(client._get('test').status_code, 200)