summaryrefslogtreecommitdiff
path: root/gitlab/tests/objects
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2020-04-17 02:26:28 +0200
committerNejc Habjan <nejc.habjan@siemens.com>2020-08-22 20:09:52 +0200
commit76b2cadf1418e4ea2ac420ebba5a4b4f16fbd4c7 (patch)
tree4dbe6ae57c4f03e1351f7a49e590cbbc6d31121a /gitlab/tests/objects
parent11383e70f74c70e6fe8a56f18b5b170db982f402 (diff)
downloadgitlab-76b2cadf1418e4ea2ac420ebba5a4b4f16fbd4c7.tar.gz
refactor: split unit tests by GitLab API resources
Diffstat (limited to 'gitlab/tests/objects')
-rw-r--r--gitlab/tests/objects/test_application.py226
-rw-r--r--gitlab/tests/objects/test_commits.py74
-rw-r--r--gitlab/tests/objects/test_deploy_tokens.py44
-rw-r--r--gitlab/tests/objects/test_deployments.py53
-rw-r--r--gitlab/tests/objects/test_environments.py31
-rw-r--r--gitlab/tests/objects/test_groups.py121
-rw-r--r--gitlab/tests/objects/test_hooks.py23
-rw-r--r--gitlab/tests/objects/test_issues.py42
-rw-r--r--gitlab/tests/objects/test_pipeline_schedules.py71
-rw-r--r--gitlab/tests/objects/test_project_import_export.py129
-rw-r--r--gitlab/tests/objects/test_project_statistics.py29
-rw-r--r--gitlab/tests/objects/test_projects.py718
-rw-r--r--gitlab/tests/objects/test_remote_mirrors.py103
-rw-r--r--gitlab/tests/objects/test_services.py134
-rw-r--r--gitlab/tests/objects/test_snippets.py121
-rw-r--r--gitlab/tests/objects/test_submodules.py58
-rw-r--r--gitlab/tests/objects/test_todos.py58
-rw-r--r--gitlab/tests/objects/test_users.py94
18 files changed, 1379 insertions, 750 deletions
diff --git a/gitlab/tests/objects/test_application.py b/gitlab/tests/objects/test_application.py
index a10691b..356f0d3 100644
--- a/gitlab/tests/objects/test_application.py
+++ b/gitlab/tests/objects/test_application.py
@@ -1,120 +1,108 @@
-import unittest
-import gitlab
-import os
-import pickle
-import tempfile
+"""
+GitLab API: https://docs.gitlab.com/ce/api/applications.html
+"""
+
import json
-import unittest
-import requests
-from gitlab import * # noqa
-from gitlab.v4.objects import * # noqa
-from httmock import HTTMock, urlmatch, response # noqa
-
-
-headers = {"content-type": "application/json"}
-
-
-class TestApplicationAppearance(unittest.TestCase):
- def setUp(self):
- self.gl = Gitlab(
- "http://localhost",
- private_token="private_token",
- ssl_verify=True,
- api_version="4",
- )
- self.title = "GitLab Test Instance"
- self.new_title = "new-title"
- self.description = "gitlab-test.example.com"
- self.new_description = "new-description"
-
- def test_get_update_appearance(self):
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/application/appearance",
- method="get",
- )
- def resp_get_appearance(url, request):
- content = """{
- "title": "%s",
- "description": "%s",
- "logo": "/uploads/-/system/appearance/logo/1/logo.png",
- "header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
- "favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
- "new_project_guidelines": "Please read the FAQs for help.",
- "header_message": "",
- "footer_message": "",
- "message_background_color": "#e75e40",
- "message_font_color": "#ffffff",
- "email_header_and_footer_enabled": false}""" % (
- self.title,
- self.description,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/application/appearance",
- method="put",
- )
- def resp_update_appearance(url, request):
- content = """{
- "title": "%s",
- "description": "%s",
- "logo": "/uploads/-/system/appearance/logo/1/logo.png",
- "header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
- "favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
- "new_project_guidelines": "Please read the FAQs for help.",
- "header_message": "",
- "footer_message": "",
- "message_background_color": "#e75e40",
- "message_font_color": "#ffffff",
- "email_header_and_footer_enabled": false}""" % (
- self.new_title,
- self.new_description,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- with HTTMock(resp_get_appearance), HTTMock(resp_update_appearance):
- appearance = self.gl.appearance.get()
- assert appearance.title == self.title
- assert appearance.description == self.description
- appearance.title = self.new_title
- appearance.description = self.new_description
- appearance.save()
- assert appearance.title == self.new_title
- assert appearance.description == self.new_description
-
- def test_update_appearance(self):
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/application/appearance",
- method="put",
- )
- def resp_update_appearance(url, request):
- content = """{
- "title": "%s",
- "description": "%s",
- "logo": "/uploads/-/system/appearance/logo/1/logo.png",
- "header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
- "favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
- "new_project_guidelines": "Please read the FAQs for help.",
- "header_message": "",
- "footer_message": "",
- "message_background_color": "#e75e40",
- "message_font_color": "#ffffff",
- "email_header_and_footer_enabled": false}""" % (
- self.new_title,
- self.new_description,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- with HTTMock(resp_update_appearance):
- resp = self.gl.appearance.update(
- title=self.new_title, description=self.new_description
- )
+
+from httmock import urlmatch, response, with_httmock # noqa
+
+from .mocks import headers
+
+
+title = "GitLab Test Instance"
+description = "gitlab-test.example.com"
+new_title = "new-title"
+new_description = "new-description"
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/applications", method="post",
+)
+def resp_application_create(url, request):
+ content = '{"name": "test_app", "redirect_uri": "http://localhost:8080", "scopes": ["api", "email"]}'
+ json_content = json.loads(content)
+ return response(200, json_content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/application/appearance",
+ method="get",
+)
+def resp_get_appearance(url, request):
+ content = """{
+ "title": "%s",
+ "description": "%s",
+ "logo": "/uploads/-/system/appearance/logo/1/logo.png",
+ "header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
+ "favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
+ "new_project_guidelines": "Please read the FAQs for help.",
+ "header_message": "",
+ "footer_message": "",
+ "message_background_color": "#e75e40",
+ "message_font_color": "#ffffff",
+ "email_header_and_footer_enabled": false}""" % (
+ title,
+ description,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/application/appearance",
+ method="put",
+)
+def resp_update_appearance(url, request):
+ content = """{
+ "title": "%s",
+ "description": "%s",
+ "logo": "/uploads/-/system/appearance/logo/1/logo.png",
+ "header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
+ "favicon": "/uploads/-/system/appearance/favicon/1/favicon.png",
+ "new_project_guidelines": "Please read the FAQs for help.",
+ "header_message": "",
+ "footer_message": "",
+ "message_background_color": "#e75e40",
+ "message_font_color": "#ffffff",
+ "email_header_and_footer_enabled": false}""" % (
+ new_title,
+ new_description,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@with_httmock(resp_application_create)
+def test_create_application(gl):
+ application = gl.applications.create(
+ {
+ "name": "test_app",
+ "redirect_uri": "http://localhost:8080",
+ "scopes": ["api", "email"],
+ "confidential": False,
+ }
+ )
+ assert application.name == "test_app"
+ assert application.redirect_uri == "http://localhost:8080"
+ assert application.scopes == ["api", "email"]
+
+
+@with_httmock(resp_get_appearance, resp_update_appearance)
+def test_get_update_appearance(gl):
+ appearance = gl.appearance.get()
+ assert appearance.title == title
+ assert appearance.description == description
+ appearance.title = new_title
+ appearance.description = new_description
+ appearance.save()
+ assert appearance.title == new_title
+ assert appearance.description == new_description
+
+
+@with_httmock(resp_update_appearance)
+def test_update_application_appearance(gl):
+ resp = gl.appearance.update(title=new_title, description=new_description)
diff --git a/gitlab/tests/objects/test_commits.py b/gitlab/tests/objects/test_commits.py
index bf7d5a8..eaa7b82 100644
--- a/gitlab/tests/objects/test_commits.py
+++ b/gitlab/tests/objects/test_commits.py
@@ -1,7 +1,10 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/commits.html
+"""
+
from httmock import urlmatch, response, with_httmock
from .mocks import headers
-from .test_projects import TestProject
@urlmatch(
@@ -69,39 +72,36 @@ def resp_get_commit_gpg_signature(url, request):
return response(200, content, headers, None, 5, request)
-class TestCommit(TestProject):
- """
- Base class for commit tests. Inherits from TestProject,
- since currently all commit methods are under projects.
- """
-
- @with_httmock(resp_get_commit)
- def test_get_commit(self):
- commit = self.project.commits.get("6b2257ea")
- assert commit.short_id == "6b2257ea"
- assert commit.title == "Initial commit"
-
- @with_httmock(resp_create_commit)
- def test_create_commit(self):
- data = {
- "branch": "master",
- "commit_message": "Commit message",
- "actions": [{"action": "create", "file_path": "README", "content": "",}],
- }
- commit = self.project.commits.create(data)
- assert commit.short_id == "ed899a2f"
- assert commit.title == data["commit_message"]
-
- @with_httmock(resp_revert_commit)
- def test_revert_commit(self):
- commit = self.project.commits.get("6b2257ea", lazy=True)
- revert_commit = commit.revert(branch="master")
- assert revert_commit["short_id"] == "8b090c1b"
- assert revert_commit["title"] == 'Revert "Initial commit"'
-
- @with_httmock(resp_get_commit_gpg_signature)
- def test_get_commit_gpg_signature(self):
- commit = self.project.commits.get("6b2257ea", lazy=True)
- signature = commit.signature()
- assert signature["gpg_key_primary_keyid"] == "8254AAB3FBD54AC9"
- assert signature["verification_status"] == "verified"
+@with_httmock(resp_get_commit)
+def test_get_commit(project):
+ commit = project.commits.get("6b2257ea")
+ assert commit.short_id == "6b2257ea"
+ assert commit.title == "Initial commit"
+
+
+@with_httmock(resp_create_commit)
+def test_create_commit(project):
+ data = {
+ "branch": "master",
+ "commit_message": "Commit message",
+ "actions": [{"action": "create", "file_path": "README", "content": "",}],
+ }
+ commit = project.commits.create(data)
+ assert commit.short_id == "ed899a2f"
+ assert commit.title == data["commit_message"]
+
+
+@with_httmock(resp_revert_commit)
+def test_revert_commit(project):
+ commit = project.commits.get("6b2257ea", lazy=True)
+ revert_commit = commit.revert(branch="master")
+ assert revert_commit["short_id"] == "8b090c1b"
+ assert revert_commit["title"] == 'Revert "Initial commit"'
+
+
+@with_httmock(resp_get_commit_gpg_signature)
+def test_get_commit_gpg_signature(project):
+ commit = project.commits.get("6b2257ea", lazy=True)
+ signature = commit.signature()
+ assert signature["gpg_key_primary_keyid"] == "8254AAB3FBD54AC9"
+ assert signature["verification_status"] == "verified"
diff --git a/gitlab/tests/objects/test_deploy_tokens.py b/gitlab/tests/objects/test_deploy_tokens.py
new file mode 100644
index 0000000..b98a670
--- /dev/null
+++ b/gitlab/tests/objects/test_deploy_tokens.py
@@ -0,0 +1,44 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import ProjectDeployToken
+
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/deploy_tokens",
+ method="post",
+)
+def resp_deploy_token_create(url, request):
+ content = """{
+ "id": 1,
+ "name": "test_deploy_token",
+ "username": "custom-user",
+ "expires_at": "2022-01-01T00:00:00.000Z",
+ "token": "jMRvtPNxrn3crTAGukpZ",
+ "scopes": [ "read_repository" ]}"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_deploy_token_create)
+def test_deploy_tokens(gl):
+ deploy_token = gl.projects.get(1, lazy=True).deploytokens.create(
+ {
+ "name": "test_deploy_token",
+ "expires_at": "2022-01-01T00:00:00.000Z",
+ "username": "custom-user",
+ "scopes": ["read_repository"],
+ }
+ )
+ assert isinstance(deploy_token, ProjectDeployToken)
+ assert deploy_token.id == 1
+ assert deploy_token.expires_at == "2022-01-01T00:00:00.000Z"
+ assert deploy_token.username == "custom-user"
+ assert deploy_token.scopes == ["read_repository"]
diff --git a/gitlab/tests/objects/test_deployments.py b/gitlab/tests/objects/test_deployments.py
new file mode 100644
index 0000000..098251a
--- /dev/null
+++ b/gitlab/tests/objects/test_deployments.py
@@ -0,0 +1,53 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/deployments.html
+"""
+
+import json
+
+from httmock import response, urlmatch, with_httmock
+
+from .mocks import headers
+
+content = '{"id": 42, "status": "success", "ref": "master"}'
+json_content = json.loads(content)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/deployments",
+ method="post",
+)
+def resp_deployment_create(url, request):
+ return response(200, json_content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/deployments/42",
+ method="put",
+)
+def resp_deployment_update(url, request):
+ return response(200, json_content, headers, None, 5, request)
+
+
+@with_httmock(resp_deployment_create, resp_deployment_update)
+def test_deployment(project):
+ deployment = project.deployments.create(
+ {
+ "environment": "Test",
+ "sha": "1agf4gs",
+ "ref": "master",
+ "tag": False,
+ "status": "created",
+ }
+ )
+ assert deployment.id == 42
+ assert deployment.status == "success"
+ assert deployment.ref == "master"
+
+ json_content["status"] = "failed"
+ deployment.status = "failed"
+ deployment.save()
+ assert deployment.status == "failed"
diff --git a/gitlab/tests/objects/test_environments.py b/gitlab/tests/objects/test_environments.py
new file mode 100644
index 0000000..3175c64
--- /dev/null
+++ b/gitlab/tests/objects/test_environments.py
@@ -0,0 +1,31 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/environments.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import ProjectEnvironment
+
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/environments/1",
+ method="get",
+)
+def resp_get_environment(url, request):
+ content = '{"name": "environment_name", "id": 1, "last_deployment": "sometime"}'.encode(
+ "utf-8"
+ )
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_environment)
+def test_project_environments(project):
+ environment = project.environments.get(1)
+ assert isinstance(environment, ProjectEnvironment)
+ assert environment.id == 1
+ assert environment.last_deployment == "sometime"
+ assert environment.name == "environment_name"
diff --git a/gitlab/tests/objects/test_groups.py b/gitlab/tests/objects/test_groups.py
index 12ebdb2..b5464b5 100644
--- a/gitlab/tests/objects/test_groups.py
+++ b/gitlab/tests/objects/test_groups.py
@@ -1,4 +1,8 @@
-import unittest
+"""
+GitLab API: https://docs.gitlab.com/ce/api/groups.html
+"""
+
+import pytest
from httmock import response, urlmatch, with_httmock
@@ -36,66 +40,55 @@ def resp_create_import(url, request):
return response(202, content, headers, None, 25, request)
-class TestGroup(unittest.TestCase):
- def setUp(self):
- self.gl = gitlab.Gitlab(
- "http://localhost",
- private_token="private_token",
- ssl_verify=True,
- api_version=4,
- )
-
- @with_httmock(resp_get_group)
- def test_get_group(self):
- data = self.gl.groups.get(1)
- assert isinstance(data, gitlab.v4.objects.Group)
- assert data.name == "name"
- assert data.path == "path"
- assert data.id == 1
-
- @with_httmock(resp_create_group)
- def test_create_group(self):
- name, path = "name", "path"
- data = self.gl.groups.create({"name": name, "path": path})
- assert isinstance(data, gitlab.v4.objects.Group)
- assert data.name == name
- assert data.path == path
-
-
-class TestGroupExport(TestGroup):
- def setUp(self):
- super(TestGroupExport, self).setUp()
- self.group = self.gl.groups.get(1, lazy=True)
-
- @with_httmock(resp_create_export)
- def test_create_group_export(self):
- export = self.group.exports.create()
- assert export.message == "202 Accepted"
-
- @unittest.skip("GitLab API endpoint not implemented")
- @with_httmock(resp_create_export)
- def test_refresh_group_export_status(self):
- export = self.group.exports.create()
- export.refresh()
- assert export.export_status == "finished"
-
- @with_httmock(resp_create_export, resp_download_export)
- def test_download_group_export(self):
- export = self.group.exports.create()
- download = export.download()
- assert isinstance(download, bytes)
- assert download == binary_content
-
-
-class TestGroupImport(TestGroup):
- @with_httmock(resp_create_import)
- def test_import_group(self):
- group_import = self.gl.groups.import_group("file", "api-group", "API Group")
- assert group_import["message"] == "202 Accepted"
-
- @unittest.skip("GitLab API endpoint not implemented")
- @with_httmock(resp_create_import)
- def test_refresh_group_import_status(self):
- group_import = self.group.imports.get()
- group_import.refresh()
- assert group_import.import_status == "finished"
+@with_httmock(resp_get_group)
+def test_get_group(gl):
+ data = gl.groups.get(1)
+ assert isinstance(data, gitlab.v4.objects.Group)
+ assert data.name == "name"
+ assert data.path == "path"
+ assert data.id == 1
+
+
+@with_httmock(resp_create_group)
+def test_create_group(gl):
+ name, path = "name", "path"
+ data = gl.groups.create({"name": name, "path": path})
+ assert isinstance(data, gitlab.v4.objects.Group)
+ assert data.name == name
+ assert data.path == path
+
+
+@with_httmock(resp_create_export)
+def test_create_group_export(group):
+ export = group.exports.create()
+ assert export.message == "202 Accepted"
+
+
+@pytest.mark.skip("GitLab API endpoint not implemented")
+@with_httmock(resp_create_export)
+def test_refresh_group_export_status(group):
+ export = group.exports.create()
+ export.refresh()
+ assert export.export_status == "finished"
+
+
+@with_httmock(resp_create_export, resp_download_export)
+def test_download_group_export(group):
+ export = group.exports.create()
+ download = export.download()
+ assert isinstance(download, bytes)
+ assert download == binary_content
+
+
+@with_httmock(resp_create_import)
+def test_import_group(gl):
+ group_import = gl.groups.import_group("file", "api-group", "API Group")
+ assert group_import["message"] == "202 Accepted"
+
+
+@pytest.mark.skip("GitLab API endpoint not implemented")
+@with_httmock(resp_create_import)
+def test_refresh_group_import_status(group):
+ group_import = group.imports.get()
+ group_import.refresh()
+ assert group_import.import_status == "finished"
diff --git a/gitlab/tests/objects/test_hooks.py b/gitlab/tests/objects/test_hooks.py
new file mode 100644
index 0000000..45403c4
--- /dev/null
+++ b/gitlab/tests/objects/test_hooks.py
@@ -0,0 +1,23 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/system_hooks.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import Hook
+
+from .mocks import headers
+
+
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/hooks/1", method="get")
+def resp_get_hook(url, request):
+ content = '{"url": "testurl", "id": 1}'.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_hook)
+def test_hooks(gl):
+ data = gl.hooks.get(1)
+ assert isinstance(data, Hook)
+ assert data.url == "testurl"
+ assert data.id == 1
diff --git a/gitlab/tests/objects/test_issues.py b/gitlab/tests/objects/test_issues.py
new file mode 100644
index 0000000..e094841
--- /dev/null
+++ b/gitlab/tests/objects/test_issues.py
@@ -0,0 +1,42 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/issues.html
+"""
+
+from httmock import urlmatch, response, with_httmock
+
+from .mocks import headers
+from gitlab.v4.objects import ProjectIssuesStatistics
+
+
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/issues", method="get")
+def resp_get_issue(url, request):
+ content = '[{"name": "name", "id": 1}, ' '{"name": "other_name", "id": 2}]'
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/issues_statistics",
+ method="get",
+)
+def resp_get_environment(url, request):
+ content = """{"statistics": {"counts": {"all": 20, "closed": 5, "opened": 15}}}""".encode(
+ "utf-8"
+ )
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_issue)
+def test_issues(gl):
+ data = gl.issues.list()
+ assert data[1].id == 2
+ assert data[1].name == "other_name"
+
+
+@with_httmock(resp_get_environment)
+def test_project_issues_statistics(project):
+ statistics = project.issuesstatistics.get()
+ assert isinstance(statistics, ProjectIssuesStatistics)
+ assert statistics.statistics["counts"]["all"] == 20
diff --git a/gitlab/tests/objects/test_pipeline_schedules.py b/gitlab/tests/objects/test_pipeline_schedules.py
new file mode 100644
index 0000000..6b56304
--- /dev/null
+++ b/gitlab/tests/objects/test_pipeline_schedules.py
@@ -0,0 +1,71 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/pipeline_schedules.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/pipeline_schedules$",
+ method="post",
+)
+def resp_create_project_pipeline_schedule(url, request):
+ """Mock for creating project pipeline Schedules POST response."""
+ content = """{
+ "id": 14,
+ "description": "Build packages",
+ "ref": "master",
+ "cron": "0 1 * * 5",
+ "cron_timezone": "UTC",
+ "next_run_at": "2017-05-26T01:00:00.000Z",
+ "active": true,
+ "created_at": "2017-05-19T13:43:08.169Z",
+ "updated_at": "2017-05-19T13:43:08.169Z",
+ "last_pipeline": null,
+ "owner": {
+ "name": "Administrator",
+ "username": "root",
+ "id": 1,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "https://gitlab.example.com/root"
+ }
+}"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/pipeline_schedules/14/play",
+ method="post",
+)
+def resp_play_project_pipeline_schedule(url, request):
+ """Mock for playing a project pipeline schedule POST response."""
+ content = """{"message": "201 Created"}"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(
+ resp_create_project_pipeline_schedule, resp_play_project_pipeline_schedule
+)
+def test_project_pipeline_schedule_play(project):
+ description = "Build packages"
+ cronline = "0 1 * * 5"
+ sched = project.pipelineschedules.create(
+ {"ref": "master", "description": description, "cron": cronline}
+ )
+ assert sched is not None
+ assert description == sched.description
+ assert cronline == sched.cron
+
+ play_result = sched.play()
+ assert play_result is not None
+ assert "message" in play_result
+ assert play_result["message"] == "201 Created"
diff --git a/gitlab/tests/objects/test_project_import_export.py b/gitlab/tests/objects/test_project_import_export.py
new file mode 100644
index 0000000..e5c37a8
--- /dev/null
+++ b/gitlab/tests/objects/test_project_import_export.py
@@ -0,0 +1,129 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/project_import_export.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from .mocks import *
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/1/export", method="get",
+)
+def resp_export_status(url, request):
+ """Mock for Project Export GET response."""
+ content = """{
+ "id": 1,
+ "description": "Itaque perspiciatis minima aspernatur",
+ "name": "Gitlab Test",
+ "name_with_namespace": "Gitlab Org / Gitlab Test",
+ "path": "gitlab-test",
+ "path_with_namespace": "gitlab-org/gitlab-test",
+ "created_at": "2017-08-29T04:36:44.383Z",
+ "export_status": "finished",
+ "_links": {
+ "api_url": "https://gitlab.test/api/v4/projects/1/export/download",
+ "web_url": "https://gitlab.test/gitlab-test/download_export"
+ }
+ }
+ """
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/import", method="post",
+)
+def resp_import_project(url, request):
+ """Mock for Project Import POST response."""
+ content = """{
+ "id": 1,
+ "description": null,
+ "name": "api-project",
+ "name_with_namespace": "Administrator / api-project",
+ "path": "api-project",
+ "path_with_namespace": "root/api-project",
+ "created_at": "2018-02-13T09:05:58.023Z",
+ "import_status": "scheduled"
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/1/import", method="get",
+)
+def resp_import_status(url, request):
+ """Mock for Project Import GET response."""
+ content = """{
+ "id": 1,
+ "description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
+ "name": "Gitlab Test",
+ "name_with_namespace": "Gitlab Org / Gitlab Test",
+ "path": "gitlab-test",
+ "path_with_namespace": "gitlab-org/gitlab-test",
+ "created_at": "2017-08-29T04:36:44.383Z",
+ "import_status": "finished"
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/import/github", method="post",
+)
+def resp_import_github(url, request):
+ """Mock for GitHub Project Import POST response."""
+ content = """{
+ "id": 27,
+ "name": "my-repo",
+ "full_path": "/root/my-repo",
+ "full_name": "Administrator / my-repo"
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@with_httmock(resp_import_project)
+def test_import_project(gl):
+ project_import = gl.projects.import_project("file", "api-project")
+ assert project_import["import_status"] == "scheduled"
+
+
+@with_httmock(resp_import_status)
+def test_refresh_project_import_status(project):
+ project_import = project.imports.get()
+ project_import.refresh()
+ assert project_import.import_status == "finished"
+
+
+@with_httmock(resp_import_github)
+def test_import_github(gl):
+ base_path = "/root"
+ name = "my-repo"
+ ret = gl.projects.import_github("githubkey", 1234, base_path, name)
+ assert isinstance(ret, dict)
+ assert ret["name"] == name
+ assert ret["full_path"] == "/".join((base_path, name))
+ assert ret["full_name"].endswith(name)
+
+
+@with_httmock(resp_create_export)
+def test_create_project_export(project):
+ export = project.exports.create()
+ assert export.message == "202 Accepted"
+
+
+@with_httmock(resp_create_export, resp_export_status)
+def test_refresh_project_export_status(project):
+ export = project.exports.create()
+ export.refresh()
+ assert export.export_status == "finished"
+
+
+@with_httmock(resp_create_export, resp_download_export)
+def test_download_project_export(project):
+ export = project.exports.create()
+ download = export.download()
+ assert isinstance(download, bytes)
+ assert download == binary_content
diff --git a/gitlab/tests/objects/test_project_statistics.py b/gitlab/tests/objects/test_project_statistics.py
new file mode 100644
index 0000000..c2b194f
--- /dev/null
+++ b/gitlab/tests/objects/test_project_statistics.py
@@ -0,0 +1,29 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/project_statistics.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import ProjectAdditionalStatistics
+
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/statistics",
+ method="get",
+)
+def resp_get_statistics(url, request):
+ content = """{"fetches": {"total": 50, "days": [{"count": 10, "date": "2018-01-10"}]}}""".encode(
+ "utf-8"
+ )
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_statistics)
+def test_project_additional_statistics(project):
+ statistics = project.additionalstatistics.get()
+ assert isinstance(statistics, ProjectAdditionalStatistics)
+ assert statistics.fetches["total"] == 50
diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py
index fa105ae..7fefe3f 100644
--- a/gitlab/tests/objects/test_projects.py
+++ b/gitlab/tests/objects/test_projects.py
@@ -1,547 +1,205 @@
-import unittest
-import gitlab
-import os
-import pickle
-import tempfile
-import json
-import unittest
-import requests
-from gitlab import * # noqa
-from gitlab.v4.objects import * # noqa
-from httmock import HTTMock, urlmatch, response, with_httmock # noqa
-
-from .mocks import * # noqa
-
-
-@urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/projects/1/export", method="get",
-)
-def resp_export_status(url, request):
- """Mock for Project Export GET response."""
- content = """{
- "id": 1,
- "description": "Itaque perspiciatis minima aspernatur",
- "name": "Gitlab Test",
- "name_with_namespace": "Gitlab Org / Gitlab Test",
- "path": "gitlab-test",
- "path_with_namespace": "gitlab-org/gitlab-test",
- "created_at": "2017-08-29T04:36:44.383Z",
- "export_status": "finished",
- "_links": {
- "api_url": "https://gitlab.test/api/v4/projects/1/export/download",
- "web_url": "https://gitlab.test/gitlab-test/download_export"
- }
- }
- """
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
-
-@urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/projects/import", method="post",
-)
-def resp_import_project(url, request):
- """Mock for Project Import POST response."""
- content = """{
- "id": 1,
- "description": null,
- "name": "api-project",
- "name_with_namespace": "Administrator / api-project",
- "path": "api-project",
- "path_with_namespace": "root/api-project",
- "created_at": "2018-02-13T09:05:58.023Z",
- "import_status": "scheduled"
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
-
-@urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/projects/1/import", method="get",
-)
-def resp_import_status(url, request):
- """Mock for Project Import GET response."""
- content = """{
- "id": 1,
- "description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
- "name": "Gitlab Test",
- "name_with_namespace": "Gitlab Org / Gitlab Test",
- "path": "gitlab-test",
- "path_with_namespace": "gitlab-org/gitlab-test",
- "created_at": "2017-08-29T04:36:44.383Z",
- "import_status": "finished"
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
-
-@urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/import/github", method="post",
-)
-def resp_import_github(url, request):
- """Mock for GitHub Project Import POST response."""
- content = """{
- "id": 27,
- "name": "my-repo",
- "full_path": "/root/my-repo",
- "full_name": "Administrator / my-repo"
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
-
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/remote_mirrors",
- method="get",
-)
-def resp_get_remote_mirrors(url, request):
- """Mock for Project Remote Mirrors GET response."""
- content = """[
- {
- "enabled": true,
- "id": 101486,
- "last_error": null,
- "last_successful_update_at": "2020-01-06T17:32:02.823Z",
- "last_update_at": "2020-01-06T17:32:02.823Z",
- "last_update_started_at": "2020-01-06T17:31:55.864Z",
- "only_protected_branches": true,
- "update_status": "finished",
- "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
- }
- ]"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+"""
+GitLab API: https://docs.gitlab.com/ce/api/projects.html
+"""
+import pytest
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/remote_mirrors",
- method="post",
-)
-def resp_create_remote_mirror(url, request):
- """Mock for Project Remote Mirrors POST response."""
- content = """{
- "enabled": false,
- "id": 101486,
- "last_error": null,
- "last_successful_update_at": null,
- "last_update_at": null,
- "last_update_started_at": null,
- "only_protected_branches": false,
- "update_status": "none",
- "url": "https://*****:*****@example.com/gitlab/example.git"
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+from gitlab.v4.objects import Project
+from httmock import urlmatch, response, with_httmock
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/remote_mirrors/1",
- method="put",
-)
-def resp_update_remote_mirror(url, request):
- """Mock for Project Remote Mirrors PUT response."""
- content = """{
- "enabled": false,
- "id": 101486,
- "last_error": null,
- "last_successful_update_at": "2020-01-06T17:32:02.823Z",
- "last_update_at": "2020-01-06T17:32:02.823Z",
- "last_update_started_at": "2020-01-06T17:31:55.864Z",
- "only_protected_branches": true,
- "update_status": "finished",
- "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+from .mocks import headers
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/services/pipelines-email",
- method="put",
-)
-def resp_update_service(url, request):
- """Mock for Service update PUT response."""
- content = """{
- "id": 100152,
- "title": "Pipelines emails",
- "slug": "pipelines-email",
- "created_at": "2019-01-14T08:46:43.637+01:00",
- "updated_at": "2019-07-01T14:10:36.156+02:00",
- "active": true,
- "commit_events": true,
- "push_events": true,
- "issues_events": true,
- "confidential_issues_events": true,
- "merge_requests_events": true,
- "tag_push_events": true,
- "note_events": true,
- "confidential_note_events": true,
- "pipeline_events": true,
- "wiki_page_events": true,
- "job_events": true,
- "comment_on_event_enabled": true,
- "project_id": 1
- }"""
- content = content.encode("utf-8")
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects/1", method="get")
+def resp_get_project(url, request):
+ content = '{"name": "name", "id": 1}'.encode("utf-8")
return response(200, content, headers, None, 5, request)
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/services/pipelines-email",
- method="get",
-)
-def resp_get_service(url, request):
- """Mock for Service GET response."""
- content = """{
- "id": 100152,
- "title": "Pipelines emails",
- "slug": "pipelines-email",
- "created_at": "2019-01-14T08:46:43.637+01:00",
- "updated_at": "2019-07-01T14:10:36.156+02:00",
- "active": true,
- "commit_events": true,
- "push_events": true,
- "issues_events": true,
- "confidential_issues_events": true,
- "merge_requests_events": true,
- "tag_push_events": true,
- "note_events": true,
- "confidential_note_events": true,
- "pipeline_events": true,
- "wiki_page_events": true,
- "job_events": true,
- "comment_on_event_enabled": true,
- "project_id": 1
- }"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+@with_httmock(resp_get_project)
+def test_get_project(gl):
+ data = gl.projects.get(1)
+ assert isinstance(data, Project)
+ assert data.name == "name"
+ assert data.id == 1
-@urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/projects/1/services", method="get",
-)
-def resp_get_active_services(url, request):
- """Mock for active Services GET response."""
- content = """[{
- "id": 100152,
- "title": "Pipelines emails",
- "slug": "pipelines-email",
- "created_at": "2019-01-14T08:46:43.637+01:00",
- "updated_at": "2019-07-01T14:10:36.156+02:00",
- "active": true,
- "commit_events": true,
- "push_events": true,
- "issues_events": true,
- "confidential_issues_events": true,
- "merge_requests_events": true,
- "tag_push_events": true,
- "note_events": true,
- "confidential_note_events": true,
- "pipeline_events": true,
- "wiki_page_events": true,
- "job_events": true,
- "comment_on_event_enabled": true,
- "project_id": 1
- }]"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+@pytest.mark.skip(reason="missing test")
+def test_list_projects(gl):
+ pass
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/pipeline_schedules$",
- method="post",
-)
-def resp_create_project_pipeline_schedule(url, request):
- """Mock for creating project pipeline Schedules POST response."""
- content = """{
- "id": 14,
- "description": "Build packages",
- "ref": "master",
- "cron": "0 1 * * 5",
- "cron_timezone": "UTC",
- "next_run_at": "2017-05-26T01:00:00.000Z",
- "active": true,
- "created_at": "2017-05-19T13:43:08.169Z",
- "updated_at": "2017-05-19T13:43:08.169Z",
- "last_pipeline": null,
- "owner": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "https://gitlab.example.com/root"
- }
-}"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+@pytest.mark.skip(reason="missing test")
+def test_list_user_projects(gl):
+ pass
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/pipeline_schedules/14/play",
- method="post",
-)
-def resp_play_project_pipeline_schedule(url, request):
- """Mock for playing a project pipeline schedule POST response."""
- content = """{"message": "201 Created"}"""
- content = content.encode("utf-8")
- return response(200, content, headers, None, 5, request)
+@pytest.mark.skip(reason="missing test")
+def test_list_user_starred_projects(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_list_project_users(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_create_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_create_user_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_update_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_fork_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_list_project_forks(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_star_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_unstar_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_list_project_starrers(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_get_project_languages(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_archive_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_unarchive_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_remove_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_restore_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_upload_file(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_share_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_delete_shared_project_link(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_list_project_hooks(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_get_project_hook(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_create_project_hook(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_update_project_hook(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_delete_project_hook(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_create_forked_from_relationship(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_delete_forked_from_relationship(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_search_projects_by_name(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_project_housekeeping(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_get_project_push_rules(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_create_project_push_rule(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_update_project_push_rule(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_delete_project_push_rule(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_transfer_project(gl):
+ pass
+
+
+@pytest.mark.skip(reason="missing test")
+def test_project_pull_mirror(gl):
+ pass
-class TestProject(unittest.TestCase):
- """Base class for GitLab Project tests."""
-
- def setUp(self):
- self.gl = Gitlab(
- "http://localhost",
- private_token="private_token",
- ssl_verify=True,
- api_version="4",
- )
- self.project = self.gl.projects.get(1, lazy=True)
-
-
-class TestProjectSnippets(TestProject):
- def test_list_project_snippets(self):
- title = "Example Snippet Title"
- visibility = "private"
-
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/snippets",
- method="get",
- )
- def resp_list_snippet(url, request):
- content = """[{
- "title": "%s",
- "description": "More verbose snippet description",
- "file_name": "example.txt",
- "content": "source code with multiple lines",
- "visibility": "%s"}]""" % (
- title,
- visibility,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- with HTTMock(resp_list_snippet):
- snippets = self.project.snippets.list()
- assert len(snippets) == 1
- assert snippets[0].title == title
- assert snippets[0].visibility == visibility
-
- def test_get_project_snippets(self):
- title = "Example Snippet Title"
- visibility = "private"
-
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/snippets/1",
- method="get",
- )
- def resp_get_snippet(url, request):
- content = """{
- "title": "%s",
- "description": "More verbose snippet description",
- "file_name": "example.txt",
- "content": "source code with multiple lines",
- "visibility": "%s"}""" % (
- title,
- visibility,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- with HTTMock(resp_get_snippet):
- snippet = self.project.snippets.get(1)
- assert snippet.title == title
- assert snippet.visibility == visibility
-
- def test_create_update_project_snippets(self):
- title = "Example Snippet Title"
- visibility = "private"
-
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/snippets",
- method="put",
- )
- def resp_update_snippet(url, request):
- content = """{
- "title": "%s",
- "description": "More verbose snippet description",
- "file_name": "example.txt",
- "content": "source code with multiple lines",
- "visibility": "%s"}""" % (
- title,
- visibility,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- @urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/projects/1/snippets",
- method="post",
- )
- def resp_create_snippet(url, request):
- content = """{
- "title": "%s",
- "description": "More verbose snippet description",
- "file_name": "example.txt",
- "content": "source code with multiple lines",
- "visibility": "%s"}""" % (
- title,
- visibility,
- )
- content = content.encode("utf-8")
- return response(200, content, headers, None, 25, request)
-
- with HTTMock(resp_create_snippet, resp_update_snippet):
- snippet = self.project.snippets.create(
- {
- "title": title,
- "file_name": title,
- "content": title,
- "visibility": visibility,
- }
- )
- assert snippet.title == title
- assert snippet.visibility == visibility
- title = "new-title"
- snippet.title = title
- snippet.save()
- assert snippet.title == title
- assert snippet.visibility == visibility
-
-
-class TestProjectExport(TestProject):
- @with_httmock(resp_create_export)
- def test_create_project_export(self):
- export = self.project.exports.create()
- assert export.message == "202 Accepted"
-
- @with_httmock(resp_create_export, resp_export_status)
- def test_refresh_project_export_status(self):
- export = self.project.exports.create()
- export.refresh()
- assert export.export_status == "finished"
-
- @with_httmock(resp_create_export, resp_download_export)
- def test_download_project_export(self):
- export = self.project.exports.create()
- download = export.download()
- assert isinstance(download, bytes)
- assert download == binary_content
-
-
-class TestProjectImport(TestProject):
- @with_httmock(resp_import_project)
- def test_import_project(self):
- project_import = self.gl.projects.import_project("file", "api-project")
- assert project_import["import_status"] == "scheduled"
-
- @with_httmock(resp_import_status)
- def test_refresh_project_import_status(self):
- project_import = self.project.imports.get()
- project_import.refresh()
- assert project_import.import_status == "finished"
-
- @with_httmock(resp_import_github)
- def test_import_github(self):
- base_path = "/root"
- name = "my-repo"
- ret = self.gl.projects.import_github("githubkey", 1234, base_path, name)
- assert isinstance(ret, dict)
- assert ret["name"] == name
- assert ret["full_path"] == "/".join((base_path, name))
- assert ret["full_name"].endswith(name)
-
-
-class TestProjectRemoteMirrors(TestProject):
- @with_httmock(resp_get_remote_mirrors)
- def test_list_project_remote_mirrors(self):
- mirrors = self.project.remote_mirrors.list()
- assert isinstance(mirrors, list)
- assert isinstance(mirrors[0], ProjectRemoteMirror)
- assert mirrors[0].enabled
-
- @with_httmock(resp_create_remote_mirror)
- def test_create_project_remote_mirror(self):
- mirror = self.project.remote_mirrors.create({"url": "https://example.com"})
- assert isinstance(mirror, ProjectRemoteMirror)
- assert mirror.update_status == "none"
-
- @with_httmock(resp_create_remote_mirror, resp_update_remote_mirror)
- def test_update_project_remote_mirror(self):
- mirror = self.project.remote_mirrors.create({"url": "https://example.com"})
- mirror.only_protected_branches = True
- mirror.save()
- assert mirror.update_status == "finished"
- assert mirror.only_protected_branches
-
-
-class TestProjectServices(TestProject):
- @with_httmock(resp_get_active_services)
- def test_list_active_services(self):
- services = self.project.services.list()
- assert isinstance(services, list)
- assert isinstance(services[0], ProjectService)
- assert services[0].active
- assert services[0].push_events
-
- def test_list_available_services(self):
- services = self.project.services.available()
- assert isinstance(services, list)
- assert isinstance(services[0], str)
-
- @with_httmock(resp_get_service)
- def test_get_service(self):
- service = self.project.services.get("pipelines-email")
- assert isinstance(service, ProjectService)
- assert service.push_events == True
-
- @with_httmock(resp_get_service, resp_update_service)
- def test_update_service(self):
- service = self.project.services.get("pipelines-email")
- service.issues_events = True
- service.save()
- assert service.issues_events == True
-
-
-class TestProjectPipelineSchedule(TestProject):
- @with_httmock(
- resp_create_project_pipeline_schedule, resp_play_project_pipeline_schedule
- )
- def test_project_pipeline_schedule_play(self):
- description = "Build packages"
- cronline = "0 1 * * 5"
- sched = self.project.pipelineschedules.create(
- {"ref": "master", "description": description, "cron": cronline}
- )
- self.assertIsNotNone(sched)
- self.assertEqual(description, sched.description)
- self.assertEqual(cronline, sched.cron)
-
- play_result = sched.play()
- self.assertIsNotNone(play_result)
- self.assertIn("message", play_result)
- self.assertEqual("201 Created", play_result["message"])
+@pytest.mark.skip(reason="missing test")
+def test_project_snapshot(gl):
+ pass
diff --git a/gitlab/tests/objects/test_remote_mirrors.py b/gitlab/tests/objects/test_remote_mirrors.py
new file mode 100644
index 0000000..e62a71e
--- /dev/null
+++ b/gitlab/tests/objects/test_remote_mirrors.py
@@ -0,0 +1,103 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/remote_mirrors.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import ProjectRemoteMirror
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/remote_mirrors",
+ method="get",
+)
+def resp_get_remote_mirrors(url, request):
+ """Mock for Project Remote Mirrors GET response."""
+ content = """[
+ {
+ "enabled": true,
+ "id": 101486,
+ "last_error": null,
+ "last_successful_update_at": "2020-01-06T17:32:02.823Z",
+ "last_update_at": "2020-01-06T17:32:02.823Z",
+ "last_update_started_at": "2020-01-06T17:31:55.864Z",
+ "only_protected_branches": true,
+ "update_status": "finished",
+ "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
+ }
+ ]"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/remote_mirrors",
+ method="post",
+)
+def resp_create_remote_mirror(url, request):
+ """Mock for Project Remote Mirrors POST response."""
+ content = """{
+ "enabled": false,
+ "id": 101486,
+ "last_error": null,
+ "last_successful_update_at": null,
+ "last_update_at": null,
+ "last_update_started_at": null,
+ "only_protected_branches": false,
+ "update_status": "none",
+ "url": "https://*****:*****@example.com/gitlab/example.git"
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/remote_mirrors/1",
+ method="put",
+)
+def resp_update_remote_mirror(url, request):
+ """Mock for Project Remote Mirrors PUT response."""
+ content = """{
+ "enabled": false,
+ "id": 101486,
+ "last_error": null,
+ "last_successful_update_at": "2020-01-06T17:32:02.823Z",
+ "last_update_at": "2020-01-06T17:32:02.823Z",
+ "last_update_started_at": "2020-01-06T17:31:55.864Z",
+ "only_protected_branches": true,
+ "update_status": "finished",
+ "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git"
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_remote_mirrors)
+def test_list_project_remote_mirrors(project):
+ mirrors = project.remote_mirrors.list()
+ assert isinstance(mirrors, list)
+ assert isinstance(mirrors[0], ProjectRemoteMirror)
+ assert mirrors[0].enabled
+
+
+@with_httmock(resp_create_remote_mirror)
+def test_create_project_remote_mirror(project):
+ mirror = project.remote_mirrors.create({"url": "https://example.com"})
+ assert isinstance(mirror, ProjectRemoteMirror)
+ assert mirror.update_status == "none"
+
+
+@with_httmock(resp_create_remote_mirror, resp_update_remote_mirror)
+def test_update_project_remote_mirror(project):
+ mirror = project.remote_mirrors.create({"url": "https://example.com"})
+ mirror.only_protected_branches = True
+ mirror.save()
+ assert mirror.update_status == "finished"
+ assert mirror.only_protected_branches
diff --git a/gitlab/tests/objects/test_services.py b/gitlab/tests/objects/test_services.py
new file mode 100644
index 0000000..a0cded7
--- /dev/null
+++ b/gitlab/tests/objects/test_services.py
@@ -0,0 +1,134 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/services.html
+"""
+
+from httmock import urlmatch, response, with_httmock
+
+from gitlab.v4.objects import ProjectService
+from .mocks import headers
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/services/pipelines-email",
+ method="put",
+)
+def resp_update_service(url, request):
+ """Mock for Service update PUT response."""
+ content = """{
+ "id": 100152,
+ "title": "Pipelines emails",
+ "slug": "pipelines-email",
+ "created_at": "2019-01-14T08:46:43.637+01:00",
+ "updated_at": "2019-07-01T14:10:36.156+02:00",
+ "active": true,
+ "commit_events": true,
+ "push_events": true,
+ "issues_events": true,
+ "confidential_issues_events": true,
+ "merge_requests_events": true,
+ "tag_push_events": true,
+ "note_events": true,
+ "confidential_note_events": true,
+ "pipeline_events": true,
+ "wiki_page_events": true,
+ "job_events": true,
+ "comment_on_event_enabled": true,
+ "project_id": 1
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/services/pipelines-email",
+ method="get",
+)
+def resp_get_service(url, request):
+ """Mock for Service GET response."""
+ content = """{
+ "id": 100152,
+ "title": "Pipelines emails",
+ "slug": "pipelines-email",
+ "created_at": "2019-01-14T08:46:43.637+01:00",
+ "updated_at": "2019-07-01T14:10:36.156+02:00",
+ "active": true,
+ "commit_events": true,
+ "push_events": true,
+ "issues_events": true,
+ "confidential_issues_events": true,
+ "merge_requests_events": true,
+ "tag_push_events": true,
+ "note_events": true,
+ "confidential_note_events": true,
+ "pipeline_events": true,
+ "wiki_page_events": true,
+ "job_events": true,
+ "comment_on_event_enabled": true,
+ "project_id": 1
+ }"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/1/services", method="get",
+)
+def resp_get_active_services(url, request):
+ """Mock for active Services GET response."""
+ content = """[{
+ "id": 100152,
+ "title": "Pipelines emails",
+ "slug": "pipelines-email",
+ "created_at": "2019-01-14T08:46:43.637+01:00",
+ "updated_at": "2019-07-01T14:10:36.156+02:00",
+ "active": true,
+ "commit_events": true,
+ "push_events": true,
+ "issues_events": true,
+ "confidential_issues_events": true,
+ "merge_requests_events": true,
+ "tag_push_events": true,
+ "note_events": true,
+ "confidential_note_events": true,
+ "pipeline_events": true,
+ "wiki_page_events": true,
+ "job_events": true,
+ "comment_on_event_enabled": true,
+ "project_id": 1
+ }]"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_active_services)
+def test_list_active_services(project):
+ services = project.services.list()
+ assert isinstance(services, list)
+ assert isinstance(services[0], ProjectService)
+ assert services[0].active
+ assert services[0].push_events
+
+
+def test_list_available_services(project):
+ services = project.services.available()
+ assert isinstance(services, list)
+ assert isinstance(services[0], str)
+
+
+@with_httmock(resp_get_service)
+def test_get_service(project):
+ service = project.services.get("pipelines-email")
+ assert isinstance(service, ProjectService)
+ assert service.push_events is True
+
+
+@with_httmock(resp_get_service, resp_update_service)
+def test_update_service(project):
+ service = project.services.get("pipelines-email")
+ service.issues_events = True
+ service.save()
+ assert service.issues_events is True
diff --git a/gitlab/tests/objects/test_snippets.py b/gitlab/tests/objects/test_snippets.py
new file mode 100644
index 0000000..86eb54c
--- /dev/null
+++ b/gitlab/tests/objects/test_snippets.py
@@ -0,0 +1,121 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/project_snippets.html
+ https://docs.gitlab.com/ee/api/snippets.html (todo)
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from .mocks import headers
+
+
+title = "Example Snippet Title"
+visibility = "private"
+new_title = "new-title"
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/1/snippets", method="get",
+)
+def resp_list_snippet(url, request):
+ content = """[{
+ "title": "%s",
+ "description": "More verbose snippet description",
+ "file_name": "example.txt",
+ "content": "source code with multiple lines",
+ "visibility": "%s"}]""" % (
+ title,
+ visibility,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/snippets/1",
+ method="get",
+)
+def resp_get_snippet(url, request):
+ content = """{
+ "title": "%s",
+ "description": "More verbose snippet description",
+ "file_name": "example.txt",
+ "content": "source code with multiple lines",
+ "visibility": "%s"}""" % (
+ title,
+ visibility,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/snippets",
+ method="post",
+)
+def resp_create_snippet(url, request):
+ content = """{
+ "title": "%s",
+ "description": "More verbose snippet description",
+ "file_name": "example.txt",
+ "content": "source code with multiple lines",
+ "visibility": "%s"}""" % (
+ title,
+ visibility,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/projects/1/snippets", method="put",
+)
+def resp_update_snippet(url, request):
+ content = """{
+ "title": "%s",
+ "description": "More verbose snippet description",
+ "file_name": "example.txt",
+ "content": "source code with multiple lines",
+ "visibility": "%s"}""" % (
+ new_title,
+ visibility,
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 25, request)
+
+
+@with_httmock(resp_list_snippet)
+def test_list_project_snippets(project):
+ snippets = project.snippets.list()
+ assert len(snippets) == 1
+ assert snippets[0].title == title
+ assert snippets[0].visibility == visibility
+
+
+@with_httmock(resp_get_snippet)
+def test_get_project_snippets(project):
+ snippet = project.snippets.get(1)
+ assert snippet.title == title
+ assert snippet.visibility == visibility
+
+
+@with_httmock(resp_create_snippet, resp_update_snippet)
+def test_create_update_project_snippets(project):
+ snippet = project.snippets.create(
+ {
+ "title": title,
+ "file_name": title,
+ "content": title,
+ "visibility": visibility,
+ }
+ )
+ assert snippet.title == title
+ assert snippet.visibility == visibility
+
+ snippet.title = new_title
+ snippet.save()
+ assert snippet.title == new_title
+ assert snippet.visibility == visibility
diff --git a/gitlab/tests/objects/test_submodules.py b/gitlab/tests/objects/test_submodules.py
new file mode 100644
index 0000000..2e76302
--- /dev/null
+++ b/gitlab/tests/objects/test_submodules.py
@@ -0,0 +1,58 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/repository_submodules.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import Project
+
+from .mocks import headers
+
+
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects/1$", method="get")
+def resp_get_project(url, request):
+ content = '{"name": "name", "id": 1}'.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/projects/1/repository/submodules/foo%2Fbar",
+ method="put",
+)
+def resp_update_submodule(url, request):
+ content = """{
+ "id": "ed899a2f4b50b4370feeea94676502b42383c746",
+ "short_id": "ed899a2f4b5",
+ "title": "Message",
+ "author_name": "Author",
+ "author_email": "author@example.com",
+ "committer_name": "Author",
+ "committer_email": "author@example.com",
+ "created_at": "2018-09-20T09:26:24.000-07:00",
+ "message": "Message",
+ "parent_ids": [ "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba" ],
+ "committed_date": "2018-09-20T09:26:24.000-07:00",
+ "authored_date": "2018-09-20T09:26:24.000-07:00",
+ "status": null}"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_project, resp_update_submodule)
+def test_update_submodule(gl):
+ project = gl.projects.get(1)
+ assert isinstance(project, Project)
+ assert project.name == "name"
+ assert project.id == 1
+
+ ret = project.update_submodule(
+ submodule="foo/bar",
+ branch="master",
+ commit_sha="4c3674f66071e30b3311dac9b9ccc90502a72664",
+ commit_message="Message",
+ )
+ assert isinstance(ret, dict)
+ assert ret["message"] == "Message"
+ assert ret["id"] == "ed899a2f4b50b4370feeea94676502b42383c746"
diff --git a/gitlab/tests/objects/test_todos.py b/gitlab/tests/objects/test_todos.py
new file mode 100644
index 0000000..5b30dc9
--- /dev/null
+++ b/gitlab/tests/objects/test_todos.py
@@ -0,0 +1,58 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/todos.html
+"""
+
+import json
+import os
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import Todo
+
+from .mocks import headers
+
+
+with open(os.path.dirname(__file__) + "/../data/todo.json", "r") as json_file:
+ todo_content = json_file.read()
+ json_content = json.loads(todo_content)
+ encoded_content = todo_content.encode("utf-8")
+
+
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/todos", method="get")
+def resp_get_todo(url, request):
+ return response(200, encoded_content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http",
+ netloc="localhost",
+ path="/api/v4/todos/102/mark_as_done",
+ method="post",
+)
+def resp_mark_as_done(url, request):
+ single_todo = json.dumps(json_content[0])
+ content = single_todo.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/todos/mark_as_done", method="post",
+)
+def resp_mark_all_as_done(url, request):
+ return response(204, {}, headers, None, 5, request)
+
+
+@with_httmock(resp_get_todo, resp_mark_as_done)
+def test_todo(gl):
+ todo = gl.todos.list()[0]
+ assert isinstance(todo, Todo)
+ assert todo.id == 102
+ assert todo.target_type == "MergeRequest"
+ assert todo.target["assignee"]["username"] == "root"
+
+ todo.mark_as_done()
+
+
+@with_httmock(resp_mark_all_as_done)
+def test_todo_mark_all_as_done(gl):
+ gl.todos.mark_all_as_done()
diff --git a/gitlab/tests/objects/test_users.py b/gitlab/tests/objects/test_users.py
new file mode 100644
index 0000000..88175d0
--- /dev/null
+++ b/gitlab/tests/objects/test_users.py
@@ -0,0 +1,94 @@
+"""
+GitLab API: https://docs.gitlab.com/ce/api/users.html
+"""
+
+from httmock import response, urlmatch, with_httmock
+
+from gitlab.v4.objects import User, UserMembership, UserStatus
+from .mocks import headers
+
+
+@urlmatch(scheme="http", netloc="localhost", path="/api/v4/users/1", method="get")
+def resp_get_user(url, request):
+ content = (
+ '{"name": "name", "id": 1, "password": "password", '
+ '"username": "username", "email": "email"}'
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/users/1/memberships", method="get",
+)
+def resp_get_user_memberships(url, request):
+ content = """[
+ {
+ "source_id": 1,
+ "source_name": "Project one",
+ "source_type": "Project",
+ "access_level": "20"
+ },
+ {
+ "source_id": 3,
+ "source_name": "Group three",
+ "source_type": "Namespace",
+ "access_level": "20"
+ }
+ ]"""
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/users/1/activate", method="post",
+)
+def resp_activate(url, request):
+ return response(201, {}, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/users/1/deactivate", method="post",
+)
+def resp_deactivate(url, request):
+ return response(201, {}, headers, None, 5, request)
+
+
+@urlmatch(
+ scheme="http", netloc="localhost", path="/api/v4/users/1/status", method="get",
+)
+def resp_get_user_status(url, request):
+ content = (
+ '{"message": "test", "message_html": "<h1>Message</h1>", "emoji": "thumbsup"}'
+ )
+ content = content.encode("utf-8")
+ return response(200, content, headers, None, 5, request)
+
+
+@with_httmock(resp_get_user)
+def test_get_user(gl):
+ user = gl.users.get(1)
+ assert isinstance(user, User)
+ assert user.name == "name"
+ assert user.id == 1
+
+
+@with_httmock(resp_get_user_memberships)
+def test_user_memberships(user):
+ memberships = user.memberships.list()
+ assert isinstance(memberships[0], UserMembership)
+ assert memberships[0].source_type == "Project"
+
+
+@with_httmock(resp_get_user_status)
+def test_user_status(user):
+ status = user.status.get()
+ assert isinstance(status, UserStatus)
+ assert status.message == "test"
+ assert status.emoji == "thumbsup"
+
+
+@with_httmock(resp_activate, resp_deactivate)
+def test_user_activate_deactivate(user):
+ user.activate()
+ user.deactivate()