# Path: cap_client/api/base.py
# class CapAPI(object):
#     """Base CAP interface class.
# 
#     Build your own API class on top of it, to handle requests to CAP server.
#     """
# 
#     def __init__(self):
#         """Initialize."""
#         server_url = os.environ.get('CAP_SERVER_URL',
#                                     'https://analysispreservation.cern.ch')
#         apipath = os.environ.get('CAP_SERVER_API_PATH', 'api/')
#         self.api = urljoin(server_url, apipath)
#         try:
#             self.access_token = os.environ['CAP_ACCESS_TOKEN']
#         except KeyError:
#             raise UsageError(
#                 'No personal access token provided.\n'
#                 'Try: export CAP_ACCESS_TOKEN=[TOKEN]\n\n'
#                 'If you do not have your token yet, login to the website and'
#                 'generate one from your account settings page.')
# 
#     def _make_request(self,
#                       url,
#                       method='get',
#                       expected_status_code=200,
#                       headers={'Content-type': 'application/json'},
#                       stream=False,
#                       **kwargs):
#         """Make request to the CAP server.
# 
#         :param url: endpoint url eg. 'deposits/{pid}'
#         :type url: str
#         :param method: request method
#         :type method: str, optional
#         :param expected_status_code: status code expected on success
#         :type expected_status_code: int, optional
#         :param headers: request headers
#         :type headers: dict, optional
#         :param stream: request streamed response
#         :type stream: bool, optional
# 
#         :raises BadStatusCode: when response status code
#         different than expected
# 
#         :return: response data
#         """
#         endpoint = urljoin(self.api, url)
#         method_obj = getattr(requests, method)
#         headers.update(
#             {'Authorization': 'OAuth2 {}'.format(self.access_token)})
# 
#         response = method_obj(url=endpoint,
#                               verify=False,
#                               headers=headers,
#                               stream=stream,
#                               **kwargs)
# 
#         if response.status_code != expected_status_code:
#             try:
#                 data, msg = response.json(), None
#             except ValueError:
#                 data = msg = response.text
# 
#             # use predefined messages
#             msg = status_code_to_msg.get(response.status_code, msg)
# 
#             raise BadStatusCode(
#                 message=msg,
#                 expected_status_code=expected_status_code,
#                 status_code=response.status_code,
#                 endpoint=endpoint,
#                 data=data,
#             )
# 
#         if stream:
#             return response
#         else:
#             try:
#                 return response.json()
#             except ValueError:
#                 return response.text
# 
# Path: cap_client/errors.py
# class BadStatusCode(CLIError):
#     """Response status code not as expected."""
# 
#     def __init__(self,
#                  message='',
#                  expected_status_code=None,
#                  status_code=None,
#                  endpoint=None,
#                  data=None):
#         """Initialize BadStatusCode."""
#         self.message = message
#         self.expected_status_code = expected_status_code
#         self.status_code = status_code
#         self.endpoint = endpoint
#         self.data = data
# 
#     def __str__(self):
#         """Error details."""
#         if not self.message and isinstance(self.data, dict):
#             msg = [self.data.get('message', '')]
#             # validation errors
#             for err in self.data.get('errors', []):
#                 if 'field' in err and 'message' in err:
#                     field = '.'.join(err['field'])
#                     msg.append((field + ' ' if field else '') + err['message'])
# 
#             return '\n'.join(msg)
# 
#         return self.message
# 
#     def show(self):
#         """Show exception details to the user."""
#         logging.debug(self.data)
#         super(BadStatusCode, self).show()


import json
import responses
from pytest import raises
from cap_client.api.base import CapAPI
from cap_client.errors import BadStatusCode
    resp = CapAPI()._make_request(url='endpoint', stream=True)

    assert resp.content == b'test-data'


@responses.activate
def test_make_request_when_no_text_resp():
    responses.add(responses.GET,
                  'https://analysispreservation-dev.cern.ch/api/endpoint',
                  body='success',
                  status=201)

    resp = CapAPI()._make_request(url='endpoint',
                                  expected_status_code=201,
                                  method='get')
    assert resp == 'success'


@responses.activate
def test_make_request_when_response_status_code_different_than_expected_and_json_response(
):
    responses.add(responses.GET,
                  'https://analysispreservation-dev.cern.ch/api/endpoint',
                  json={
                      'status': 400,
                      'message': 'Error'
                  },
                  status=400)

    with raises(BadStatusCode) as e:

# Path: cap_client/api/base.py
# class CapAPI(object):
#     """Base CAP interface class.
# 
#     Build your own API class on top of it, to handle requests to CAP server.
#     """
# 
#     def __init__(self):
#         """Initialize."""
#         server_url = os.environ.get('CAP_SERVER_URL',
#                                     'https://analysispreservation.cern.ch')
#         apipath = os.environ.get('CAP_SERVER_API_PATH', 'api/')
#         self.api = urljoin(server_url, apipath)
#         try:
#             self.access_token = os.environ['CAP_ACCESS_TOKEN']
#         except KeyError:
#             raise UsageError(
#                 'No personal access token provided.\n'
#                 'Try: export CAP_ACCESS_TOKEN=[TOKEN]\n\n'
#                 'If you do not have your token yet, login to the website and'
#                 'generate one from your account settings page.')
# 
#     def _make_request(self,
#                       url,
#                       method='get',
#                       expected_status_code=200,
#                       headers={'Content-type': 'application/json'},
#                       stream=False,
#                       **kwargs):
#         """Make request to the CAP server.
# 
#         :param url: endpoint url eg. 'deposits/{pid}'
#         :type url: str
#         :param method: request method
#         :type method: str, optional
#         :param expected_status_code: status code expected on success
#         :type expected_status_code: int, optional
#         :param headers: request headers
#         :type headers: dict, optional
#         :param stream: request streamed response
#         :type stream: bool, optional
# 
#         :raises BadStatusCode: when response status code
#         different than expected
# 
#         :return: response data
#         """
#         endpoint = urljoin(self.api, url)
#         method_obj = getattr(requests, method)
#         headers.update(
#             {'Authorization': 'OAuth2 {}'.format(self.access_token)})
# 
#         response = method_obj(url=endpoint,
#                               verify=False,
#                               headers=headers,
#                               stream=stream,
#                               **kwargs)
# 
#         if response.status_code != expected_status_code:
#             try:
#                 data, msg = response.json(), None
#             except ValueError:
#                 data = msg = response.text
# 
#             # use predefined messages
#             msg = status_code_to_msg.get(response.status_code, msg)
# 
#             raise BadStatusCode(
#                 message=msg,
#                 expected_status_code=expected_status_code,
#                 status_code=response.status_code,
#                 endpoint=endpoint,
#                 data=data,
#             )
# 
#         if stream:
#             return response
#         else:
#             try:
#                 return response.json()
#             except ValueError:
#                 return response.text
# 
# Path: cap_client/errors.py
# class BadStatusCode(CLIError):
#     """Response status code not as expected."""
# 
#     def __init__(self,
#                  message='',
#                  expected_status_code=None,
#                  status_code=None,
#                  endpoint=None,
#                  data=None):
#         """Initialize BadStatusCode."""
#         self.message = message
#         self.expected_status_code = expected_status_code
#         self.status_code = status_code
#         self.endpoint = endpoint
#         self.data = data
# 
#     def __str__(self):
#         """Error details."""
#         if not self.message and isinstance(self.data, dict):
#             msg = [self.data.get('message', '')]
#             # validation errors
#             for err in self.data.get('errors', []):
#                 if 'field' in err and 'message' in err:
#                     field = '.'.join(err['field'])
#                     msg.append((field + ' ' if field else '') + err['message'])
# 
#             return '\n'.join(msg)
# 
#         return self.message
# 
#     def show(self):
#         """Show exception details to the user."""
#         logging.debug(self.data)
#         super(BadStatusCode, self).show()


# Path: tests/unit/test_base_api.py
import json
import responses
from pytest import raises
from cap_client.api.base import CapAPI
from cap_client.errors import BadStatusCode

    resp = CapAPI()._make_request(url='endpoint', stream=True)

    assert resp.content == b'test-data'


@responses.activate
def test_make_request_when_no_text_resp():
    responses.add(responses.GET,
                  'https://analysispreservation-dev.cern.ch/api/endpoint',
                  body='success',
                  status=201)

    resp = CapAPI()._make_request(url='endpoint',
                                  expected_status_code=201,
                                  method='get')
    assert resp == 'success'


@responses.activate
def test_make_request_when_response_status_code_different_than_expected_and_json_response(
):
    responses.add(responses.GET,
                  'https://analysispreservation-dev.cern.ch/api/endpoint',
                  json={
                      'status': 400,
                      'message': 'Error'
                  },
                  status=400)

    with raises(BadStatusCode) as e:

        CapAPI()._make_request(url='endpoint', expected_status_code=201)