# Path: pypd/mixins.py
# class ClientMixin(object):
#     api_key = None
#     base_url = None
#     proxies = None
# 
#     def __init__(self, api_key=None, base_url=None, proxies=None):
#         # if no api key is provided try to get one from the packages api_key
#         if api_key:
#             self.api_key = api_key
# 
#         if self.api_key is None:
#             from pypd import api_key
#             self.api_key = api_key
# 
#         if base_url:
#             self.base_url = base_url
# 
#         if self.base_url is None:
#             from pypd import base_url
#             self.base_url = base_url
# 
#         if not proxies:
#             from pypd import proxies
# 
#         self.proxies = proxies
# 
#     def _handle_response(self, response):
#         if response.status_code == 404:
#             response.raise_for_status()
#         elif response.status_code // 100 == 4:
#             raise BadRequest(response.status_code, response.text)
#         elif response.status_code // 100 != 2:
#             raise UnknownError(response.status_code, response.text)
# 
#         if not response.text:
#             return None
# 
#         try:
#             response = response.json()
#         except:
#             raise InvalidResponse(response.text)
# 
#         return response
# 
#     def _do_request(self, method, *args, **kwargs):
#         """
#         Modularized because API was broken.
# 
#         Need to be able to inject Mocked response objects here.
#         """
#         log('Doing HTTP [{3}] request: {0} - headers: {1} - payload: {2}'.format(
#             args[0], kwargs.get('headers'), kwargs.get('json'), method,),
#             level=logging.DEBUG,)
#         requests_method = getattr(requests, method)
#         return self._handle_response(requests_method(*args, **kwargs))
# 
#     def request(self, method='GET', endpoint='', query_params=None,
#                 data=None, add_headers=None, headers=None,):
#         auth = 'Token token={0}'.format(self.api_key)
#         if query_params is None:
#             query_params = {}
# 
#         if headers is None:
#             headers = {
#                 'Accept': CONTENT_TYPE,
#                 'Authorization': auth,
#                 'Content-Type': 'application/json',
#             }
#         elif not isinstance(headers, dict):
#             raise InvalidHeaders(headers)
# 
#         if add_headers is not None:
#             headers.update(**add_headers)
# 
#         for k, v in query_params.copy().items():
#             if isinstance(v, six.string_types):
#                 continue
#             elif isinstance(v, Number):
#                 continue
#             elif isinstance(v, datetime.datetime):
#                 query_params[k] = v.isoformat()
#             elif isinstance(v, ClientMixin):
#                 query_params[k] = v['id']
#             try:
#                 iter(v)
#             except:
#                 continue
#             key = '%s[]' % k
#             query_params.pop(k)
#             values = [v_['id'] if isinstance(v_, ClientMixin) else v_
#                       for v_ in v]
#             query_params[key] = values
# 
#         kwargs = {
#             'headers': headers,
#             'params': query_params,
#             'proxies': self.proxies,
#         }
# 
#         if data is not None:
#             kwargs['json'] = data
# 
#         return self._do_request(
#             method.lower(),
#             '/'.join((self.base_url, endpoint)),
#             **kwargs
#         )
# 
# Path: pypd/errors.py
# class BadRequest(Error):
#     def __init__(self, code=400, message='', *args, **kwargs):
#         self.code = code
#         self.message = message
#         self.errors = []
# 
#         Error.__init__(self, *args, **kwargs)
# 
#         try:
#             obj = json.loads(message)['error']
#             self.code = obj.get('code', code)
#             self.message = obj.get('message', message)
#             self.errors = obj.get('errors', [])
#         except:
#             pass
# 
#     def __str__(self):
#         error = '{0} ({1}): {2}'.format(self.__class__.__name__, self.code,
#                                         self.message)
#         if self.errors:
#             addon = self.errors[0] if len(self.errors) == 1 else self.errors
#             error = '{0} - {1}'.format(error, addon)
# 
#         return error
# 
# class UnknownError(Error):
#     def __init__(self, code, url, message=''):
#         self.code = code
#         self.url = url
#         self.message = message
# 
#     def __str__(self):
#         return '{0} ({1}): {2}'.format(self.__class__.__name__, self.code,
#                                        self.message)
# 
# class InvalidResponse(Error):
#     """A server response was pure nonsense."""
# 
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return 'InvalidResponse: {0}'.format(self.data)
# 
# class InvalidHeaders(Error):
#     def __init__(self, headers):
#         self.headers = headers
#         self.message = "Request received an invalid headers object, %r".format(
#             headers,
#         )


import unittest
import requests_mock
from requests import HTTPError
from pypd.mixins import ClientMixin
from pypd.errors import (BadRequest, UnknownError, InvalidResponse,
                         InvalidHeaders)

    def test_request_5xx(self, m):
        method = 'GET'
        m.register_uri(method, self.url, status_code=500)

        self.assertRaises(
            UnknownError,
            self.requester.request, method, self.endpoint
        )

    def test_request_invalid_json(self, m):
        method = 'GET'
        m.register_uri(method, self.url, text='{"1"}')

        self.assertRaises(
            InvalidResponse,
            self.requester.request, method, self.endpoint
        )

    def test_valid_headers(self, m):
        method = 'GET'
        m.register_uri(method, self.url)
        self.requester.request(method, self.endpoint)

    def test_invalid_headers(self, m):
        method = 'GET'
        m.register_uri(method, self.url)

        self.assertRaises(
            InvalidHeaders,

# Path: pypd/mixins.py
# class ClientMixin(object):
#     api_key = None
#     base_url = None
#     proxies = None
# 
#     def __init__(self, api_key=None, base_url=None, proxies=None):
#         # if no api key is provided try to get one from the packages api_key
#         if api_key:
#             self.api_key = api_key
# 
#         if self.api_key is None:
#             from pypd import api_key
#             self.api_key = api_key
# 
#         if base_url:
#             self.base_url = base_url
# 
#         if self.base_url is None:
#             from pypd import base_url
#             self.base_url = base_url
# 
#         if not proxies:
#             from pypd import proxies
# 
#         self.proxies = proxies
# 
#     def _handle_response(self, response):
#         if response.status_code == 404:
#             response.raise_for_status()
#         elif response.status_code // 100 == 4:
#             raise BadRequest(response.status_code, response.text)
#         elif response.status_code // 100 != 2:
#             raise UnknownError(response.status_code, response.text)
# 
#         if not response.text:
#             return None
# 
#         try:
#             response = response.json()
#         except:
#             raise InvalidResponse(response.text)
# 
#         return response
# 
#     def _do_request(self, method, *args, **kwargs):
#         """
#         Modularized because API was broken.
# 
#         Need to be able to inject Mocked response objects here.
#         """
#         log('Doing HTTP [{3}] request: {0} - headers: {1} - payload: {2}'.format(
#             args[0], kwargs.get('headers'), kwargs.get('json'), method,),
#             level=logging.DEBUG,)
#         requests_method = getattr(requests, method)
#         return self._handle_response(requests_method(*args, **kwargs))
# 
#     def request(self, method='GET', endpoint='', query_params=None,
#                 data=None, add_headers=None, headers=None,):
#         auth = 'Token token={0}'.format(self.api_key)
#         if query_params is None:
#             query_params = {}
# 
#         if headers is None:
#             headers = {
#                 'Accept': CONTENT_TYPE,
#                 'Authorization': auth,
#                 'Content-Type': 'application/json',
#             }
#         elif not isinstance(headers, dict):
#             raise InvalidHeaders(headers)
# 
#         if add_headers is not None:
#             headers.update(**add_headers)
# 
#         for k, v in query_params.copy().items():
#             if isinstance(v, six.string_types):
#                 continue
#             elif isinstance(v, Number):
#                 continue
#             elif isinstance(v, datetime.datetime):
#                 query_params[k] = v.isoformat()
#             elif isinstance(v, ClientMixin):
#                 query_params[k] = v['id']
#             try:
#                 iter(v)
#             except:
#                 continue
#             key = '%s[]' % k
#             query_params.pop(k)
#             values = [v_['id'] if isinstance(v_, ClientMixin) else v_
#                       for v_ in v]
#             query_params[key] = values
# 
#         kwargs = {
#             'headers': headers,
#             'params': query_params,
#             'proxies': self.proxies,
#         }
# 
#         if data is not None:
#             kwargs['json'] = data
# 
#         return self._do_request(
#             method.lower(),
#             '/'.join((self.base_url, endpoint)),
#             **kwargs
#         )
# 
# Path: pypd/errors.py
# class BadRequest(Error):
#     def __init__(self, code=400, message='', *args, **kwargs):
#         self.code = code
#         self.message = message
#         self.errors = []
# 
#         Error.__init__(self, *args, **kwargs)
# 
#         try:
#             obj = json.loads(message)['error']
#             self.code = obj.get('code', code)
#             self.message = obj.get('message', message)
#             self.errors = obj.get('errors', [])
#         except:
#             pass
# 
#     def __str__(self):
#         error = '{0} ({1}): {2}'.format(self.__class__.__name__, self.code,
#                                         self.message)
#         if self.errors:
#             addon = self.errors[0] if len(self.errors) == 1 else self.errors
#             error = '{0} - {1}'.format(error, addon)
# 
#         return error
# 
# class UnknownError(Error):
#     def __init__(self, code, url, message=''):
#         self.code = code
#         self.url = url
#         self.message = message
# 
#     def __str__(self):
#         return '{0} ({1}): {2}'.format(self.__class__.__name__, self.code,
#                                        self.message)
# 
# class InvalidResponse(Error):
#     """A server response was pure nonsense."""
# 
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return 'InvalidResponse: {0}'.format(self.data)
# 
# class InvalidHeaders(Error):
#     def __init__(self, headers):
#         self.headers = headers
#         self.message = "Request received an invalid headers object, %r".format(
#             headers,
#         )


# Path: test/unit/clientmixin.py
import unittest
import requests_mock
from requests import HTTPError
from pypd.mixins import ClientMixin
from pypd.errors import (BadRequest, UnknownError, InvalidResponse,
                         InvalidHeaders)


    def test_request_5xx(self, m):
        method = 'GET'
        m.register_uri(method, self.url, status_code=500)

        self.assertRaises(
            UnknownError,
            self.requester.request, method, self.endpoint
        )

    def test_request_invalid_json(self, m):
        method = 'GET'
        m.register_uri(method, self.url, text='{"1"}')

        self.assertRaises(
            InvalidResponse,
            self.requester.request, method, self.endpoint
        )

    def test_valid_headers(self, m):
        method = 'GET'
        m.register_uri(method, self.url)
        self.requester.request(method, self.endpoint)

    def test_invalid_headers(self, m):
        method = 'GET'
        m.register_uri(method, self.url)

        self.assertRaises(
            InvalidHeaders,

            self.requester.request, method, self.endpoint,