diff --git a/README.rst b/README.rst index 2804cb4..2e2490e 100644 --- a/README.rst +++ b/README.rst @@ -97,11 +97,6 @@ Sample Output (truncated for readability) ... -Limitations -=========== - -1. `These endpoints `__ are not yet supported. - Development =========== diff --git a/circleci/api.py b/circleci/api.py index c59ddc2..acc0919 100644 --- a/circleci/api.py +++ b/circleci/api.py @@ -10,6 +10,8 @@ from requests.auth import HTTPBasicAuth from circleci.error import BadHttpVerbError +from circleci.error import BadKeyTypeError + class Api(): """A python interface into the CircleCI API""" @@ -274,25 +276,190 @@ def trigger_build( resp = self._request('POST', endpoint, params) return resp + def add_ssh_key( + self, + username, + project, + ssh_key, + vcs_type='github', + hostname=None): + """Create an ssh key + + Used to access external systems that require SSH key-based authentication. + + Params: + username (str): + org or user name + project (str): + case sensitive repo name + branch (str): + defaults to master + ssh_key(str): + private rsa key + + note: this must be unencrypted + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + hostname (str): + optional hostname, if set the key + will only work for this hostname. + + Endpoint: + POST: /project/:vcs-type/:username/:project/ssh-key + """ + endpoint = 'project/{0}/{1}/{2}/ssh-key'.format( + vcs_type, + username, + project + ) + + params = { + "hostname": hostname, + "private_key": ssh_key + } + + resp = self._request('POST', endpoint, data=params) + return resp + + def list_checkout_keys(self, username, project, vcs_type='github'): + """List checkout keys for a project + + Args: + username (str): + org or user name + project (str): + case sensitive repo name + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + + Endpoint: + GET: /project/:vcs-type/:username/:project/checkout-key + """ + endpoint = 'project/{0}/{1}/{2}/checkout-key'.format( + vcs_type, + username, + project + ) + + resp = self._request('GET', endpoint) + return resp + + def create_checkout_key(self, username, project, key_type, vcs_type='github'): + """Create a new checkout keys for a project + + Args: + username (str): + org or user name + project (str): + case sensitive repo name + key_type (str): + The type of key to create + + Can be 'deploy-key' or 'github-user-key' + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + + Endpoint: + POST: /project/:vcs-type/:username/:project/checkout-key + """ + valid_types = ['deploy-key', 'github-user-key'] + + if key_type not in valid_types: + raise BadKeyTypeError(key_type, "key_type must be deploy-key or github-user-key") + + params = { + "type": key_type + } + + endpoint = 'project/{0}/{1}/{2}/checkout-key'.format( + vcs_type, + username, + project + ) + + resp = self._request('POST', endpoint, data=params) + return resp + + def get_checkout_key(self, username, project, fingerprint, vcs_type='github'): + """Get a checkout key. + + Args: + username (str): + org or user name + project (str): + case sensitive repo name + fingerprint (str): + The fingerprint of the checkout key + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + + Endpoint: + GET: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + """ + endpoint = 'project/{0}/{1}/{2}/checkout-key/{3}'.format( + vcs_type, + username, + project, + fingerprint + ) + + resp = self._request('GET', endpoint) + + return resp + + def delete_checkout_key(self, username, project, fingerprint, vcs_type='github'): + """Delete a checkout key. + + Args: + username (str): + org or user name + project (str): + case sensitive repo name + fingerprint (str): + The fingerprint of the checkout key + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + + Endpoint: + DELETE: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + """ + endpoint = 'project/{0}/{1}/{2}/checkout-key/{3}'.format( + vcs_type, + username, + project, + fingerprint + ) + + resp = self._request('DELETE', endpoint) + return resp + + def clear_cache(self, username, project, vcs_type='github'): + """Clear cache for a project -# TODO support the rest of these methods -# POST: /project/:vcs-type/:username/:project/ssh-key -# Create an ssh key used to access external systems that require SSH key-based authentication -# GET: /project/:vcs-type/:username/:project/checkout-key -# Lists checkout keys. -# POST: /project/:vcs-type/:username/:project/checkout-key -# Create a new checkout key. -# GET: /project/:vcs-type/:username/:project/checkout-key/:fingerprint -# Get a checkout key. -# DELETE: /project/:vcs-type/:username/:project/checkout-key/:fingerprint -# Delete a checkout key. -# DELETE: /project/:vcs-type/:username/:project/build-cache -# Clears the cache for a project. -# POST: /user/ssh-key -# Adds a CircleCI key to your GitHub User account. -# POST: /user/heroku-key -# Adds your Heroku API key to CircleCI, takes apikey as form param name. + Args: + username (str): + org or user name + project (str): + case sensitive repo name + vcs_type (str): + defaults to github + on circleci.com you can also pass in bitbucket + Endpoint: + DELETE: /project/:vcs-type/:username/:project/build-cache + """ + endpoint = 'project/{0}/{1}/{2}/build-cache'.format( + vcs_type, + username, + project + ) + resp = self._request('DELETE', endpoint) + return resp def _request(self, verb, endpoint, data=None): """Request a url. @@ -322,8 +489,10 @@ def _request(self, verb, endpoint, data=None): elif verb == 'POST': resp = requests.post(request_url, auth=auth, headers=headers, data=data) + elif verb == 'DELETE': + resp = requests.delete(request_url, auth=auth, headers=headers) else: - raise BadHttpVerbError(verb, "verb must be GET or POST") + raise BadHttpVerbError(verb, "verb must be GET, POST, or DELETE") return resp.json() diff --git a/circleci/error.py b/circleci/error.py index 2f5df98..d365de2 100644 --- a/circleci/error.py +++ b/circleci/error.py @@ -9,6 +9,7 @@ class CircleCIError(Exception): """Base class for CircleCI errors""" pass + class BadHttpVerbError(CircleCIError): """Exception raises for bad HTTP verb @@ -20,4 +21,18 @@ class BadHttpVerbError(CircleCIError): """ def __init__(self, verb, message): self.verb = verb + self.message = message + + +class BadKeyTypeError(CircleCIError): + """Exception raises for bad Key Type + + Args: + key_type (str): + Value passed in for key_type + message (str): + explanation message + """ + def __init__(self, key_type, message): + self.key_type = key_type self.message = message \ No newline at end of file diff --git a/docs/circleci.api.txt b/docs/circleci.api.txt index 364ab1d..658e4aa 100644 --- a/docs/circleci.api.txt +++ b/docs/circleci.api.txt @@ -31,6 +31,32 @@ CLASSES | token (str): | Your CircleCI token.abs | + | add_ssh_key(self, username, project, ssh_key, vcs_type='github', hostname=None) + | Create an ssh key + | + | Used to access external systems that require SSH key-based authentication. + | + | Params: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | branch (str): + | defaults to master + | ssh_key(str): + | private rsa key + | + | note: this must be unencrypted + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | hostname (str): + | optional hostname, if set the key + | will only work for this hostname. + | + | Endpoint: + | POST: /project/:vcs-type/:username/:project/ssh-key + | | add_ssh_user(self, username, project, build_num, vcs_type='github') | Adds a user to the build's SSH permissions. | @@ -65,6 +91,57 @@ CLASSES | Endpoint: | POST: /project/:vcs-type/:username/:project/:build_num/cancel | + | clear_cache(self, username, project, vcs_type='github') + | Clear cache for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | DELETE: /project/:vcs-type/:username/:project/build-cache + | + | create_checkout_key(self, username, project, key_type, vcs_type='github') + | Create a new checkout keys for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | key_type (str): + | The type of key to create + | + | Can be 'deploy-key' or 'github-user-key' + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | POST: /project/:vcs-type/:username/:project/checkout-key + | + | delete_checkout_key(self, username, project, fingerprint, vcs_type='github') + | Delete a checkout key. + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | fingerprint (str): + | The fingerprint of the checkout key + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | DELETE: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + | | follow_project(self, username, project, vcs_type='github') | Follow a new project on CircleCI. | @@ -114,6 +191,23 @@ CLASSES | Endpoint: | GET: /project/:vcs-type/:username/:project/:build_num | + | get_checkout_key(self, username, project, fingerprint, vcs_type='github') + | Get a checkout key. + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | fingerprint (str): + | The fingerprint of the checkout key + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | GET: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + | | get_project_build_summary(self, username, project, vcs_type='github') | Build summary for each of the last 30 builds for a single git repo. | @@ -147,6 +241,21 @@ CLASSES | Endpoint: | GET: /me | + | list_checkout_keys(self, username, project, vcs_type='github') + | List checkout keys for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | GET: /project/:vcs-type/:username/:project/checkout-key + | | retry_build(self, username, project, build_num, vcs_type='github') | Retries the build. | diff --git a/docs/circleci.error.txt b/docs/circleci.error.txt index ba6babb..b7c6ec5 100644 --- a/docs/circleci.error.txt +++ b/docs/circleci.error.txt @@ -11,6 +11,7 @@ CLASSES builtins.Exception(builtins.BaseException) CircleCIError BadHttpVerbError + BadKeyTypeError class BadHttpVerbError(CircleCIError) | Exception raises for bad HTTP verb @@ -89,6 +90,83 @@ CLASSES | | args + class BadKeyTypeError(CircleCIError) + | Exception raises for bad Key Type + | + | Args: + | key_type (str): + | Value passed in for key_type + | message (str): + | explanation message + | + | Method resolution order: + | BadKeyTypeError + | CircleCIError + | builtins.Exception + | builtins.BaseException + | builtins.object + | + | Methods defined here: + | + | __init__(self, key_type, message) + | Initialize self. See help(type(self)) for accurate signature. + | + | ---------------------------------------------------------------------- + | Data descriptors inherited from CircleCIError: + | + | __weakref__ + | list of weak references to the object (if defined) + | + | ---------------------------------------------------------------------- + | Methods inherited from builtins.Exception: + | + | __new__(*args, **kwargs) from builtins.type + | Create and return a new object. See help(type) for accurate signature. + | + | ---------------------------------------------------------------------- + | Methods inherited from builtins.BaseException: + | + | __delattr__(self, name, /) + | Implement delattr(self, name). + | + | __getattribute__(self, name, /) + | Return getattr(self, name). + | + | __reduce__(...) + | helper for pickle + | + | __repr__(self, /) + | Return repr(self). + | + | __setattr__(self, name, value, /) + | Implement setattr(self, name, value). + | + | __setstate__(...) + | + | __str__(self, /) + | Return str(self). + | + | with_traceback(...) + | Exception.with_traceback(tb) -- + | set self.__traceback__ to tb and return self. + | + | ---------------------------------------------------------------------- + | Data descriptors inherited from builtins.BaseException: + | + | __cause__ + | exception cause + | + | __context__ + | exception context + | + | __dict__ + | + | __suppress_context__ + | + | __traceback__ + | + | args + class CircleCIError(builtins.Exception) | Base class for CircleCI errors | diff --git a/docs/circleci.experimental.txt b/docs/circleci.experimental.txt index 4262c8b..3b89b81 100644 --- a/docs/circleci.experimental.txt +++ b/docs/circleci.experimental.txt @@ -59,6 +59,32 @@ CLASSES | token (str): | Your CircleCI token.abs | + | add_ssh_key(self, username, project, ssh_key, vcs_type='github', hostname=None) + | Create an ssh key + | + | Used to access external systems that require SSH key-based authentication. + | + | Params: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | branch (str): + | defaults to master + | ssh_key(str): + | private rsa key + | + | note: this must be unencrypted + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | hostname (str): + | optional hostname, if set the key + | will only work for this hostname. + | + | Endpoint: + | POST: /project/:vcs-type/:username/:project/ssh-key + | | add_ssh_user(self, username, project, build_num, vcs_type='github') | Adds a user to the build's SSH permissions. | @@ -93,6 +119,57 @@ CLASSES | Endpoint: | POST: /project/:vcs-type/:username/:project/:build_num/cancel | + | clear_cache(self, username, project, vcs_type='github') + | Clear cache for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | DELETE: /project/:vcs-type/:username/:project/build-cache + | + | create_checkout_key(self, username, project, key_type, vcs_type='github') + | Create a new checkout keys for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | key_type (str): + | The type of key to create + | + | Can be 'deploy-key' or 'github-user-key' + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | POST: /project/:vcs-type/:username/:project/checkout-key + | + | delete_checkout_key(self, username, project, fingerprint, vcs_type='github') + | Delete a checkout key. + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | fingerprint (str): + | The fingerprint of the checkout key + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | DELETE: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + | | follow_project(self, username, project, vcs_type='github') | Follow a new project on CircleCI. | @@ -142,6 +219,23 @@ CLASSES | Endpoint: | GET: /project/:vcs-type/:username/:project/:build_num | + | get_checkout_key(self, username, project, fingerprint, vcs_type='github') + | Get a checkout key. + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | fingerprint (str): + | The fingerprint of the checkout key + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | GET: /project/:vcs-type/:username/:project/checkout-key/:fingerprint + | | get_project_build_summary(self, username, project, vcs_type='github') | Build summary for each of the last 30 builds for a single git repo. | @@ -175,6 +269,21 @@ CLASSES | Endpoint: | GET: /me | + | list_checkout_keys(self, username, project, vcs_type='github') + | List checkout keys for a project + | + | Args: + | username (str): + | org or user name + | project (str): + | case sensitive repo name + | vcs_type (str): + | defaults to github + | on circleci.com you can also pass in bitbucket + | + | Endpoint: + | GET: /project/:vcs-type/:username/:project/checkout-key + | | retry_build(self, username, project, build_num, vcs_type='github') | Retries the build. | diff --git a/setup.py b/setup.py index 73d3ab6..45eac20 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def readme(): setup( name="circleci", - version="1.1.0.dev6", + version="1.1.0", description="Python wrapper for the CircleCI API", long_description=readme(), url="https://github.com/levlaz/circleci.py", @@ -21,7 +21,7 @@ def readme(): author_email="lev@levlaz.org", license="MIT", classifiers=[ - "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", diff --git a/tests/circle/test_api.py b/tests/circle/test_api.py index da8041d..f7480a1 100644 --- a/tests/circle/test_api.py +++ b/tests/circle/test_api.py @@ -7,11 +7,12 @@ from unittest.mock import MagicMock, patch from circleci.api import Api from circleci.error import BadHttpVerbError +from circleci.error import BadKeyTypeError class TestCircleCIApi(unittest.TestCase): def setUp(self): - self.c = Api('fake-token') + self.c = Api(os.getenv('CIRCLE_TOKEN')) def loadMock(self, filename): """helper function to open mock responses""" @@ -26,7 +27,7 @@ def test_bad_verb(self): self.c._request('BAD', 'dummy') self.assertEqual('BAD', e.exception.verb) - self.assertIn('GET or POST', e.exception.message) + self.assertIn('GET, POST, or DELETE', e.exception.message) def test_get_user_info(self): self.loadMock('mock_user_info_response') @@ -93,15 +94,55 @@ def test_add_ssh_user(self): self.assertEqual(resp['reponame'], 'MOCK+testing') self.assertEqual(resp['ssh_users'][0]['login'], 'ccie-tester') - # def test_add_ssh_key(self): - # resp = self.c.create_ssh_key('ccie-tester', 'testing') - # with open('tests/mocks/mock_create_ssh_key_response', 'w') as f: - # json.dump(resp, f) - - # print(resp) - def test_trigger_build(self): self.loadMock('mock_trigger_build_response') resp = json.loads(self.c.trigger_build('ccie-tester', 'testing')) - self.assertEqual(resp['reponame'], 'MOCK+testing') \ No newline at end of file + self.assertEqual(resp['reponame'], 'MOCK+testing') + + def test_list_checkout_keys(self): + self.loadMock('mock_list_checkout_keys_response') + resp = json.loads(self.c.list_checkout_keys('levlaz', 'circleci-sandbox')) + + self.assertEqual(resp[0]['type'], 'deploy-key') + self.assertIn('public_key', resp[0]) + + def test_create_checkout_key(self): + + with self.assertRaises(BadKeyTypeError) as e: + self.c.create_checkout_key('levlaz', 'test', 'bad') + + self.assertEqual('bad', e.exception.key_type) + self.assertIn('deploy-key', e.exception.message) + + self.loadMock('mock_create_checkout_key_response') + resp = json.loads(self.c.create_checkout_key('levlaz', 'test', 'deploy-key')) + + self.assertEqual(resp['type'], 'deploy-key') + self.assertIn('public_key', resp) + + def test_get_checkout_key(self): + + self.loadMock('mock_get_checkout_key_response') + resp = json.loads(self.c.get_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e')) + + self.assertEqual(resp['type'], 'deploy-key') + self.assertIn('public_key', resp) + + def test_delete_checkout_key(self): + self.loadMock('mock_delete_checkout_key_response') + resp = json.loads(self.c.delete_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e')) + + self.assertEqual(resp['message'], 'ok') + + def test_clear_cache(self): + self.loadMock('mock_clear_cache_response') + resp = json.loads(self.c.clear_cache('levlaz', 'circleci-sandbox')) + + self.assertEqual('build dependency caches deleted', resp['status']) + + # def test_helper(self): + # resp = self.c.add_circle_key() + # print(resp) + # with open('tests/mocks/mock_add_circle_key_response', 'w') as f: + # json.dump(resp, f) \ No newline at end of file diff --git a/tests/circle/test_integration.py b/tests/circle/test_integration.py index 8bc4d84..6e875c3 100644 --- a/tests/circle/test_integration.py +++ b/tests/circle/test_integration.py @@ -20,4 +20,42 @@ def test_trigger_with_build_params(self): resp = self.c.trigger_build('levlaz', 'circleci-demo-javascript-express', params=params) - self.assertEqual(resp['build_parameters']['CIRCLE_JOB'], 'test') \ No newline at end of file + self.assertEqual(resp['build_parameters']['CIRCLE_JOB'], 'test') + + def test_add_ssh_key(self): + + # note this is a throwaway key + key = """ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAr74mGZIij/V59DTGRPaijyDolWA33FlyopBVSys09MOOF7HT +EWLMwyyRIR3t6mjl7kcS3rTPWORLF4U+8iMv1EyitV+fV+pQIJmK8gZvyyNePCR0 +wvAizhNTcYgtZF86D/EBNHwOdN0o4P+4qlbBlPjFiW7S5X6iDbrV9H4ADQDI2R+c +EBets+aVRrtCdR+cGrOS9BRVf4NK6ADQaKOcgTYRTJuxI48O18iUj9dZSCAlO6xQ +obpALlQKj0srGcx9++vTzED3Wr9JpOfsC8LqNdJdaF6KJfBsc1xczSw980hcXwWx +/zrQaii5W7nFU2lRrwdXyscqutL1I5lLKDYhLQIDAQABAoIBACA9mxG/3HVajGf/ +sov+Ty5A1EprH3ReOIiYP/2NTKbGpW+1YMpkvLnlmC5iJj6FxgDjqxOOSie9ogUL +ndOgHusssADkLQBc7Rw97t6dza6Pq38PFRiaI1h49Srz15f9XFKGXTk6tRA9bn1w +jHk7d0IULXEcErald6dbKlszLmE0AHvWHWNrABwbNBzG2PrFFbrWbYiUDhIx8Ebj +9IKDu8JqYr5o6Kv8agOAWkq4S3iGQ9S+suTiV+3/kyK7XL5TI5gVPdZR4NIAGFKO ++1TBNtCiYl+LQ46km5cmirESTsObNM3JrF8VWBlVZoVrxZiIhYUAKrFzcJ905Vrh +PN0rwmECgYEA6LWeorGs9kyVgNI4KnvVI1AXACnpy4L48ypqIns5A71j+4OiVI64 +dWAlHB64ZoMVVBqTCv/uiloqzlK+FCe8cxi3Xh/hBDmKmGZygpFoRdGwmNA+1CoA +DZftaswUQ64Qt8jc9HmQnufvkxniNAewRxuZDP462WgBwZhRe8hvUqUCgYEAwVT0 +HojCaLm2TMY2XE9EzCHNF1XlfqzB0i0dJ4pQ2SZ8st1F8vkEjHsPEOURRkLzWFC4 +A/QWFsmhv4UKpDplV5QV3S+FgbpzLdV64vUYBuo06OZGcJgCdtZyt6vGSB4f+mq2 +VQt+j6ZYlI5nWwkz1Yvg8AmBemuXNFui8o/c9ekCgYB2vwa9+nBKFnZLj/n9I8d1 +B49VFA4rPSAP5VrXUY2cbO4yD8+r2lAiBPeqy7pJBSbDDfRurn5otu4U7n/0BPrS +uJAJRbcq0rn4Xn6cRdqxlfjJYapN1UjFpvsNfinxB0ecoLCvR8EWdT/5DkIxTqMT +BfApgylAeyQ6R6F8yqCTyQKBgQCN5XFrO8scnDmt7ckWRWPkQ2bJGtVe/SMgxNXi +IIWoa7QYf4mIhLaO+P8c0lO0cw0yI8R7ulnADet2qwodcXLSLbFCb0+Y4KUK3eXc +0DD7WkjNK75Fg3xDhrAaGKxmYB3uaQY8MzyH6HqZRk+bpIxzzr+gzglHNdJ7rkpR +p79wiQKBgQCwFyjcLAfA5uJDZ9jVEZ2BKgd9IGo16HrRnd+mpggUBGf2mbE2JGgk +rAUZ8tU0o5Ec6T0ZQkcous7OwBZGE+JLuFa3S6JfISLw42brjQ9dE5mosm7m2d4H +3C9cAnmV6aJkTwT46OiNvUYZ8je5WP+4Kqb2ke9xw3ddk5X1n5AB4w== +-----END RSA PRIVATE KEY----- +""" + resp = self.c.add_ssh_key('levlaz', 'circleci-sandbox', key, hostname='localhost') + + # there is no response when success, so we test to make sure + # that there is no other message as well. + self.assertTrue(len(resp) == 0) \ No newline at end of file diff --git a/tests/mocks/mock_clear_cache_response b/tests/mocks/mock_clear_cache_response new file mode 100644 index 0000000..3f96ade --- /dev/null +++ b/tests/mocks/mock_clear_cache_response @@ -0,0 +1 @@ +{"status": "build dependency caches deleted"} \ No newline at end of file diff --git a/tests/mocks/mock_create_checkout_key_response b/tests/mocks/mock_create_checkout_key_response new file mode 100644 index 0000000..ac18081 --- /dev/null +++ b/tests/mocks/mock_create_checkout_key_response @@ -0,0 +1 @@ +{"public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/fY7Kr3SiVzN6Tw7+5GjT7Qj5ldT92DcUAFJC/LJTRNcpTu1WtfuqEtdq3yoNm2PY4KgBViIecUuoeoKkfj9aQcuPFkol9RYeEbu80D21zke/aC4P4VFrCWaeLapEvFSSDF/lOSVGA7l+DEOoOtAcmIBOsPrkixyDmNf5orr9B0nZCOVlv6bq2sjIqJNEI1ER2sNY+ie1VZAA9kClMEd8rtGPKNC2T7couwiS3RR0jGob1VVuVuPw8B+JgWspg4RjpEKM9RLQpRb2mTDJBOmppogMNztXNav/WhRfdhDz8nlyI8liP1S19CDLFMaAHe2sH5hry8Qx8592yLt9Ght5 \n", "type": "deploy-key", "fingerprint": "94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e", "login": null, "preferred": true, "time": "2017-10-25T08:19:19.213Z"} \ No newline at end of file diff --git a/tests/mocks/mock_create_ssh_key_response b/tests/mocks/mock_create_ssh_key_response index 52a491c..3cc762b 100644 --- a/tests/mocks/mock_create_ssh_key_response +++ b/tests/mocks/mock_create_ssh_key_response @@ -1 +1 @@ -{"message": "a private key is required"} \ No newline at end of file +"" \ No newline at end of file diff --git a/tests/mocks/mock_delete_checkout_key_response b/tests/mocks/mock_delete_checkout_key_response new file mode 100644 index 0000000..24a8db7 --- /dev/null +++ b/tests/mocks/mock_delete_checkout_key_response @@ -0,0 +1 @@ +{"message": "ok"} \ No newline at end of file diff --git a/tests/mocks/mock_get_checkout_key_response b/tests/mocks/mock_get_checkout_key_response new file mode 100644 index 0000000..ac18081 --- /dev/null +++ b/tests/mocks/mock_get_checkout_key_response @@ -0,0 +1 @@ +{"public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/fY7Kr3SiVzN6Tw7+5GjT7Qj5ldT92DcUAFJC/LJTRNcpTu1WtfuqEtdq3yoNm2PY4KgBViIecUuoeoKkfj9aQcuPFkol9RYeEbu80D21zke/aC4P4VFrCWaeLapEvFSSDF/lOSVGA7l+DEOoOtAcmIBOsPrkixyDmNf5orr9B0nZCOVlv6bq2sjIqJNEI1ER2sNY+ie1VZAA9kClMEd8rtGPKNC2T7couwiS3RR0jGob1VVuVuPw8B+JgWspg4RjpEKM9RLQpRb2mTDJBOmppogMNztXNav/WhRfdhDz8nlyI8liP1S19CDLFMaAHe2sH5hry8Qx8592yLt9Ght5 \n", "type": "deploy-key", "fingerprint": "94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e", "login": null, "preferred": true, "time": "2017-10-25T08:19:19.213Z"} \ No newline at end of file diff --git a/tests/mocks/mock_list_checkout_keys_response b/tests/mocks/mock_list_checkout_keys_response new file mode 100644 index 0000000..12e2ada --- /dev/null +++ b/tests/mocks/mock_list_checkout_keys_response @@ -0,0 +1 @@ +[{"public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCEQcQIgpaJezfCyJM9BG4yu1ecsSoe0CAvnoO/U4B8PpwX6iB9CgqftQEkndanJSaPscMPw29L6KHS0RrMlXX8qHbkzB0C/qBy2hrhOKJLQpL6ez4LSjBJcC2FR6tjFMDHMBHlg5b6IzccNI6foyfHa7R557W+WCtBnSzLLk8AYyzF4A+G7ActXulI0UInwMxUBN8nr2VI4AhIRhzk2pIRYhEF8Mgs1IAmjbTmrWP1gPwOaqWBchch90h07HH7WwuRyHy076FGVMOB16fKK80SLaBeZ6KVygfkXF/7ZdkU4JbJUjlFs/JnJslXgR8SmMiqLRP1VxaNXbRTPaiwtEfj \n", "type": "deploy-key", "fingerprint": "9f:71:46:8b:a0:96:81:2d:53:b9:ad:0d:6d:e1:9c:51", "login": null, "preferred": true, "time": "2017-10-18T06:49:39.006Z"}] \ No newline at end of file