示例#1
0
class TestClient(TestCase):
    def setUp(self):
        self.c = Client()

    def test_set_credentials_with_valid(self):
        self.c.set_credentials('login', 'password')
        self.assertEqual(self.c.requester.auth, ('login', 'password'))

    def test_set_credentials_with_invalid(self):
        self.c.set_credentials('', '')
        self.assertIsNone(self.c.requester.auth)

    def test_set_token_with_valid(self):
        self.c.set_token('tokenize')
        self.assertEqual(self.c.requester.params['access_token'], 'tokenize')

    def test_set_token_with_invalid(self):
        self.c.set_token('')
        self.assertIsNone(self.c.requester.params.get('access_token'))

    def test_INIT_client_with_another_config_args(self):
        new_c = Client(base_url='url',
                       per_page=10,
                       user='******',
                       repo='myrepo',
                       verbose='stream')
        self.assertEqual(new_c.config['base_url'], 'url')
        self.assertEqual(new_c.requester.params['per_page'], 10)
        self.assertEqual(new_c.user, 'me')
        self.assertEqual(new_c.repo, 'myrepo')
        self.assertEqual(new_c.requester.config['verbose'], 'stream')

    @patch.object(requests.sessions.Session, 'request')
    def test_PARSE_args_in_request_without_params(self, request_method):
        extra = dict(arg1='arg1', arg2='arg2')
        self.c.request('', '', data='data', **extra)
        request_method.assert_called_with('',
                                          self.c.config['base_url'],
                                          data='data',
                                          params=extra)

    @patch.object(requests.sessions.Session, 'request')
    def test_PARSE_args_in_request_with_params(self, request_method):
        extra = dict(arg1='arg1', arg2='arg2')
        self.c.request('', '', params=dict(arg0='arg0'), **extra)
        request_method.assert_called_with('',
                                          self.c.config['base_url'],
                                          params=dict(arg0='arg0', **extra))

    @patch.object(Client, 'request')
    def test_DELEGATES_methods(self, request_method):
        request_method.return_value = mock_response()
        self.c.get('')
        request_method.assert_called_with('get', '')

        request_method.return_value = mock_response('post')
        self.c.post('')
        request_method.assert_called_with('post', '')

        request_method.return_value = mock_response('patch')
        self.c.patch('')
        request_method.assert_called_with('patch', '')

        self.c.put('')
        request_method.assert_called_with('put', '')

        request_method.return_value = mock_response('delete')
        self.c.delete('')
        request_method.assert_called_with('delete', '')

        self.c.head('')
        request_method.assert_called_with('head', '')
示例#2
0
class Service(object):
    """
    You can configure each service with this keyword variables:

    :param str login: Username to authenticate
    :param str password: Username to authenticate
    :param str user: Default username in requests
    :param str repo: Default repository in requests
    :param str token: Token to OAuth
    :param int per_page: Items in each page of multiple returns
    :param str base_url: To support another github-related API (untested)
    :param stream verbose: Stream to write debug logs

    You can configure the **authentication** with BasicAuthentication (login
    and password) and with `OAuth <http://developer.github.com/v3/oauth/>`_ (
    token).
    If you include ``login``, ``password`` and ``token`` in config; Oauth has
    precedence

    Some API requests need ``user`` and/or ``repo`` arguments (e.g
    :ref:`repos service <config precedence>`).
    You can configure the default value here to avoid repeating

    Some API requests return multiple resources with pagination. You can
    configure how many items has each page.

    You can configure ``verbose`` logging like `requests library <http://docs.
    python-requests.org/en/v0.10.6/user/advanced/#verbose-logging>`_
    """

    def __init__(self, **config):
        self._client = Client(**config)
        self.request_builder = Factory()

    def _normalize_date(self, key, _dict):
        """ If ``key`` comes as ``datetime``, it'll normalize it """
        try:
            key = str(key)
            date = datetime.strftime(_dict.get(key), GITHUB_DATE_FORMAT)
            _dict.update({key: date})
        except:
            pass

    @property
    def remaining_requests(self):
        return Client.remaining_requests

    def get_user(self):
        return self._client.user

    def set_user(self, user):
        """ Set user

        :param str user: Default username in requests
        """
        self._client.user = user

    def get_repo(self):
        return self._client.repo

    def set_repo(self, repo):
        """ Set repository

        :param str repo: Default repository in requests
        """
        self._client.repo = repo

    def set_credentials(self, login, password):
        """ Set Basic Authentication

        :param str login: Username to authenticate
        :param str password: Username to authenticate
        """
        self._client.set_credentials(login, password)

    def set_token(self, token):
        """ Set OAuth token

        :param str token: Token to OAuth
        """
        self._client.set_token(token)

    #TODO: Refact as decorator::
    """
        Reason: make_request and request_builder ... are confusing names
        @precedence('user')
        def list(self, sha, user=None):
    """
    def make_request(self, request, **kwargs):
        if 'user' in kwargs:
            kwargs['user'] = kwargs['user'] or self.get_user()
        if 'repo' in kwargs:
            kwargs['repo'] = kwargs['repo'] or self.get_repo()
        return self.request_builder(request, **kwargs)

    def _request(self, verb, request, **kwargs):
        self._client.request(verb, request, **kwargs)

    def _bool(self, request, **kwargs):
        try:
            self._client.head(request, **kwargs)
            return True
        except NotFound:
            return False

    def _patch(self, request, **kwargs):
        input_data = request.get_body()
        response = self._client.patch(request, data=input_data, **kwargs)
        return request.resource.loads(response.content)

    def _put(self, request, **kwargs):
        """ Bug in Github API? requests library?

        I must send data when the specifications' of some PUT request are 'Not
        send input data'. If I don't do that and send data as None, the
        requests library doesn't send 'Content-length' header and the server
        returns 411 - Required Content length (at least 0)

        For instance:
            - follow-user request doesn't send input data
            - merge-pull request send data

        For that reason I must do a conditional because I don't want to return
        an empty string on follow-user request because it could be confused

        Related: https://github.com/github/developer.github.com/pull/52
        """
        input_data = request.get_body() or 'PLACEHOLDER'
        response = self._client.put(request, data=input_data, **kwargs)
        if response.status_code != 204:  # != NO_CONTENT
            return request.resource.loads(response.content)

    def _delete(self, request, **kwargs):
        input_data = request.get_body()
        self._client.delete(request, data=input_data, **kwargs)

    def _post(self, request, **kwargs):
        input_data = request.get_body()
        response = self._client.post(request, data=input_data, **kwargs)
        return request.resource.loads(response.content)

    def _get(self, request, **kwargs):
        response = self._client.get(request, **kwargs)
        return request.resource.loads(response.content)

    def _get_result(self, request, **kwargs):
        method = smart.Method(self._client.get, request, **kwargs)
        return smart.Result(method)

    def _get_normal_result(self, request, **kwargs):
        method = normal.Method(self._client.get, request, **kwargs)
        return normal.Result(method)
示例#3
0
class TestClient(TestCase):

    def setUp(self):
        self.c = Client()

    def test_set_credentials_with_valid(self):
        self.c.set_credentials('login', 'password')
        self.assertEqual(self.c.requester.auth, ('login', 'password'))

    def test_set_credentials_with_invalid(self):
        self.c.set_credentials('', '')
        self.assertIsNone(self.c.requester.auth)

    def test_set_token_with_valid(self):
        self.c.set_token('tokenize')
        self.assertEqual(dict(self.c.requester.params)['access_token'],
            'tokenize')

    def test_set_token_with_invalid(self):
        self.c.set_token('')
        self.assertIsNone(dict(self.c.requester.params).get('access_token'))

    def test_INIT_client_with_another_config_args(self):
        new_c = Client(base_url='url', per_page=10, user='******', repo='myrepo',
                       verbose='stream')
        self.assertEqual(new_c.config['base_url'], 'url')
        self.assertEqual(dict(new_c.requester.params)['per_page'], 10)
        self.assertEqual(new_c.user, 'me')
        self.assertEqual(new_c.repo, 'myrepo')
        self.assertEqual(new_c.requester.config['verbose'], 'stream')

    @patch.object(requests.sessions.Session, 'request')
    def test_PARSE_args_in_request_without_params(self, request_method):
        extra = dict(arg1='arg1', arg2='arg2')
        self.c.request('', '', data='data', **extra)
        request_method.assert_called_with('', self.c.config['base_url'],
            data='data', params=extra)

    @patch.object(requests.sessions.Session, 'request')
    def test_PARSE_args_in_request_with_params(self, request_method):
        extra = dict(arg1='arg1', arg2='arg2')
        self.c.request('', '', params=dict(arg0='arg0'), **extra)
        request_method.assert_called_with('', self.c.config['base_url'],
            params=dict(arg0='arg0', **extra))

    @patch.object(Client, 'request')
    def test_DELEGATES_methods(self, request_method):
        request_method.return_value = mock_response()
        self.c.get('')
        request_method.assert_called_with('get', '')

        request_method.return_value = mock_response('post')
        self.c.post('')
        request_method.assert_called_with('post', '')

        request_method.return_value = mock_response('patch')
        self.c.patch('')
        request_method.assert_called_with('patch', '')

        self.c.put('')
        request_method.assert_called_with('put', '')

        request_method.return_value = mock_response('delete')
        self.c.delete('')
        request_method.assert_called_with('delete', '')

        self.c.head('')
        request_method.assert_called_with('head', '')