From de317f3271f7ef664adde9746936cc2f30355961 Mon Sep 17 00:00:00 2001 From: Michael Dubner Date: Sat, 21 Jan 2017 17:54:09 +0300 Subject: [PATCH] Gogs support (second attempt uses gogs_client and includes tests) --- README.md | 11 +- git_repo/services/ext/gogs.py | 260 ++++++++++++++++++ requirements.txt | 1 + ...t_gogs_test_01_create__already_exists.json | 79 ++++++ .../test_gogs_test_01_create__new.json | 115 ++++++++ ..._test_01_create_group__already_exists.json | 115 ++++++++ .../test_gogs_test_01_create_group__new.json | 151 ++++++++++ .../cassettes/test_gogs_test_02_delete.json | 111 ++++++++ .../test_gogs_test_03_delete_nouser.json | 111 ++++++++ .../cassettes/test_gogs_test_04_clone.json | 41 +++ .../cassettes/test_gogs_test_05_add.json | 41 +++ .../test_gogs_test_06_add__name.json | 41 +++ .../test_gogs_test_07_add__alone.json | 41 +++ .../test_gogs_test_08_add__alone_name.json | 41 +++ .../test_gogs_test_09_add__default.json | 41 +++ .../test_gogs_test_10_add__default_name.json | 41 +++ .../test_gogs_test_11_add__alone_default.json | 41 +++ ..._gogs_test_12_add__alone_default_name.json | 41 +++ tests/integration/local/gogs/README.md | 8 + .../local/gogs/custom/conf/app.ini | 56 ++++ tests/integration/local/gogs/init.sh | 29 ++ tests/integration/local/gogs/init_conf.sh | 7 + tests/integration/test_gogs.py | 123 +++++++++ 23 files changed, 1544 insertions(+), 2 deletions(-) create mode 100644 git_repo/services/ext/gogs.py create mode 100644 tests/integration/cassettes/test_gogs_test_01_create__already_exists.json create mode 100644 tests/integration/cassettes/test_gogs_test_01_create__new.json create mode 100644 tests/integration/cassettes/test_gogs_test_01_create_group__already_exists.json create mode 100644 tests/integration/cassettes/test_gogs_test_01_create_group__new.json create mode 100644 tests/integration/cassettes/test_gogs_test_02_delete.json create mode 100644 tests/integration/cassettes/test_gogs_test_03_delete_nouser.json create mode 100644 tests/integration/cassettes/test_gogs_test_04_clone.json create mode 100644 tests/integration/cassettes/test_gogs_test_05_add.json create mode 100644 tests/integration/cassettes/test_gogs_test_06_add__name.json create mode 100644 tests/integration/cassettes/test_gogs_test_07_add__alone.json create mode 100644 tests/integration/cassettes/test_gogs_test_08_add__alone_name.json create mode 100644 tests/integration/cassettes/test_gogs_test_09_add__default.json create mode 100644 tests/integration/cassettes/test_gogs_test_10_add__default_name.json create mode 100644 tests/integration/cassettes/test_gogs_test_11_add__alone_default.json create mode 100644 tests/integration/cassettes/test_gogs_test_12_add__alone_default_name.json create mode 100644 tests/integration/local/gogs/README.md create mode 100644 tests/integration/local/gogs/custom/conf/app.ini create mode 100755 tests/integration/local/gogs/init.sh create mode 100755 tests/integration/local/gogs/init_conf.sh create mode 100644 tests/integration/test_gogs.py diff --git a/README.md b/README.md index bcfa7d3..0e2c8de 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ very simple. To clone a new project, out of GitHub, just issue: % git hub clone guyzmo/git-repo -But that works also with a project from GitLab, Bitbucket, or your own GitLab: +But that works also with a project from GitLab, Bitbucket, your own GitLab or Gogs: % git lab clone guyzmo/git-repo % git bb clone guyzmo/git-repo % git myprecious clone guyzmo/git-repo + % git gg clone guyzmo/git-repo If you want to can choose the default branch to clone: @@ -151,6 +152,10 @@ section in the gitconfig: [gitrepo "bitbucket"] token = username:password + [gitrepo "gogs"] + fqdn = UrlOfYourGogs + token = YourVerySecretKey + Here, we're setting the basics: just the private token. You'll notice that for bitbucket the private token is your username and password seperated by a column. That's because bitbucket does not offer throw away private tokens for tools (I might implement BB's OAuth @@ -253,9 +258,11 @@ To use your own credentials, you can setup the following environment variables: * `GITHUB_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on GitHub * `GITLAB_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on GitLab * `BITBUCKET_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on Bitbucket +* `GOGS_NAMESPACE` (which defaults to `not_configured`) is the name of the account to use on Gogs * `PRIVATE_KEY_GITHUB` your private token you've setup on GitHub for your account * `PRIVATE_KEY_GITLAB` your private token you've setup on GitLab for your account * `PRIVATE_KEY_BITBUCKET` your private token you've setup on Bitbucket for your account +* `PRIVATE_KEY_GOGS` your private token you've setup on Gogs for your account ### TODO @@ -278,7 +285,7 @@ To use your own credentials, you can setup the following environment variables: * [ ] add application token support for bitbucket (cf [#14](https://github.com/guyzmo/git-repo/issues/14)) * [ ] add support for managing SSH keys (cf [#22](https://github.com/guyzmo/git-repo/issues/22)) * [ ] add support for issues? -* [ ] add support for gogs (cf [#18](https://github.com/guyzmo/git-repo/issues/18)) +* [x] add support for gogs (cf [#18](https://github.com/guyzmo/git-repo/issues/18)) * [ ] add support for gerrit (cf [#19](https://github.com/guyzmo/git-repo/issues/19)) * [ ] do what's needed to make a nice documentation — if possible in markdown !@#$ * for more features, write an issue or, even better, a PR! diff --git a/git_repo/services/ext/gogs.py b/git_repo/services/ext/gogs.py new file mode 100644 index 0000000..2823e76 --- /dev/null +++ b/git_repo/services/ext/gogs.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +import sys +import logging +log = logging.getLogger('git_repo.gogs') + +from ..service import register_target, RepositoryService, os +from ...exceptions import ResourceError, ResourceExistsError, ResourceNotFoundError + +import gogs_client +import requests +from urllib.parse import urlparse, urlunparse +import functools + +from git import config as git_config +from git.exc import GitCommandError + +@register_target('gg', 'gogs') +class GogsService(RepositoryService): + fqdn = 'try.gogs.io' + #fqdn = 'http://127.0.0.1:3000' + gg = None + + def __init__(self, *args, **kwargs): + self.session = requests.Session() + RepositoryService.__init__(self, *args, **kwargs) + self.ensure_init() + + def ensure_init(self): + if self.gg is not None: + return + self.url_base, self.fqdn = self._url_parse(self.fqdn) + if 'insecure' not in self.config: + self.insecure = self.fqdn != 'try.gogs.io' + self.session.verify = not self.insecure + if 'server-cert' in self.config: + self.session.verify = self.config['server-cert'] + self.default_private = self.config.get('default-private', 'false').lower() not in ('0','no','false') + self.ssh_url = self.config.get('ssh-url', None) or self.fqdn + if not self.repository: + config = git_config.GitConfigParser(os.path.join(os.environ['HOME'], '.gitconfig'), True) + else: + config = self.repository.config_reader() + proxies = {} + for scheme in 'http https'.split(): + proxy = config.get_value(scheme, 'proxy', '') + if proxy: + proxies[scheme] = proxy + self.session.proxies.update(proxies) + self.gg = gogs_client.GogsApi(self.url_base, self.session) + #if ':' in self._privatekey: + # self.auth = gogs_client.UsernamePassword(*self._privatekey.split(':',1)) + #else: + self.auth = gogs_client.Token(self._privatekey) + + @classmethod + def _url_parse(cls, url): + if '://' not in url: + url = 'https://'+url + parse = urlparse(url) + url_base = urlunparse((parse.scheme, parse.netloc)+('',)*4) + fqdn = parse.hostname + return url_base, fqdn + + @property + def url_ro(self): + return self.url_base + + @property + def url_rw(self): + url = self.ssh_url + if '@' in url: + return url + return '@'.join([self.git_user, url]) + + @classmethod + def get_auth_token(cls, login, password, prompt=None): + import platform + name = 'git-repo2 token used on {}'.format(platform.node()) + if '/' in login: + url, login = login.rsplit('/', 1) + else: + url = input('URL [{}]> '.format(cls.fqdn)) or cls.fqdn + url_base, fqdn = cls._url_parse(url) + gg = gogs_client.GogsApi(url_base) + auth = gogs_client.UsernamePassword(login, password) + tokens = gg.get_tokens(auth, login) + tokens = dict((token.name, token.token) for token in tokens) + if name in tokens: + return tokens[name] + if 'git-repo2 token' in tokens: + return tokens['git-repo2 token'] + token = gg.create_token(auth, name, login) + return token.token + + @property + def user(self): + return self.gg.authenticated_user(self.auth).username + + def orgs(self): + orgs = self.gg._check_ok(self.gg._get('/user/orgs', auth=self.auth)).json() + #return [gogs_client.GogsUser.from_json(org) for org in orgs] + return [org['username'] for org in orgs] + + def connect(self): + self.ensure_init() + try: + if self.insecure: + try: + try: + urllib3 = requests.packages.urllib3 + except Exception: + import urllib3 + urllib3.disable_warnings() + except ImportError: + pass + self.username = self.user # Call to self.gg.authenticated_user() + except requests.HTTPError as err: + if err.response is not None and err.response.status_code == 401: + if not self._privatekey: + raise ConnectionError('Could not connect to GoGS. ' + 'Please configure .gitconfig ' + 'with your gogs private key.') from err + else: + raise ConnectionError('Could not connect to GoGS. ' + 'Check your configuration and try again.') from err + else: + raise err + + def create(self, user, repo, add=False): + try: + if user == self.username: + repository = self.gg.create_repo(self.auth, name=repo, private=self.default_private) + elif user in self.orgs(): + data = dict(name=repo, private=self.default_private) + response = self.gg._post('/org/{}/repos'.format(user), auth=self.auth, data=data) + repository = gogs_client.GogsRepo.from_json(self.gg._check_ok(response).json()) + else: + data = dict(name=repo, private=self.default_private) + response = self.gg._post('/admin/users/{}/repos'.format(user), auth=self.auth, data=data) + repository = gogs_client.GogsRepo.from_json(self.gg._check_ok(response).json()) + except gogs_client.ApiFailure as err: + if err.status_code == 422: + raise ResourceExistsError("Project already exists.") from err + else: + raise ResourceError("Unhandled error.") from err + except Exception as err: + raise ResourceError("Unhandled exception: {}".format(err)) from err + if add: + self.add(user=self.username, repo=repo, tracking=self.name) + + def fork(self, user, repo): + raise NotImplementedError + + def delete(self, repo, user=None): + if not user: + user = self.username + try: + self.gg.delete_repo(self.auth, user, repo) + except gogs_client.ApiFailure as err: + if err.status_code == 404: + raise ResourceNotFoundError("Cannot delete: repository {}/{} does not exists.".format(user, repo)) from err + elif err.status_code == 403: + raise ResourcePermissionError("You don't have enough permissions for deleting the repository. Check the namespace or the private token's privileges") from err + elif err.status_code == 422: + raise ResourceNotFoundError("Cannot delete repository {}/{}: user {} does not exists.".format(user, repo, user)) from err + raise ResourceError("Unhandled error: {}".format(err)) from err + except Exception as err: + raise ResourceError("Unhandled exception: {}".format(err)) from err + + def list(self, user, _long=False): + import shutil, sys + from datetime import datetime + term_width = shutil.get_terminal_size((80, 20)).columns + def col_print(lines, indent=0, pad=2): + # prints a list of items in a fashion similar to the dir command + # borrowed from https://gist.github.com/critiqjo/2ca84db26daaeb1715e1 + n_lines = len(lines) + if n_lines == 0: + return + col_width = max(len(line) for line in lines) + n_cols = int((term_width + pad - indent)/(col_width + pad)) + n_cols = min(n_lines, max(1, n_cols)) + col_len = int(n_lines/n_cols) + (0 if n_lines % n_cols == 0 else 1) + if (n_cols - 1) * col_len >= n_lines: + n_cols -= 1 + cols = [lines[i*col_len : i*col_len + col_len] for i in range(n_cols)] + rows = list(zip(*cols)) + rows_missed = zip(*[col[len(rows):] for col in cols[:-1]]) + rows.extend(rows_missed) + for row in rows: + print(" "*indent + (" "*pad).join(line.ljust(col_width) for line in row)) + + r = self.gg._get('/user/repos', auth=self.auth) + repositories = self.gg._check_ok(r).json() + repositories = [repo for repo in repositories if repo['owner']['username'] == user] + if user != self.username and not repositories and user not in self.orgs: + raise ResourceNotFoundError("Unable to list namespace {} - only authenticated user and orgs available for listing.".format(user)) + if not _long: + col_print([repo['full_name'] for repo in repositories]) + else: + print('Status\tCommits\tReqs\tIssues\tForks\tCoders\tWatch\tLikes\tLang\tModif\t\t\t\tName', file=sys.stderr) + for repo in repositories: + status = ''.join([ + 'F' if repo['fork'] else ' ', # is a fork? + 'P' if repo['private'] else ' ', # is private? + ]) + try: + issues = self.gg._check_ok(self.gg._get('/repos/{}/issues'.format(repo['full_name']), auth=self.auth)).json() + except Exception: + issues = [] + print('\t'.join([ + # status + status, + # stats + str(len(list(()))), # number of commits + str(len(list(()))), # number of pulls + str(len(list(issues))), # number of issues + str(repo.get('forks_count') or 0), # number of forks + str(len(list(()))), # number of contributors + str(repo.get('watchers_count') or 0), # number of subscribers + str(repo.get('stars_count') or 0), # number of ♥ + # info + repo.get('language') or '?', # language + repo['updated_at'], # date + repo['full_name'], # name + ])) + + def get_repository(self, user, repo): + try: + return self.gg.get_repo(self.auth, user, repo) + except gogs_client.ApiFailure as err: + if err.status_code == 404: + raise ResourceNotFoundError("Cannot get: repository {}/{} does not exists.".format(user, repo)) from err + raise ResourceError("Unhandled error: {}".format(err)) from err + except Exception as err: + raise ResourceError("Unhandled exception: {}".format(err)) from err + + def gist_list(self, gist=None): + raise NotImplementedError + + def gist_fetch(self, gist, fname=None): + raise NotImplementedError + + def gist_clone(self, gist): + raise NotImplementedError + + def gist_create(self, gist_pathes, description, secret=False): + raise NotImplementedError + + def gist_delete(self, gist_id): + raise NotImplementedError + + def request_create(self, user, repo, local_branch, remote_branch, title, description=None): + raise NotImplementedError + + def request_list(self, user, repo): + raise NotImplementedError + + def request_fetch(self, user, repo, request, pull=False): + raise NotImplementedError diff --git a/requirements.txt b/requirements.txt index 6a165a3..811d2e1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ uritemplate.py==2.0.0 github3.py==0.9.5 python-gitlab>=0.18 bitbucket-api +gogs-client>=1.0.3 diff --git a/tests/integration/cassettes/test_gogs_test_01_create__already_exists.json b/tests/integration/cassettes/test_gogs_test_01_create__already_exists.json new file mode 100644 index 0000000..f62c421 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_01_create__already_exists.json @@ -0,0 +1,79 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:09", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:09 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:09", + "request": { + "body": { + "encoding": "utf-8", + "string": "name=git-repo&auto_init=False&private=False" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "43", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": "i_like_gogits=8454d8bde5123653; _csrf=AaMYap7BESTX7xci37mALGGEVaA6MTQ4NTAwNzQ0ODg5OTkxMDkwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "POST", + "uri": "http://127.0.0.1:3000/api/v1/user/repos?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"message\":\"repository already exists [uname: , name: git-repo]\",\"url\":\"https://godoc.org/github.com/go-gitea/go-sdk/gitea\"}" + }, + "headers": { + "Content-Length": "137", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:09 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "url": "http://127.0.0.1:3000/api/v1/user/repos?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_01_create__new.json b/tests/integration/cassettes/test_gogs_test_01_create__new.json new file mode 100644 index 0000000..77175c1 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_01_create__new.json @@ -0,0 +1,115 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:07", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:07 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:08", + "request": { + "body": { + "encoding": "utf-8", + "string": "name=foobar&auto_init=False&private=False" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "41", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": "i_like_gogits=56e0adf87767e97e; _csrf=dBK1EojZjHkQKQ4Cbizf4wdbqL46MTQ4NTAwNzQ0NzE2OTc4MzcwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "POST", + "uri": "http://127.0.0.1:3000/api/v1/user/repos?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":4,\"owner\":{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"},\"name\":\"foobar\",\"full_name\":\"/foobar\",\"description\":\"\",\"private\":false,\"fork\":false,\"html_url\":\"http://127.0.0.1:3000//foobar\",\"ssh_url\":\"ssh://git@:3022//foobar.git\",\"clone_url\":\"http://127.0.0.1:3000//foobar.git\",\"website\":\"\",\"stars_count\":0,\"forks_count\":0,\"watchers_count\":0,\"open_issues_count\":0,\"default_branch\":\"\",\"created_at\":\"0001-01-01T00:00:00Z\",\"updated_at\":\"0001-01-01T00:00:00Z\",\"permissions\":{\"admin\":true,\"push\":true,\"pull\":true}}" + }, + "headers": { + "Content-Length": "667", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:08 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 201, + "message": "Created" + }, + "url": "http://127.0.0.1:3000/api/v1/user/repos?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:08", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=56e0adf87767e97e; _csrf=dBK1EojZjHkQKQ4Cbizf4wdbqL46MTQ4NTAwNzQ0NzE2OTc4MzcwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":4,\"owner\":{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"},\"name\":\"foobar\",\"full_name\":\"/foobar\",\"description\":\"\",\"private\":false,\"fork\":false,\"html_url\":\"http://127.0.0.1:3000//foobar\",\"ssh_url\":\"ssh://git@:3022//foobar.git\",\"clone_url\":\"http://127.0.0.1:3000//foobar.git\",\"website\":\"\",\"stars_count\":0,\"forks_count\":0,\"watchers_count\":1,\"open_issues_count\":0,\"default_branch\":\"master\",\"created_at\":\"2017-01-21T17:04:07+03:00\",\"updated_at\":\"2017-01-21T17:04:07+03:00\",\"permissions\":{\"admin\":true,\"push\":true,\"pull\":true}}" + }, + "headers": { + "Content-Length": "683", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:08 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_01_create_group__already_exists.json b/tests/integration/cassettes/test_gogs_test_01_create_group__already_exists.json new file mode 100644 index 0000000..ee5b03b --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_01_create_group__already_exists.json @@ -0,0 +1,115 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:11", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:11 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:11", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=4c6537fcc9af60e8; _csrf=pcfgJf1T3db7bk-PcSxpoUq7oi46MTQ4NTAwNzQ1MTQzNjU3MzMwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user/orgs?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "[{\"id\":4,\"username\":\"guyzmo\",\"full_name\":\"\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/4\",\"description\":\"\",\"website\":\"\",\"location\":\"\"}]" + }, + "headers": { + "Content-Length": "136", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:11 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user/orgs?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:11", + "request": { + "body": { + "encoding": "utf-8", + "string": "name=git-repo&private=False" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "27", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": "i_like_gogits=4c6537fcc9af60e8; _csrf=pcfgJf1T3db7bk-PcSxpoUq7oi46MTQ4NTAwNzQ1MTQzNjU3MzMwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "POST", + "uri": "http://127.0.0.1:3000/api/v1/org/guyzmo/repos?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"message\":\"repository already exists [uname: guyzmo, name: git-repo]\",\"url\":\"https://godoc.org/github.com/go-gitea/go-sdk/gitea\"}" + }, + "headers": { + "Content-Length": "130", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:11 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "url": "http://127.0.0.1:3000/api/v1/org/guyzmo/repos?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_01_create_group__new.json b/tests/integration/cassettes/test_gogs_test_01_create_group__new.json new file mode 100644 index 0000000..25d4e8c --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_01_create_group__new.json @@ -0,0 +1,151 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:09", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:09 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:09", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=7d7bf3e2b6e2d99c; _csrf=I7ey25ruCsGuYX3RAE6vFn5UX3U6MTQ4NTAwNzQ0OTU2NTYzOTkwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user/orgs?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "[{\"id\":4,\"username\":\"guyzmo\",\"full_name\":\"\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/4\",\"description\":\"\",\"website\":\"\",\"location\":\"\"}]" + }, + "headers": { + "Content-Length": "136", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:09 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user/orgs?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:10", + "request": { + "body": { + "encoding": "utf-8", + "string": "name=foobar&private=False" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "25", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": "i_like_gogits=7d7bf3e2b6e2d99c; _csrf=I7ey25ruCsGuYX3RAE6vFn5UX3U6MTQ4NTAwNzQ0OTU2NTYzOTkwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "POST", + "uri": "http://127.0.0.1:3000/api/v1/org/guyzmo/repos?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":5,\"owner\":{\"id\":4,\"login\":\"guyzmo\",\"full_name\":\"\",\"email\":\"\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/4\",\"username\":\"guyzmo\"},\"name\":\"foobar\",\"full_name\":\"guyzmo/foobar\",\"description\":\"\",\"private\":false,\"fork\":false,\"html_url\":\"http://127.0.0.1:3000/guyzmo/foobar\",\"ssh_url\":\"ssh://git@:3022/guyzmo/foobar.git\",\"clone_url\":\"http://127.0.0.1:3000/guyzmo/foobar.git\",\"website\":\"\",\"stars_count\":0,\"forks_count\":0,\"watchers_count\":0,\"open_issues_count\":0,\"default_branch\":\"\",\"created_at\":\"0001-01-01T00:00:00Z\",\"updated_at\":\"0001-01-01T00:00:00Z\",\"permissions\":{\"admin\":true,\"push\":true,\"pull\":true}}" + }, + "headers": { + "Content-Length": "605", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:10 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 201, + "message": "Created" + }, + "url": "http://127.0.0.1:3000/api/v1/org/guyzmo/repos?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:11", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=7d7bf3e2b6e2d99c; _csrf=I7ey25ruCsGuYX3RAE6vFn5UX3U6MTQ4NTAwNzQ0OTU2NTYzOTkwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":5,\"owner\":{\"id\":4,\"login\":\"guyzmo\",\"full_name\":\"\",\"email\":\"\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/4\",\"username\":\"guyzmo\"},\"name\":\"foobar\",\"full_name\":\"guyzmo/foobar\",\"description\":\"\",\"private\":false,\"fork\":false,\"html_url\":\"http://127.0.0.1:3000/guyzmo/foobar\",\"ssh_url\":\"ssh://git@:3022/guyzmo/foobar.git\",\"clone_url\":\"http://127.0.0.1:3000/guyzmo/foobar.git\",\"website\":\"\",\"stars_count\":0,\"forks_count\":0,\"watchers_count\":2,\"open_issues_count\":0,\"default_branch\":\"master\",\"created_at\":\"2017-01-21T17:04:10+03:00\",\"updated_at\":\"2017-01-21T17:04:10+03:00\",\"permissions\":{\"admin\":true,\"push\":true,\"pull\":true}}" + }, + "headers": { + "Content-Length": "621", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:11 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_02_delete.json b/tests/integration/cassettes/test_gogs_test_02_delete.json new file mode 100644 index 0000000..c5a528c --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_02_delete.json @@ -0,0 +1,111 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:12", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:12 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:13", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "0", + "Cookie": "i_like_gogits=b5cab1c9d5e1def0; _csrf=fDp3VZsDXGVPx8B-9H_QXSn6epk6MTQ4NTAwNzQ1MjMzMDk0OTYwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "DELETE", + "uri": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + }, + "response": { + "body": { + "encoding": null, + "string": "" + }, + "headers": { + "Date": "Sat, 21 Jan 2017 14:04:13 GMT", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 204, + "message": "No Content" + }, + "url": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:13", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=b5cab1c9d5e1def0; _csrf=fDp3VZsDXGVPx8B-9H_QXSn6epk6MTQ4NTAwNzQ1MjMzMDk0OTYwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + }, + "response": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Content-Length": "0", + "Content-Type": "text/plain; charset=utf-8", + "Date": "Sat, 21 Jan 2017 14:04:13 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 404, + "message": "Not Found" + }, + "url": "http://127.0.0.1:3000/api/v1/repos/guyzmo/foobar?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_03_delete_nouser.json b/tests/integration/cassettes/test_gogs_test_03_delete_nouser.json new file mode 100644 index 0000000..3c079af --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_03_delete_nouser.json @@ -0,0 +1,111 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:14", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:14 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:15", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Content-Length": "0", + "Cookie": "i_like_gogits=c111a2e26ac164ec; _csrf=GFxZKCVK-D7xbFy7E2SKa8DtEbM6MTQ4NTAwNzQ1Mzk2MzQ3NzQwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "DELETE", + "uri": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + }, + "response": { + "body": { + "encoding": null, + "string": "" + }, + "headers": { + "Date": "Sat, 21 Jan 2017 14:04:15 GMT", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 204, + "message": "No Content" + }, + "url": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + } + }, + { + "recorded_at": "2017-01-21T14:04:15", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "Cookie": "i_like_gogits=c111a2e26ac164ec; _csrf=GFxZKCVK-D7xbFy7E2SKa8DtEbM6MTQ4NTAwNzQ1Mzk2MzQ3NzQwMA%3D%3D; lang=en-US", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + }, + "response": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Content-Length": "0", + "Content-Type": "text/plain; charset=utf-8", + "Date": "Sat, 21 Jan 2017 14:04:15 GMT", + "Proxy-Connection": "keep-alive", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 404, + "message": "Not Found" + }, + "url": "http://127.0.0.1:3000/api/v1/repos//foobar?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_04_clone.json b/tests/integration/cassettes/test_gogs_test_04_clone.json new file mode 100644 index 0000000..5ac4754 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_04_clone.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:15", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:15 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_05_add.json b/tests/integration/cassettes/test_gogs_test_05_add.json new file mode 100644 index 0000000..cd35864 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_05_add.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:16", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:16 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_06_add__name.json b/tests/integration/cassettes/test_gogs_test_06_add__name.json new file mode 100644 index 0000000..9eca356 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_06_add__name.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:17", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:17 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_07_add__alone.json b/tests/integration/cassettes/test_gogs_test_07_add__alone.json new file mode 100644 index 0000000..9eca356 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_07_add__alone.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:17", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:17 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_08_add__alone_name.json b/tests/integration/cassettes/test_gogs_test_08_add__alone_name.json new file mode 100644 index 0000000..9e0cf78 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_08_add__alone_name.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:18", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:18 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_09_add__default.json b/tests/integration/cassettes/test_gogs_test_09_add__default.json new file mode 100644 index 0000000..c504d8b --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_09_add__default.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:19", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:19 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_10_add__default_name.json b/tests/integration/cassettes/test_gogs_test_10_add__default_name.json new file mode 100644 index 0000000..450b95f --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_10_add__default_name.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:20", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:20 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_11_add__alone_default.json b/tests/integration/cassettes/test_gogs_test_11_add__alone_default.json new file mode 100644 index 0000000..450b95f --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_11_add__alone_default.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:20", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:20 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/cassettes/test_gogs_test_12_add__alone_default_name.json b/tests/integration/cassettes/test_gogs_test_12_add__alone_default_name.json new file mode 100644 index 0000000..8d71128 --- /dev/null +++ b/tests/integration/cassettes/test_gogs_test_12_add__alone_default_name.json @@ -0,0 +1,41 @@ +{ + "http_interactions": [ + { + "recorded_at": "2017-01-21T14:04:21", + "request": { + "body": { + "encoding": "utf-8", + "string": "" + }, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "identity", + "Connection": "keep-alive", + "User-Agent": "python-requests/2.12.4" + }, + "method": "GET", + "uri": "http://127.0.0.1:3000/api/v1/user?token=" + }, + "response": { + "body": { + "encoding": "UTF-8", + "string": "{\"id\":3,\"login\":\"\",\"full_name\":\"\",\"email\":\"guyzmo@gogs.loopback\",\"avatar_url\":\"http://127.0.0.1:3000/avatars/3\",\"username\":\"\"}" + }, + "headers": { + "Content-Length": "152", + "Content-Type": "application/json; charset=UTF-8", + "Date": "Sat, 21 Jan 2017 14:04:21 GMT", + "Proxy-Connection": "keep-alive", + "Set-Cookie": "lang=en-US; Path=/; Max-Age=2147483647", + "X-Frame-Options": "SAMEORIGIN" + }, + "status": { + "code": 200, + "message": "OK" + }, + "url": "http://127.0.0.1:3000/api/v1/user?token=" + } + } + ], + "recorded_with": "betamax/0.5.1" +} \ No newline at end of file diff --git a/tests/integration/local/gogs/README.md b/tests/integration/local/gogs/README.md new file mode 100644 index 0000000..55b06cd --- /dev/null +++ b/tests/integration/local/gogs/README.md @@ -0,0 +1,8 @@ +## Steps to re-create test environment + + * `cd /tests/integration/local/gogs` + * `./init_conf.sh` # this will change `custom/conf/app.ini` as repository/ROOT must be full path + * `/gogs web --config custom/conf/app.ini` # run with local config. Gitea also supported + * `./init.sh` # this will create users, organizations and repositories required for testing. Server must be completely started (listeninig) + +Under Windows cygwin bash required for scripts (mingw/msys not tested). diff --git a/tests/integration/local/gogs/custom/conf/app.ini b/tests/integration/local/gogs/custom/conf/app.ini new file mode 100644 index 0000000..5d7a495 --- /dev/null +++ b/tests/integration/local/gogs/custom/conf/app.ini @@ -0,0 +1,56 @@ +APP_NAME = git-repo gogs test +RUN_USER = git +RUN_MODE = prod + +[repository] +ROOT = gogs-repositories + +[database] +DB_TYPE = sqlite3 +HOST = 127.0.0.1:3306 +NAME = gogs +USER = root +PASSWD = +SSL_MODE = true +PATH = data/gogs.db + +[server] +DOMAIN = 127.0.0.1 +PROTOCOL = http +HTTP_ADDR = 127.0.0.1 +HTTP_PORT = 3000 +ROOT_URL = http://127.0.0.1:3000/ +DISABLE_SSH = false +START_SSH_SERVER = true +SSH_PORT = 3022 +OFFLINE_MODE = true + +[mailer] +ENABLED = false + +[service] +REGISTER_EMAIL_CONFIRM = false +ENABLE_NOTIFY_MAIL = false +DISABLE_REGISTRATION = true +ENABLE_CAPTCHA = false +REQUIRE_SIGNIN_VIEW = false + +[picture] +DISABLE_GRAVATAR = false +ENABLE_FEDERATED_AVATAR = false + +[session] +PROVIDER = file + +[log] +MODE = file +LEVEL = Info +ROOT_PATH = log + +[security] +INSTALL_LOCK = true + +[attachment] +ENABLED = true +PATH = private +ALLOWED_TYPES = */* diff --git a/tests/integration/local/gogs/init.sh b/tests/integration/local/gogs/init.sh new file mode 100755 index 0000000..cc6e2d4 --- /dev/null +++ b/tests/integration/local/gogs/init.sh @@ -0,0 +1,29 @@ +#!/bin/bash +echo "Checking user test-admin in Gogs on http://127.0.0.1:3000" +if python3 -c "import sys,gogs_client;up=gogs_client.UsernamePassword('test-admin','test-admin');s=gogs_client.GogsApi('http://127.0.0.1:3000');sys.exit(s.valid_authentication(up))" ; then + echo "Creating admin user test-admin" + gogs admin create-user --config custom/conf/app.ini --name=test-admin --password=test-admin --email=admin@gogs.loopback --admin=true +fi +echo "Checking user other in Gogs on http://127.0.0.1:3000" +if python3 -c "import sys,gogs_client;up=gogs_client.UsernamePassword('other','other');s=gogs_client.GogsApi('http://127.0.0.1:3000');sys.exit(s.valid_authentication(up))" ; then + echo "Creating user other" + gogs admin create-user --config custom/conf/app.ini --name=other --password=other --email=other@gogs.loopback + python3 -c "import os,gogs_client,functools;up=gogs_client.UsernamePassword('other','other');s=gogs_client.GogsApi('http://127.0.0.1:3000');r=s.create_repo(up,'git-repo',readme_template='Default',license_template='MIT License',auto_init=True);print('\t'.join(map(str,(r.repo_id,r.full_name,r.urls.ssh_url))))" +fi +echo "Checking user git-repo-test in Gogs on http://127.0.0.1:3000" +if python3 -c "import sys,gogs_client;up=gogs_client.UsernamePassword('git-repo-test','git-repo-test');s=gogs_client.GogsApi('http://127.0.0.1:3000');sys.exit(s.valid_authentication(up))" ; then + echo "Creating user git-repo-test" + gogs admin create-user --config custom/conf/app.ini --name=git-repo-test --password=git-repo-test --email=guyzmo@gogs.loopback +fi +echo "Creating access token for user git-repo-test in Gogs on http://127.0.0.1:3000" +export PRIVATE_KEY_GOGS=`python3 -c "import gogs_client;up=gogs_client.UsernamePassword('git-repo-test','git-repo-test');s=gogs_client.GogsApi('http://127.0.0.1:3000');t=s.ensure_token(up, 'git-repo');print(t.token)"` +echo "PRIVATE_KEY_GOGS=$PRIVATE_KEY_GOGS" +git config --global --replace-all gitrepo.gogs.fqdn "http://127.0.0.1:3000" +git config --global --replace-all gitrepo.gogs.token "$PRIVATE_KEY_GOGS" +echo "Creating repository git-repo under user git-repo-test in Gogs on http://127.0.0.1:3000" +python3 -c "import os,gogs_client,functools;t=gogs_client.Token(os.environ['PRIVATE_KEY_GOGS']);s=gogs_client.GogsApi('http://127.0.0.1:3000');r=[functools.partial(s.create_repo,t,'git-repo',readme_template='Default',license_template='MIT License',gitignore_templates=['Python'],auto_init=True),functools.partial(s.get_repo,t,'git-repo-test','git-repo')][bool(s.repo_exists(t,'git-repo-test','git-repo'))]();print('\t'.join(map(str,(r.repo_id,r.full_name,r.urls.ssh_url))))" +echo "Creating organization guyzmo for user git-repo-test in Gogs on http://127.0.0.1:3000" +python3 -c "import os,gogs_client;t=gogs_client.Token(os.environ['PRIVATE_KEY_GOGS']);up=gogs_client.UsernamePassword('test-admin','test-admin');s=gogs_client.GogsApi('http://127.0.0.1:3000');r=s._get('/users/guyzmo',auth=t);r=[lambda:s._check_ok(s._post('/admin/users/git-repo-test/orgs',auth=up,json={'username':'guyzmo'})),lambda:r][r.ok]().json();print('\t'.join(map(str,(r['id'],r['username'],r['avatar_url']))))" +#curl -iu test-admin:test-admin -H "Content-Type: application/json" --data "{""username"":""guyzmo""}" http://127.0.0.1:3000/api/v1/admin/users/git-repo-test/orgs +echo "Creating repository git-repo under organization guyzmo in Gogs on http://127.0.0.1:3000" +python3 -c "import os,gogs_client,functools;t=gogs_client.Token(os.environ['PRIVATE_KEY_GOGS']);s=gogs_client.GogsApi('http://127.0.0.1:3000');r=[lambda:gogs_client.GogsRepo.from_json(s._check_ok(s._post('/org/guyzmo/repos',t,json=dict(name='git-repo',readme='Default',license='MIT License',gitignore='Node',auto_init=True))).json()),functools.partial(s.get_repo,t,'guyzmo','git-repo')][bool(s.repo_exists(t,'guyzmo','git-repo'))]();print('\t'.join(map(str,(r.repo_id,r.full_name,r.urls.ssh_url))))" diff --git a/tests/integration/local/gogs/init_conf.sh b/tests/integration/local/gogs/init_conf.sh new file mode 100755 index 0000000..09db221 --- /dev/null +++ b/tests/integration/local/gogs/init_conf.sh @@ -0,0 +1,7 @@ +#!/bin/bash +if [[ `uname -o` == Cygwin ]] ; then + GOGS_ROOT=$(cmd /c cd|dos2unix)'\gogs-repositories' +else + GOGS_ROOT=$(pwd)'/gogs-repositories' +fi +python3 -c "import sys;from six.moves.configparser import ConfigParser;from six.moves import cStringIO;c=ConfigParser();c.read_string('[APP]\n'+open('custom/conf/app.ini').read());gogsroot=sys.argv[1].replace('\\\\','/');[lambda:0,sys.exit][c.get('repository','ROOT')==gogsroot]();f=cStringIO();c.set('repository','ROOT',gogsroot);print(c.get('repository','ROOT'));c.write(f);open('custom/conf/app.ini','w').write(f.getvalue().replace('[APP]\n',''))" "$GOGS_ROOT" diff --git a/tests/integration/test_gogs.py b/tests/integration/test_gogs.py new file mode 100644 index 0000000..ee52882 --- /dev/null +++ b/tests/integration/test_gogs.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +import logging + +################################################################################# +# Enable logging + +log = logging.getLogger('test.gogs') + +################################################################################# + +import os +import sys +import pytest + +from tests.helpers import GitRepoTestCase + +from git_repo.services.service import gogs +from git_repo.exceptions import ResourceExistsError + +class Test_Gogs(GitRepoTestCase): + log = log + fqdn = 'http://127.0.0.1:3000' + + @property + def local_namespace(self): + if 'GOGS_NAMESPACE' in os.environ: + return os.environ['GOGS_NAMESPACE'] + return 'git-repo-test' + + def get_service(self): + gogs.GogsService.fqdn = self.fqdn + return gogs.GogsService(c=dict()) + # return gogs.GogsService(c=dict(fqdn=self.fqdn,__name__='gitrepo "gogs"',token=os.environ['PRIVATE_KEY_GOGS'])) + + def get_requests_session(self): + return self.service.session + + def test_00_fork(self): + pass + #self.action_fork(local_namespace=self.local_namespace, + # remote_namespace='sigmavirus24', + # repository='github3-py') + + def test_01_create__new(self): + self.action_create(namespace=self.local_namespace, + repository='foobar') + + def test_01_create__already_exists(self): + with pytest.raises(ResourceExistsError): + self.action_create(namespace=self.local_namespace, + repository='git-repo') + + def test_01_create_group__new(self): + self.action_create(namespace='guyzmo', + repository='foobar') + + def test_01_create_group__already_exists(self): + with pytest.raises(ResourceExistsError): + self.action_create(namespace='guyzmo', + repository='git-repo') + + + def test_02_delete(self): + self.action_delete(namespace='guyzmo', + repository='foobar') + + def test_03_delete_nouser(self): + self.action_delete(repository='foobar') + + def test_04_clone(self): + self.action_clone(namespace=self.local_namespace, + repository='git-repo') + + def test_05_add(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo') + + def test_06_add__name(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + name='test0r') + + def test_07_add__alone(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + alone=True) + + def test_08_add__alone_name(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + name='test0r', + alone=True) + + def test_09_add__default(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + tracking='gogs') + + def test_10_add__default_name(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + name='test0r', + tracking='gogs') + + def test_11_add__alone_default(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + alone=True, + tracking='gogs') + + def test_12_add__alone_default_name(self): + self.action_add(namespace=self.local_namespace, + repository='git-repo', + alone=True, + name='test0r', + tracking='gogs') + + def test_13_open(self): + self.action_open(namespace=self.local_namespace, + repository='git-repo') + +