From 11383e70f74c70e6fe8a56f18b5b170db982f402 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Thu, 9 Apr 2020 00:13:36 +0200 Subject: chore: run unittest2pytest on all unit tests --- gitlab/tests/objects/test_application.py | 8 ++-- gitlab/tests/objects/test_commits.py | 16 ++++---- gitlab/tests/objects/test_groups.py | 26 ++++++------ gitlab/tests/objects/test_projects.py | 70 ++++++++++++++++---------------- 4 files changed, 60 insertions(+), 60 deletions(-) (limited to 'gitlab/tests/objects') diff --git a/gitlab/tests/objects/test_application.py b/gitlab/tests/objects/test_application.py index 50ca1ad..a10691b 100644 --- a/gitlab/tests/objects/test_application.py +++ b/gitlab/tests/objects/test_application.py @@ -80,13 +80,13 @@ class TestApplicationAppearance(unittest.TestCase): with HTTMock(resp_get_appearance), HTTMock(resp_update_appearance): appearance = self.gl.appearance.get() - self.assertEqual(appearance.title, self.title) - self.assertEqual(appearance.description, self.description) + assert appearance.title == self.title + assert appearance.description == self.description appearance.title = self.new_title appearance.description = self.new_description appearance.save() - self.assertEqual(appearance.title, self.new_title) - self.assertEqual(appearance.description, self.new_description) + assert appearance.title == self.new_title + assert appearance.description == self.new_description def test_update_appearance(self): @urlmatch( diff --git a/gitlab/tests/objects/test_commits.py b/gitlab/tests/objects/test_commits.py index 7e7c3b4..bf7d5a8 100644 --- a/gitlab/tests/objects/test_commits.py +++ b/gitlab/tests/objects/test_commits.py @@ -78,8 +78,8 @@ class TestCommit(TestProject): @with_httmock(resp_get_commit) def test_get_commit(self): commit = self.project.commits.get("6b2257ea") - self.assertEqual(commit.short_id, "6b2257ea") - self.assertEqual(commit.title, "Initial commit") + assert commit.short_id == "6b2257ea" + assert commit.title == "Initial commit" @with_httmock(resp_create_commit) def test_create_commit(self): @@ -89,19 +89,19 @@ class TestCommit(TestProject): "actions": [{"action": "create", "file_path": "README", "content": "",}], } commit = self.project.commits.create(data) - self.assertEqual(commit.short_id, "ed899a2f") - self.assertEqual(commit.title, data["commit_message"]) + 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") - self.assertEqual(revert_commit["short_id"], "8b090c1b") - self.assertEqual(revert_commit["title"], 'Revert "Initial commit"') + 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() - self.assertEqual(signature["gpg_key_primary_keyid"], "8254AAB3FBD54AC9") - self.assertEqual(signature["verification_status"], "verified") + assert signature["gpg_key_primary_keyid"] == "8254AAB3FBD54AC9" + assert signature["verification_status"] == "verified" diff --git a/gitlab/tests/objects/test_groups.py b/gitlab/tests/objects/test_groups.py index 075d915..12ebdb2 100644 --- a/gitlab/tests/objects/test_groups.py +++ b/gitlab/tests/objects/test_groups.py @@ -48,18 +48,18 @@ class TestGroup(unittest.TestCase): @with_httmock(resp_get_group) def test_get_group(self): data = self.gl.groups.get(1) - self.assertIsInstance(data, gitlab.v4.objects.Group) - self.assertEqual(data.name, "name") - self.assertEqual(data.path, "path") - self.assertEqual(data.id, 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}) - self.assertIsInstance(data, gitlab.v4.objects.Group) - self.assertEqual(data.name, name) - self.assertEqual(data.path, path) + assert isinstance(data, gitlab.v4.objects.Group) + assert data.name == name + assert data.path == path class TestGroupExport(TestGroup): @@ -70,32 +70,32 @@ class TestGroupExport(TestGroup): @with_httmock(resp_create_export) def test_create_group_export(self): export = self.group.exports.create() - self.assertEqual(export.message, "202 Accepted") + 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() - self.assertEqual(export.export_status, "finished") + 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() - self.assertIsInstance(download, bytes) - self.assertEqual(download, binary_content) + 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") - self.assertEqual(group_import["message"], "202 Accepted") + 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() - self.assertEqual(group_import.import_status, "finished") + assert group_import.import_status == "finished" diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py index ca7e0c8..fa105ae 100644 --- a/gitlab/tests/objects/test_projects.py +++ b/gitlab/tests/objects/test_projects.py @@ -341,9 +341,9 @@ class TestProjectSnippets(TestProject): with HTTMock(resp_list_snippet): snippets = self.project.snippets.list() - self.assertEqual(len(snippets), 1) - self.assertEqual(snippets[0].title, title) - self.assertEqual(snippets[0].visibility, visibility) + assert len(snippets) == 1 + assert snippets[0].title == title + assert snippets[0].visibility == visibility def test_get_project_snippets(self): title = "Example Snippet Title" @@ -370,8 +370,8 @@ class TestProjectSnippets(TestProject): with HTTMock(resp_get_snippet): snippet = self.project.snippets.get(1) - self.assertEqual(snippet.title, title) - self.assertEqual(snippet.visibility, visibility) + assert snippet.title == title + assert snippet.visibility == visibility def test_create_update_project_snippets(self): title = "Example Snippet Title" @@ -424,107 +424,107 @@ class TestProjectSnippets(TestProject): "visibility": visibility, } ) - self.assertEqual(snippet.title, title) - self.assertEqual(snippet.visibility, visibility) + assert snippet.title == title + assert snippet.visibility == visibility title = "new-title" snippet.title = title snippet.save() - self.assertEqual(snippet.title, title) - self.assertEqual(snippet.visibility, visibility) + 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() - self.assertEqual(export.message, "202 Accepted") + 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() - self.assertEqual(export.export_status, "finished") + 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() - self.assertIsInstance(download, bytes) - self.assertEqual(download, binary_content) + 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") - self.assertEqual(project_import["import_status"], "scheduled") + 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() - self.assertEqual(project_import.import_status, "finished") + 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) - self.assertIsInstance(ret, dict) - self.assertEqual(ret["name"], name) - self.assertEqual(ret["full_path"], "/".join((base_path, name))) - self.assertTrue(ret["full_name"].endswith(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() - self.assertIsInstance(mirrors, list) - self.assertIsInstance(mirrors[0], ProjectRemoteMirror) - self.assertTrue(mirrors[0].enabled) + 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"}) - self.assertIsInstance(mirror, ProjectRemoteMirror) - self.assertEqual(mirror.update_status, "none") + 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() - self.assertEqual(mirror.update_status, "finished") - self.assertTrue(mirror.only_protected_branches) + 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() - self.assertIsInstance(services, list) - self.assertIsInstance(services[0], ProjectService) - self.assertTrue(services[0].active) - self.assertTrue(services[0].push_events) + 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() - self.assertIsInstance(services, list) - self.assertIsInstance(services[0], str) + 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") - self.assertIsInstance(service, ProjectService) - self.assertEqual(service.push_events, True) + 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() - self.assertEqual(service.issues_events, True) + assert service.issues_events == True class TestProjectPipelineSchedule(TestProject): -- cgit v1.2.1 From 76b2cadf1418e4ea2ac420ebba5a4b4f16fbd4c7 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Fri, 17 Apr 2020 02:26:28 +0200 Subject: refactor: split unit tests by GitLab API resources --- gitlab/tests/objects/test_application.py | 226 +++---- gitlab/tests/objects/test_commits.py | 74 +-- gitlab/tests/objects/test_deploy_tokens.py | 44 ++ gitlab/tests/objects/test_deployments.py | 53 ++ gitlab/tests/objects/test_environments.py | 31 + gitlab/tests/objects/test_groups.py | 121 ++-- gitlab/tests/objects/test_hooks.py | 23 + gitlab/tests/objects/test_issues.py | 42 ++ gitlab/tests/objects/test_pipeline_schedules.py | 71 ++ gitlab/tests/objects/test_project_import_export.py | 129 ++++ gitlab/tests/objects/test_project_statistics.py | 29 + gitlab/tests/objects/test_projects.py | 718 ++++++--------------- gitlab/tests/objects/test_remote_mirrors.py | 103 +++ gitlab/tests/objects/test_services.py | 134 ++++ gitlab/tests/objects/test_snippets.py | 121 ++++ gitlab/tests/objects/test_submodules.py | 58 ++ gitlab/tests/objects/test_todos.py | 58 ++ gitlab/tests/objects/test_users.py | 94 +++ 18 files changed, 1379 insertions(+), 750 deletions(-) create mode 100644 gitlab/tests/objects/test_deploy_tokens.py create mode 100644 gitlab/tests/objects/test_deployments.py create mode 100644 gitlab/tests/objects/test_environments.py create mode 100644 gitlab/tests/objects/test_hooks.py create mode 100644 gitlab/tests/objects/test_issues.py create mode 100644 gitlab/tests/objects/test_pipeline_schedules.py create mode 100644 gitlab/tests/objects/test_project_import_export.py create mode 100644 gitlab/tests/objects/test_project_statistics.py create mode 100644 gitlab/tests/objects/test_remote_mirrors.py create mode 100644 gitlab/tests/objects/test_services.py create mode 100644 gitlab/tests/objects/test_snippets.py create mode 100644 gitlab/tests/objects/test_submodules.py create mode 100644 gitlab/tests/objects/test_todos.py create mode 100644 gitlab/tests/objects/test_users.py (limited to 'gitlab/tests/objects') 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": "

Message

", "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() -- cgit v1.2.1 From 204782a117f77f367dee87aa2c70822587829147 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Sun, 23 Aug 2020 21:16:20 +0200 Subject: refactor: rewrite unit tests for objects with responses --- gitlab/tests/objects/conftest.py | 65 ++++++++ gitlab/tests/objects/mocks.py | 35 ----- gitlab/tests/objects/test_appearance.py | 66 ++++++++ gitlab/tests/objects/test_application.py | 108 ------------- gitlab/tests/objects/test_applications.py | 45 ++++++ gitlab/tests/objects/test_commits.py | 158 +++++++++---------- gitlab/tests/objects/test_deploy_tokens.py | 36 ++--- gitlab/tests/objects/test_deployments.py | 51 +++---- gitlab/tests/objects/test_environments.py | 31 ++-- gitlab/tests/objects/test_groups.py | 97 ++++++------ gitlab/tests/objects/test_hooks.py | 24 +-- gitlab/tests/objects/test_issues.py | 52 ++++--- gitlab/tests/objects/test_pipeline_schedules.py | 97 ++++++------ gitlab/tests/objects/test_project_import_export.py | 169 +++++++++------------ gitlab/tests/objects/test_project_statistics.py | 31 ++-- gitlab/tests/objects/test_projects.py | 44 ++++-- gitlab/tests/objects/test_remote_mirrors.py | 111 +++++--------- gitlab/tests/objects/test_runners.py | 8 +- gitlab/tests/objects/test_services.py | 163 ++++++++------------ gitlab/tests/objects/test_snippets.py | 135 +++++++--------- gitlab/tests/objects/test_submodules.py | 74 ++++----- gitlab/tests/objects/test_todos.py | 69 +++++---- gitlab/tests/objects/test_users.py | 166 +++++++++++--------- 23 files changed, 898 insertions(+), 937 deletions(-) create mode 100644 gitlab/tests/objects/conftest.py delete mode 100644 gitlab/tests/objects/mocks.py create mode 100644 gitlab/tests/objects/test_appearance.py delete mode 100644 gitlab/tests/objects/test_application.py create mode 100644 gitlab/tests/objects/test_applications.py (limited to 'gitlab/tests/objects') diff --git a/gitlab/tests/objects/conftest.py b/gitlab/tests/objects/conftest.py new file mode 100644 index 0000000..76f76d1 --- /dev/null +++ b/gitlab/tests/objects/conftest.py @@ -0,0 +1,65 @@ +"""Common mocks for resources in gitlab.v4.objects""" + +import re + +import pytest +import responses + + +@pytest.fixture +def binary_content(): + return b"binary content" + + +@pytest.fixture +def accepted_content(): + return {"message": "202 Accepted"} + + +@pytest.fixture +def created_content(): + return {"message": "201 Created"} + + +@pytest.fixture +def resp_export(accepted_content, binary_content): + """Common fixture for group and project exports.""" + export_status_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", + }, + } + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.POST, + url=re.compile(r".*/api/v4/(groups|projects)/1/export"), + json=accepted_content, + content_type="application/json", + status=202, + ) + rsps.add( + method=responses.GET, + url=re.compile(r".*/api/v4/(groups|projects)/1/export/download"), + body=binary_content, + content_type="application/octet-stream", + status=200, + ) + # Currently only project export supports status checks + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/export", + json=export_status_content, + content_type="application/json", + status=200, + ) + yield rsps diff --git a/gitlab/tests/objects/mocks.py b/gitlab/tests/objects/mocks.py deleted file mode 100644 index e051339..0000000 --- a/gitlab/tests/objects/mocks.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Common mocks for resources in gitlab.v4.objects""" - -from httmock import response, urlmatch - - -headers = {"content-type": "application/json"} -binary_content = b"binary content" - - -@urlmatch( - scheme="http", - netloc="localhost", - path="/api/v4/(groups|projects)/1/export", - method="post", -) -def resp_create_export(url, request): - """Common mock for Group/Project Export POST response.""" - content = """{ - "message": "202 Accepted" - }""" - content = content.encode("utf-8") - return response(202, content, headers, None, 25, request) - - -@urlmatch( - scheme="http", - netloc="localhost", - path="/api/v4/(groups|projects)/1/export/download", - method="get", -) -def resp_download_export(url, request): - """Common mock for Group/Project Export Download GET response.""" - headers = {"content-type": "application/octet-stream"} - content = binary_content - return response(200, content, headers, None, 25, request) diff --git a/gitlab/tests/objects/test_appearance.py b/gitlab/tests/objects/test_appearance.py new file mode 100644 index 0000000..7c52301 --- /dev/null +++ b/gitlab/tests/objects/test_appearance.py @@ -0,0 +1,66 @@ +""" +GitLab API: https://docs.gitlab.com/ce/api/appearance.html +""" + +import pytest +import responses + + +title = "GitLab Test Instance" +description = "gitlab-test.example.com" +new_title = "new-title" +new_description = "new-description" + + +@pytest.fixture +def resp_application_appearance(): + content = { + "title": title, + "description": description, + "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, + } + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/application/appearance", + json=content, + content_type="application/json", + status=200, + ) + + updated_content = dict(content) + updated_content["title"] = new_title + updated_content["description"] = new_description + + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/application/appearance", + json=updated_content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_get_update_appearance(gl, resp_application_appearance): + 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 + + +def test_update_appearance(gl, resp_application_appearance): + resp = gl.appearance.update(title=new_title, description=new_description) diff --git a/gitlab/tests/objects/test_application.py b/gitlab/tests/objects/test_application.py deleted file mode 100644 index 356f0d3..0000000 --- a/gitlab/tests/objects/test_application.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -GitLab API: https://docs.gitlab.com/ce/api/applications.html -""" - -import json - -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_applications.py b/gitlab/tests/objects/test_applications.py new file mode 100644 index 0000000..f8b5d88 --- /dev/null +++ b/gitlab/tests/objects/test_applications.py @@ -0,0 +1,45 @@ +""" +GitLab API: https://docs.gitlab.com/ce/api/applications.html +""" + +import pytest +import responses + + +title = "GitLab Test Instance" +description = "gitlab-test.example.com" +new_title = "new-title" +new_description = "new-description" + + +@pytest.fixture +def resp_application_create(): + content = { + "name": "test_app", + "redirect_uri": "http://localhost:8080", + "scopes": ["api", "email"], + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/applications", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_create_application(gl, resp_application_create): + 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"] diff --git a/gitlab/tests/objects/test_commits.py b/gitlab/tests/objects/test_commits.py index eaa7b82..9d11508 100644 --- a/gitlab/tests/objects/test_commits.py +++ b/gitlab/tests/objects/test_commits.py @@ -2,85 +2,89 @@ GitLab API: https://docs.gitlab.com/ce/api/commits.html """ -from httmock import urlmatch, response, with_httmock - -from .mocks import headers - - -@urlmatch( - scheme="http", - netloc="localhost", - path="/api/v4/projects/1/repository/commits/6b2257ea", - method="get", -) -def resp_get_commit(url, request): - """Mock for commit GET response.""" - content = """{ - "id": "6b2257eabcec3db1f59dafbd84935e3caea04235", - "short_id": "6b2257ea", - "title": "Initial commit" - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@urlmatch( - scheme="http", path="/api/v4/projects/1/repository/commits", method="post", -) -def resp_create_commit(url, request): - """Mock for commit create POST response.""" - content = """{ - "id": "ed899a2f4b50b4370feeea94676502b42383c746", - "short_id": "ed899a2f", - "title": "Commit message" - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@urlmatch( - scheme="http", path="/api/v4/projects/1/repository/commits/6b2257ea", method="post", -) -def resp_revert_commit(url, request): - """Mock for commit revert POST response.""" - content = """{ - "id": "8b090c1b79a14f2bd9e8a738f717824ff53aebad", - "short_id": "8b090c1b", - "title":"Revert \\"Initial commit\\"" - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@urlmatch( - scheme="http", - netloc="localhost", - path="/api/v4/projects/1/repository/commits/6b2257ea/signature", - method="get", -) -def resp_get_commit_gpg_signature(url, request): - """Mock for commit GPG signature GET response.""" - content = """{ - "gpg_key_id": 1, - "gpg_key_primary_keyid": "8254AAB3FBD54AC9", - "gpg_key_user_name": "John Doe", - "gpg_key_user_email": "johndoe@example.com", - "verification_status": "verified", - "gpg_key_subkey_id": null - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@with_httmock(resp_get_commit) -def test_get_commit(project): +import pytest +import responses + + +@pytest.fixture +def resp_create_commit(): + content = { + "id": "ed899a2f4b50b4370feeea94676502b42383c746", + "short_id": "ed899a2f", + "title": "Commit message", + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/repository/commits", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_commit(): + get_content = { + "id": "6b2257eabcec3db1f59dafbd84935e3caea04235", + "short_id": "6b2257ea", + "title": "Initial commit", + } + revert_content = { + "id": "8b090c1b79a14f2bd9e8a738f717824ff53aebad", + "short_id": "8b090c1b", + "title": 'Revert "Initial commit"', + } + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/repository/commits/6b2257ea", + json=get_content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/repository/commits/6b2257ea/revert", + json=revert_content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_get_commit_gpg_signature(): + content = { + "gpg_key_id": 1, + "gpg_key_primary_keyid": "8254AAB3FBD54AC9", + "gpg_key_user_name": "John Doe", + "gpg_key_user_email": "johndoe@example.com", + "verification_status": "verified", + "gpg_key_subkey_id": None, + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/repository/commits/6b2257ea/signature", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_get_commit(project, resp_commit): 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): +def test_create_commit(project, resp_create_commit): data = { "branch": "master", "commit_message": "Commit message", @@ -91,16 +95,14 @@ def test_create_commit(project): assert commit.title == data["commit_message"] -@with_httmock(resp_revert_commit) -def test_revert_commit(project): +def test_revert_commit(project, resp_commit): 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): +def test_get_commit_gpg_signature(project, resp_get_commit_gpg_signature): commit = project.commits.get("6b2257ea", lazy=True) signature = commit.signature() assert signature["gpg_key_primary_keyid"] == "8254AAB3FBD54AC9" diff --git a/gitlab/tests/objects/test_deploy_tokens.py b/gitlab/tests/objects/test_deploy_tokens.py index b98a670..9cfa598 100644 --- a/gitlab/tests/objects/test_deploy_tokens.py +++ b/gitlab/tests/objects/test_deploy_tokens.py @@ -1,34 +1,36 @@ """ GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses 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 = """{ +create_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) + "scopes": ["read_repository"], +} + + +@pytest.fixture +def resp_deploy_token_create(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/deploy_tokens", + json=create_content, + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_deploy_token_create) -def test_deploy_tokens(gl): +def test_deploy_tokens(gl, resp_deploy_token_create): deploy_token = gl.projects.get(1, lazy=True).deploytokens.create( { "name": "test_deploy_token", diff --git a/gitlab/tests/objects/test_deployments.py b/gitlab/tests/objects/test_deployments.py index 098251a..3cde8fe 100644 --- a/gitlab/tests/objects/test_deployments.py +++ b/gitlab/tests/objects/test_deployments.py @@ -1,39 +1,37 @@ """ GitLab API: https://docs.gitlab.com/ce/api/deployments.html """ +import pytest +import responses -import json -from httmock import response, urlmatch, with_httmock +@pytest.fixture +def resp_deployment(): + content = {"id": 42, "status": "success", "ref": "master"} -from .mocks import headers + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/deployments", + json=content, + content_type="application/json", + status=200, + ) -content = '{"id": 42, "status": "success", "ref": "master"}' -json_content = json.loads(content) + updated_content = dict(content) + updated_content["status"] = "failed" + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/deployments/42", + json=updated_content, + content_type="application/json", + status=200, + ) + yield rsps -@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): +def test_deployment(project, resp_deployment): deployment = project.deployments.create( { "environment": "Test", @@ -47,7 +45,6 @@ def test_deployment(project): 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 index 3175c64..b49a1db 100644 --- a/gitlab/tests/objects/test_environments.py +++ b/gitlab/tests/objects/test_environments.py @@ -1,29 +1,28 @@ """ GitLab API: https://docs.gitlab.com/ce/api/environments.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses from gitlab.v4.objects import ProjectEnvironment -from .mocks import headers +@pytest.fixture +def resp_get_environment(): + content = {"name": "environment_name", "id": 1, "last_deployment": "sometime"} -@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 responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/environments/1", + json=content, + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_get_environment) -def test_project_environments(project): +def test_project_environments(project, resp_get_environment): environment = project.environments.get(1) assert isinstance(environment, ProjectEnvironment) assert environment.id == 1 diff --git a/gitlab/tests/objects/test_groups.py b/gitlab/tests/objects/test_groups.py index b5464b5..d4786f4 100644 --- a/gitlab/tests/objects/test_groups.py +++ b/gitlab/tests/objects/test_groups.py @@ -3,45 +3,54 @@ GitLab API: https://docs.gitlab.com/ce/api/groups.html """ import pytest - -from httmock import response, urlmatch, with_httmock +import responses import gitlab -from .mocks import * # noqa - - -@urlmatch(scheme="http", netloc="localhost", path="/api/v4/groups/1", method="get") -def resp_get_group(url, request): - content = '{"name": "name", "id": 1, "path": "path"}' - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@urlmatch(scheme="http", netloc="localhost", path="/api/v4/groups", method="post") -def resp_create_group(url, request): - content = '{"name": "name", "id": 1, "path": "path"}' - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) - - -@urlmatch( - scheme="http", netloc="localhost", path="/api/v4/groups/import", method="post", -) -def resp_create_import(url, request): - """Mock for Group import tests. - - GitLab does not respond with import status for group imports. - """ - - content = """{ - "message": "202 Accepted" - }""" - content = content.encode("utf-8") - return response(202, content, headers, None, 25, request) -@with_httmock(resp_get_group) -def test_get_group(gl): +@pytest.fixture +def resp_groups(): + content = {"name": "name", "id": 1, "path": "path"} + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/groups/1", + json=content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/groups", + json=[content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/groups", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_create_import(accepted_content): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/groups/import", + json=accepted_content, + content_type="application/json", + status=202, + ) + yield rsps + + +def test_get_group(gl, resp_groups): data = gl.groups.get(1) assert isinstance(data, gitlab.v4.objects.Group) assert data.name == "name" @@ -49,8 +58,7 @@ def test_get_group(gl): assert data.id == 1 -@with_httmock(resp_create_group) -def test_create_group(gl): +def test_create_group(gl, resp_groups): name, path = "name", "path" data = gl.groups.create({"name": name, "path": path}) assert isinstance(data, gitlab.v4.objects.Group) @@ -58,37 +66,32 @@ def test_create_group(gl): assert data.path == path -@with_httmock(resp_create_export) -def test_create_group_export(group): +def test_create_group_export(group, resp_export): 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): +def test_refresh_group_export_status(group, resp_export): 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): +def test_download_group_export(group, resp_export, binary_content): 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): +def test_import_group(gl, resp_create_import): 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): +def test_refresh_group_import_status(group, resp_groups): 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 index 45403c4..fe5c21c 100644 --- a/gitlab/tests/objects/test_hooks.py +++ b/gitlab/tests/objects/test_hooks.py @@ -1,22 +1,28 @@ """ GitLab API: https://docs.gitlab.com/ce/api/system_hooks.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses from gitlab.v4.objects import Hook -from .mocks import headers +@pytest.fixture +def resp_get_hook(): + content = {"url": "testurl", "id": 1} -@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 responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/hooks/1", + json=content, + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_get_hook) -def test_hooks(gl): +def test_hooks(gl, resp_get_hook): data = gl.hooks.get(1) assert isinstance(data, Hook) assert data.url == "testurl" diff --git a/gitlab/tests/objects/test_issues.py b/gitlab/tests/objects/test_issues.py index e094841..f67d720 100644 --- a/gitlab/tests/objects/test_issues.py +++ b/gitlab/tests/objects/test_issues.py @@ -2,41 +2,49 @@ GitLab API: https://docs.gitlab.com/ce/api/issues.html """ -from httmock import urlmatch, response, with_httmock +import pytest +import responses -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) +@pytest.fixture +def resp_issue(): + content = [{"name": "name", "id": 1}, {"name": "other_name", "id": 2}] + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/issues", + json=content, + content_type="application/json", + status=200, + ) + yield rsps -@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) +@pytest.fixture +def resp_issue_statistics(): + content = {"statistics": {"counts": {"all": 20, "closed": 5, "opened": 15}}} -@with_httmock(resp_get_issue) -def test_issues(gl): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/issues_statistics", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_issues(gl, resp_issue): 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): +def test_project_issues_statistics(project, resp_issue_statistics): 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 index 6b56304..c5dcc76 100644 --- a/gitlab/tests/objects/test_pipeline_schedules.py +++ b/gitlab/tests/objects/test_pipeline_schedules.py @@ -1,61 +1,52 @@ """ 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" +import pytest +import responses + + +@pytest.fixture +def resp_project_pipeline_schedule(created_content): + 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": None, + "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): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/pipeline_schedules", + json=content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/pipeline_schedules/14/play", + json=created_content, + content_type="application/json", + status=201, + ) + yield rsps + + +def test_project_pipeline_schedule_play(project, resp_project_pipeline_schedule): description = "Build packages" cronline = "0 1 * * 5" sched = project.pipelineschedules.create( diff --git a/gitlab/tests/objects/test_project_import_export.py b/gitlab/tests/objects/test_project_import_export.py index e5c37a8..78e51b1 100644 --- a/gitlab/tests/objects/test_project_import_export.py +++ b/gitlab/tests/objects/test_project_import_export.py @@ -1,104 +1,90 @@ """ GitLab API: https://docs.gitlab.com/ce/api/project_import_export.html """ +import pytest +import responses + + +@pytest.fixture +def resp_import_project(): + content = { + "id": 1, + "description": None, + "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", + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/import", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_import_status(): + 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", + } -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" - } + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/import", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_import_github(): + 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/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): + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/import/github", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_import_project(gl, resp_import_project): 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): +def test_refresh_project_import_status(project, resp_import_status): project_import = project.imports.get() project_import.refresh() assert project_import.import_status == "finished" -@with_httmock(resp_import_github) -def test_import_github(gl): +def test_import_github(gl, resp_import_github): base_path = "/root" name = "my-repo" ret = gl.projects.import_github("githubkey", 1234, base_path, name) @@ -108,21 +94,18 @@ def test_import_github(gl): assert ret["full_name"].endswith(name) -@with_httmock(resp_create_export) -def test_create_project_export(project): +def test_create_project_export(project, resp_export): export = project.exports.create() assert export.message == "202 Accepted" -@with_httmock(resp_create_export, resp_export_status) -def test_refresh_project_export_status(project): +def test_refresh_project_export_status(project, resp_export): 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): +def test_download_project_export(project, resp_export, binary_content): export = project.exports.create() download = export.download() assert isinstance(download, bytes) diff --git a/gitlab/tests/objects/test_project_statistics.py b/gitlab/tests/objects/test_project_statistics.py index c2b194f..50d9a6d 100644 --- a/gitlab/tests/objects/test_project_statistics.py +++ b/gitlab/tests/objects/test_project_statistics.py @@ -1,29 +1,28 @@ """ GitLab API: https://docs.gitlab.com/ce/api/project_statistics.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses from gitlab.v4.objects import ProjectAdditionalStatistics -from .mocks import headers +@pytest.fixture +def resp_project_statistics(): + content = {"fetches": {"total": 50, "days": [{"count": 10, "date": "2018-01-10"}]}} -@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 responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/statistics", + json=content, + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_get_statistics) -def test_project_additional_statistics(project): +def test_project_additional_statistics(project, resp_project_statistics): 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 7fefe3f..1e8b8b6 100644 --- a/gitlab/tests/objects/test_projects.py +++ b/gitlab/tests/objects/test_projects.py @@ -3,31 +3,51 @@ GitLab API: https://docs.gitlab.com/ce/api/projects.html """ import pytest - +import responses from gitlab.v4.objects import Project -from httmock import urlmatch, response, with_httmock -from .mocks import headers +project_content = {"name": "name", "id": 1} + + +@pytest.fixture +def resp_get_project(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1", + json=project_content, + content_type="application/json", + status=200, + ) + yield rsps -@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) +@pytest.fixture +def resp_list_projects(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects", + json=[project_content], + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_get_project) -def test_get_project(gl): + +def test_get_project(gl, resp_get_project): data = gl.projects.get(1) assert isinstance(data, Project) assert data.name == "name" assert data.id == 1 -@pytest.mark.skip(reason="missing test") -def test_list_projects(gl): - pass +def test_list_projects(gl, resp_list_projects): + projects = gl.projects.list() + assert isinstance(projects[0], Project) + assert projects[0].name == "name" @pytest.mark.skip(reason="missing test") diff --git a/gitlab/tests/objects/test_remote_mirrors.py b/gitlab/tests/objects/test_remote_mirrors.py index e62a71e..1ac35a2 100644 --- a/gitlab/tests/objects/test_remote_mirrors.py +++ b/gitlab/tests/objects/test_remote_mirrors.py @@ -2,100 +2,69 @@ GitLab API: https://docs.gitlab.com/ce/api/remote_mirrors.html """ -from httmock import response, urlmatch, with_httmock +import pytest +import responses 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, +@pytest.fixture +def resp_remote_mirrors(): + content = { + "enabled": True, + "id": 1, + "last_error": None, "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, + "only_protected_branches": True, "update_status": "none", - "url": "https://*****:*****@example.com/gitlab/example.git" - }""" - content = content.encode("utf-8") - return response(200, content, headers, None, 5, request) + "url": "https://*****:*****@gitlab.com/gitlab-org/security/gitlab.git", + } + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/remote_mirrors", + json=[content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/remote_mirrors", + json=content, + content_type="application/json", + status=200, + ) -@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) + updated_content = dict(content) + updated_content["update_status"] = "finished" + + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/remote_mirrors/1", + json=updated_content, + content_type="application/json", + status=200, + ) + yield rsps -@with_httmock(resp_get_remote_mirrors) -def test_list_project_remote_mirrors(project): +def test_list_project_remote_mirrors(project, resp_remote_mirrors): 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): +def test_create_project_remote_mirror(project, resp_remote_mirrors): 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): +def test_update_project_remote_mirror(project, resp_remote_mirrors): mirror = project.remote_mirrors.create({"url": "https://example.com"}) mirror.only_protected_branches = True mirror.save() diff --git a/gitlab/tests/objects/test_runners.py b/gitlab/tests/objects/test_runners.py index 2f86bef..490ba36 100644 --- a/gitlab/tests/objects/test_runners.py +++ b/gitlab/tests/objects/test_runners.py @@ -1,9 +1,9 @@ -import unittest +import re + +import pytest import responses + import gitlab -import pytest -import re -from .mocks import * # noqa runner_detail = { diff --git a/gitlab/tests/objects/test_services.py b/gitlab/tests/objects/test_services.py index a0cded7..5b2bcb8 100644 --- a/gitlab/tests/objects/test_services.py +++ b/gitlab/tests/objects/test_services.py @@ -2,110 +2,71 @@ GitLab API: https://docs.gitlab.com/ce/api/services.html """ -from httmock import urlmatch, response, with_httmock +import pytest +import responses 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 = """{ +@pytest.fixture +def resp_service(): + 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): + "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, + } + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/services", + json=[content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/services", + json=content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/services/pipelines-email", + json=content, + content_type="application/json", + status=200, + ) + updated_content = dict(content) + updated_content["issues_events"] = False + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/services/pipelines-email", + json=updated_content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_list_active_services(project, resp_service): services = project.services.list() assert isinstance(services, list) assert isinstance(services[0], ProjectService) @@ -113,22 +74,20 @@ def test_list_active_services(project): assert services[0].push_events -def test_list_available_services(project): +def test_list_available_services(project, resp_service): services = project.services.available() assert isinstance(services, list) assert isinstance(services[0], str) -@with_httmock(resp_get_service) -def test_get_service(project): +def test_get_service(project, resp_service): 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): +def test_update_service(project, resp_service): service = project.services.get("pipelines-email") - service.issues_events = True + service.issues_events = False service.save() - assert service.issues_events is True + assert service.issues_events is False diff --git a/gitlab/tests/objects/test_snippets.py b/gitlab/tests/objects/test_snippets.py index 86eb54c..7e8afc2 100644 --- a/gitlab/tests/objects/test_snippets.py +++ b/gitlab/tests/objects/test_snippets.py @@ -3,9 +3,8 @@ 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 +import pytest +import responses title = "Example Snippet Title" @@ -13,97 +12,67 @@ 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): +@pytest.fixture +def resp_snippet(): + content = { + "title": title, + "description": "More verbose snippet description", + "file_name": "example.txt", + "content": "source code with multiple lines", + "visibility": visibility, + } + + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/snippets", + json=[content], + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/snippets/1", + json=content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/snippets", + json=content, + content_type="application/json", + status=200, + ) + + updated_content = dict(content) + updated_content["title"] = new_title + updated_content["visibility"] = visibility + + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/snippets", + json=updated_content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_list_project_snippets(project, resp_snippet): 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): +def test_get_project_snippet(project, resp_snippet): 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): +def test_create_update_project_snippets(project, resp_snippet): snippet = project.snippets.create( { "title": title, diff --git a/gitlab/tests/objects/test_submodules.py b/gitlab/tests/objects/test_submodules.py index 2e76302..539af7b 100644 --- a/gitlab/tests/objects/test_submodules.py +++ b/gitlab/tests/objects/test_submodules.py @@ -1,52 +1,42 @@ """ GitLab API: https://docs.gitlab.com/ce/api/repository_submodules.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses 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 +@pytest.fixture +def resp_update_submodule(): + 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": None, + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.PUT, + url="http://localhost/api/v4/projects/1/repository/submodules/foo%2Fbar", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_update_submodule(project, resp_update_submodule): ret = project.update_submodule( submodule="foo/bar", branch="master", diff --git a/gitlab/tests/objects/test_todos.py b/gitlab/tests/objects/test_todos.py index 5b30dc9..07bb680 100644 --- a/gitlab/tests/objects/test_todos.py +++ b/gitlab/tests/objects/test_todos.py @@ -5,45 +5,51 @@ GitLab API: https://docs.gitlab.com/ce/api/todos.html import json import os -from httmock import response, urlmatch, with_httmock +import pytest +import responses 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): +@pytest.fixture +def resp_todo(): + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/todos", + json=json_content, + content_type="application/json", + status=200, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/todos/102/mark_as_done", + json=json_content[0], + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_mark_all_as_done(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/todos/mark_as_done", + json={}, + content_type="application/json", + status=204, + ) + yield rsps + + +def test_todo(gl, resp_todo): todo = gl.todos.list()[0] assert isinstance(todo, Todo) assert todo.id == 102 @@ -53,6 +59,5 @@ def test_todo(gl): todo.mark_as_done() -@with_httmock(resp_mark_all_as_done) -def test_todo_mark_all_as_done(gl): +def test_todo_mark_all_as_done(gl, resp_mark_all_as_done): gl.todos.mark_all_as_done() diff --git a/gitlab/tests/objects/test_users.py b/gitlab/tests/objects/test_users.py index 88175d0..ec282cf 100644 --- a/gitlab/tests/objects/test_users.py +++ b/gitlab/tests/objects/test_users.py @@ -1,94 +1,120 @@ """ GitLab API: https://docs.gitlab.com/ce/api/users.html """ - -from httmock import response, urlmatch, with_httmock +import pytest +import responses 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": "

Message

", "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): + + +@pytest.fixture +def resp_get_user(): + content = { + "name": "name", + "id": 1, + "password": "password", + "username": "username", + "email": "email", + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/users/1", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_get_user_memberships(): + 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", + }, + ] + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/users/1/memberships", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_activate(): + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/users/1/activate", + json={}, + content_type="application/json", + status=201, + ) + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/users/1/deactivate", + json={}, + content_type="application/json", + status=201, + ) + yield rsps + + +@pytest.fixture +def resp_get_user_status(): + content = { + "message": "test", + "message_html": "

Message

", + "emoji": "thumbsup", + } + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/users/1/status", + json=content, + content_type="application/json", + status=200, + ) + yield rsps + + +def test_get_user(gl, resp_get_user): 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): +def test_user_memberships(user, resp_get_user_memberships): 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): +def test_user_status(user, resp_get_user_status): 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): +def test_user_activate_deactivate(user, resp_activate): user.activate() user.deactivate() -- cgit v1.2.1