summaryrefslogtreecommitdiff
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/__init__.py0
-rw-r--r--tests/unit/conftest.py84
-rw-r--r--tests/unit/data/todo.json75
-rw-r--r--tests/unit/mixins/__init__.py0
-rw-r--r--tests/unit/mixins/test_meta_mixins.py58
-rw-r--r--tests/unit/mixins/test_mixin_methods.py300
-rw-r--r--tests/unit/mixins/test_object_mixins_attributes.py79
-rw-r--r--tests/unit/objects/__init__.py0
-rw-r--r--tests/unit/objects/conftest.py70
-rw-r--r--tests/unit/objects/test_appearance.py65
-rw-r--r--tests/unit/objects/test_applications.py44
-rw-r--r--tests/unit/objects/test_audit_events.py109
-rw-r--r--tests/unit/objects/test_badges.py210
-rw-r--r--tests/unit/objects/test_bridges.py109
-rw-r--r--tests/unit/objects/test_commits.py115
-rw-r--r--tests/unit/objects/test_deploy_tokens.py45
-rw-r--r--tests/unit/objects/test_deployments.py50
-rw-r--r--tests/unit/objects/test_environments.py30
-rw-r--r--tests/unit/objects/test_groups.py155
-rw-r--r--tests/unit/objects/test_hooks.py209
-rw-r--r--tests/unit/objects/test_issues.py88
-rw-r--r--tests/unit/objects/test_job_artifacts.py30
-rw-r--r--tests/unit/objects/test_jobs.py96
-rw-r--r--tests/unit/objects/test_keys.py54
-rw-r--r--tests/unit/objects/test_members.py58
-rw-r--r--tests/unit/objects/test_merge_request_pipelines.py53
-rw-r--r--tests/unit/objects/test_merge_requests.py56
-rw-r--r--tests/unit/objects/test_mro.py122
-rw-r--r--tests/unit/objects/test_packages.py252
-rw-r--r--tests/unit/objects/test_personal_access_tokens.py94
-rw-r--r--tests/unit/objects/test_pipeline_schedules.py62
-rw-r--r--tests/unit/objects/test_pipelines.py146
-rw-r--r--tests/unit/objects/test_project_access_tokens.py113
-rw-r--r--tests/unit/objects/test_project_import_export.py112
-rw-r--r--tests/unit/objects/test_project_merge_request_approvals.py317
-rw-r--r--tests/unit/objects/test_project_statistics.py28
-rw-r--r--tests/unit/objects/test_projects.py237
-rw-r--r--tests/unit/objects/test_releases.py170
-rw-r--r--tests/unit/objects/test_remote_mirrors.py72
-rw-r--r--tests/unit/objects/test_repositories.py49
-rw-r--r--tests/unit/objects/test_resource_label_events.py105
-rw-r--r--tests/unit/objects/test_resource_milestone_events.py73
-rw-r--r--tests/unit/objects/test_resource_state_events.py104
-rw-r--r--tests/unit/objects/test_runners.py282
-rw-r--r--tests/unit/objects/test_services.py93
-rw-r--r--tests/unit/objects/test_snippets.py89
-rw-r--r--tests/unit/objects/test_submodules.py46
-rw-r--r--tests/unit/objects/test_todos.py62
-rw-r--r--tests/unit/objects/test_users.py217
-rw-r--r--tests/unit/objects/test_variables.py192
-rw-r--r--tests/unit/test_base.py179
-rw-r--r--tests/unit/test_cli.py157
-rw-r--r--tests/unit/test_config.py317
-rw-r--r--tests/unit/test_exceptions.py18
-rw-r--r--tests/unit/test_gitlab.py196
-rw-r--r--tests/unit/test_gitlab_auth.py85
-rw-r--r--tests/unit/test_gitlab_http_methods.py406
-rw-r--r--tests/unit/test_types.py74
-rw-r--r--tests/unit/test_utils.py42
59 files changed, 0 insertions, 6753 deletions
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tests/unit/__init__.py
+++ /dev/null
diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
deleted file mode 100644
index f58c77a..0000000
--- a/tests/unit/conftest.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import pytest
-
-import gitlab
-
-
-@pytest.fixture
-def gl():
- return gitlab.Gitlab(
- "http://localhost",
- private_token="private_token",
- ssl_verify=True,
- api_version="4",
- )
-
-
-@pytest.fixture
-def gl_retry():
- return gitlab.Gitlab(
- "http://localhost",
- private_token="private_token",
- ssl_verify=True,
- api_version="4",
- retry_transient_errors=True,
- )
-
-
-# Todo: parametrize, but check what tests it's really useful for
-@pytest.fixture
-def gl_trailing():
- return gitlab.Gitlab(
- "http://localhost/", private_token="private_token", api_version="4"
- )
-
-
-@pytest.fixture
-def default_config(tmpdir):
- valid_config = """[global]
- default = one
- ssl_verify = true
- timeout = 2
-
- [one]
- url = http://one.url
- private_token = ABCDEF
- """
-
- config_path = tmpdir.join("python-gitlab.cfg")
- config_path.write(valid_config)
- return str(config_path)
-
-
-@pytest.fixture
-def tag_name():
- return "v1.0.0"
-
-
-@pytest.fixture
-def group(gl):
- return gl.groups.get(1, lazy=True)
-
-
-@pytest.fixture
-def project(gl):
- return gl.projects.get(1, lazy=True)
-
-
-@pytest.fixture
-def project_issue(project):
- return project.issues.get(1, lazy=True)
-
-
-@pytest.fixture
-def project_merge_request(project):
- return project.mergerequests.get(1, lazy=True)
-
-
-@pytest.fixture
-def release(project, tag_name):
- return project.releases.get(tag_name, lazy=True)
-
-
-@pytest.fixture
-def user(gl):
- return gl.users.get(1, lazy=True)
diff --git a/tests/unit/data/todo.json b/tests/unit/data/todo.json
deleted file mode 100644
index 93b2151..0000000
--- a/tests/unit/data/todo.json
+++ /dev/null
@@ -1,75 +0,0 @@
-[
- {
- "id": 102,
- "project": {
- "id": 2,
- "name": "Gitlab Ce",
- "name_with_namespace": "Gitlab Org / Gitlab Ce",
- "path": "gitlab-ce",
- "path_with_namespace": "gitlab-org/gitlab-ce"
- },
- "author": {
- "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"
- },
- "action_name": "marked",
- "target_type": "MergeRequest",
- "target": {
- "id": 34,
- "iid": 7,
- "project_id": 2,
- "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",
- "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.",
- "state": "opened",
- "created_at": "2016-06-17T07:49:24.419Z",
- "updated_at": "2016-06-17T07:52:43.484Z",
- "target_branch": "tutorials_git_tricks",
- "source_branch": "DNSBL_docs",
- "upvotes": 0,
- "downvotes": 0,
- "author": {
- "name": "Maxie Medhurst",
- "username": "craig_rutherford",
- "id": 12,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
- "web_url": "https://gitlab.example.com/craig_rutherford"
- },
- "assignee": {
- "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"
- },
- "source_project_id": 2,
- "target_project_id": 2,
- "labels": [],
- "work_in_progress": false,
- "milestone": {
- "id": 32,
- "iid": 2,
- "project_id": 2,
- "title": "v1.0",
- "description": "Assumenda placeat ea voluptatem voluptate qui.",
- "state": "active",
- "created_at": "2016-06-17T07:47:34.163Z",
- "updated_at": "2016-06-17T07:47:34.163Z",
- "due_date": null
- },
- "merge_when_pipeline_succeeds": false,
- "merge_status": "cannot_be_merged",
- "subscribed": true,
- "user_notes_count": 7
- },
- "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7",
- "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",
- "state": "pending",
- "created_at": "2016-06-17T07:52:35.225Z"
- }
-]
diff --git a/tests/unit/mixins/__init__.py b/tests/unit/mixins/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tests/unit/mixins/__init__.py
+++ /dev/null
diff --git a/tests/unit/mixins/test_meta_mixins.py b/tests/unit/mixins/test_meta_mixins.py
deleted file mode 100644
index 4c8845b..0000000
--- a/tests/unit/mixins/test_meta_mixins.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from gitlab.mixins import (
- CreateMixin,
- CRUDMixin,
- DeleteMixin,
- GetMixin,
- ListMixin,
- NoUpdateMixin,
- RetrieveMixin,
- UpdateMixin,
-)
-
-
-def test_retrieve_mixin():
- class M(RetrieveMixin):
- pass
-
- obj = M()
- assert hasattr(obj, "list")
- assert hasattr(obj, "get")
- assert not hasattr(obj, "create")
- assert not hasattr(obj, "update")
- assert not hasattr(obj, "delete")
- assert isinstance(obj, ListMixin)
- assert isinstance(obj, GetMixin)
-
-
-def test_crud_mixin():
- class M(CRUDMixin):
- pass
-
- obj = M()
- assert hasattr(obj, "get")
- assert hasattr(obj, "list")
- assert hasattr(obj, "create")
- assert hasattr(obj, "update")
- assert hasattr(obj, "delete")
- assert isinstance(obj, ListMixin)
- assert isinstance(obj, GetMixin)
- assert isinstance(obj, CreateMixin)
- assert isinstance(obj, UpdateMixin)
- assert isinstance(obj, DeleteMixin)
-
-
-def test_no_update_mixin():
- class M(NoUpdateMixin):
- pass
-
- obj = M()
- assert hasattr(obj, "get")
- assert hasattr(obj, "list")
- assert hasattr(obj, "create")
- assert not hasattr(obj, "update")
- assert hasattr(obj, "delete")
- assert isinstance(obj, ListMixin)
- assert isinstance(obj, GetMixin)
- assert isinstance(obj, CreateMixin)
- assert not isinstance(obj, UpdateMixin)
- assert isinstance(obj, DeleteMixin)
diff --git a/tests/unit/mixins/test_mixin_methods.py b/tests/unit/mixins/test_mixin_methods.py
deleted file mode 100644
index 626230e..0000000
--- a/tests/unit/mixins/test_mixin_methods.py
+++ /dev/null
@@ -1,300 +0,0 @@
-import pytest
-from httmock import HTTMock, response, urlmatch # noqa
-
-from gitlab import base
-from gitlab.mixins import (
- CreateMixin,
- DeleteMixin,
- GetMixin,
- GetWithoutIdMixin,
- ListMixin,
- RefreshMixin,
- SaveMixin,
- SetMixin,
- UpdateMixin,
-)
-
-
-class FakeObject(base.RESTObject):
- pass
-
-
-class FakeManager(base.RESTManager):
- _path = "/tests"
- _obj_cls = FakeObject
-
-
-def test_get_mixin(gl):
- class M(GetMixin, FakeManager):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/42", method="get")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = mgr.get(42)
- assert isinstance(obj, FakeObject)
- assert obj.foo == "bar"
- assert obj.id == 42
-
-
-def test_refresh_mixin(gl):
- class TestClass(RefreshMixin, FakeObject):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/42", method="get")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = FakeManager(gl)
- obj = TestClass(mgr, {"id": 42})
- res = obj.refresh()
- assert res is None
- assert obj.foo == "bar"
- assert obj.id == 42
-
-
-def test_get_without_id_mixin(gl):
- class M(GetWithoutIdMixin, FakeManager):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="get")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"foo": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = mgr.get()
- assert isinstance(obj, FakeObject)
- assert obj.foo == "bar"
- assert not hasattr(obj, "id")
-
-
-def test_list_mixin(gl):
- class M(ListMixin, FakeManager):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="get")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '[{"id": 42, "foo": "bar"},{"id": 43, "foo": "baz"}]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- # test RESTObjectList
- mgr = M(gl)
- obj_list = mgr.list(as_list=False)
- assert isinstance(obj_list, base.RESTObjectList)
- for obj in obj_list:
- assert isinstance(obj, FakeObject)
- assert obj.id in (42, 43)
-
- # test list()
- obj_list = mgr.list(all=True)
- assert isinstance(obj_list, list)
- assert obj_list[0].id == 42
- assert obj_list[1].id == 43
- assert isinstance(obj_list[0], FakeObject)
- assert len(obj_list) == 2
-
-
-def test_list_other_url(gl):
- class M(ListMixin, FakeManager):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/others", method="get")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '[{"id": 42, "foo": "bar"}]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj_list = mgr.list(path="/others", as_list=False)
- assert isinstance(obj_list, base.RESTObjectList)
- obj = obj_list.next()
- assert obj.id == 42
- assert obj.foo == "bar"
- with pytest.raises(StopIteration):
- obj_list.next()
-
-
-def test_create_mixin_missing_attrs(gl):
- class M(CreateMixin, FakeManager):
- _create_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
-
- mgr = M(gl)
- data = {"foo": "bar", "baz": "blah"}
- mgr._check_missing_create_attrs(data)
-
- data = {"baz": "blah"}
- with pytest.raises(AttributeError) as error:
- mgr._check_missing_create_attrs(data)
- assert "foo" in str(error.value)
-
-
-def test_create_mixin(gl):
- class M(CreateMixin, FakeManager):
- _create_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
- _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="post")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = mgr.create({"foo": "bar"})
- assert isinstance(obj, FakeObject)
- assert obj.id == 42
- assert obj.foo == "bar"
-
-
-def test_create_mixin_custom_path(gl):
- class M(CreateMixin, FakeManager):
- _create_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
- _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/others", method="post")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = mgr.create({"foo": "bar"}, path="/others")
- assert isinstance(obj, FakeObject)
- assert obj.id == 42
- assert obj.foo == "bar"
-
-
-def test_update_mixin_missing_attrs(gl):
- class M(UpdateMixin, FakeManager):
- _update_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
-
- mgr = M(gl)
- data = {"foo": "bar", "baz": "blah"}
- mgr._check_missing_update_attrs(data)
-
- data = {"baz": "blah"}
- with pytest.raises(AttributeError) as error:
- mgr._check_missing_update_attrs(data)
- assert "foo" in str(error.value)
-
-
-def test_update_mixin(gl):
- class M(UpdateMixin, FakeManager):
- _create_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
- _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/42", method="put")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "baz"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- server_data = mgr.update(42, {"foo": "baz"})
- assert isinstance(server_data, dict)
- assert server_data["id"] == 42
- assert server_data["foo"] == "baz"
-
-
-def test_update_mixin_no_id(gl):
- class M(UpdateMixin, FakeManager):
- _create_attrs = base.RequiredOptional(
- required=("foo",), optional=("bar", "baz")
- )
- _update_attrs = base.RequiredOptional(required=("foo",), optional=("bam",))
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="put")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"foo": "baz"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- server_data = mgr.update(new_data={"foo": "baz"})
- assert isinstance(server_data, dict)
- assert server_data["foo"] == "baz"
-
-
-def test_delete_mixin(gl):
- class M(DeleteMixin, FakeManager):
- pass
-
- @urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/tests/42", method="delete"
- )
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = ""
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- mgr.delete(42)
-
-
-def test_save_mixin(gl):
- class M(UpdateMixin, FakeManager):
- pass
-
- class TestClass(SaveMixin, base.RESTObject):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/42", method="put")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"id": 42, "foo": "baz"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = TestClass(mgr, {"id": 42, "foo": "bar"})
- obj.foo = "baz"
- obj.save()
- assert obj._attrs["foo"] == "baz"
- assert obj._updated_attrs == {}
-
-
-def test_set_mixin(gl):
- class M(SetMixin, FakeManager):
- pass
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests/foo", method="put")
- def resp_cont(url, request):
- headers = {"Content-Type": "application/json"}
- content = '{"key": "foo", "value": "bar"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- mgr = M(gl)
- obj = mgr.set("foo", "bar")
- assert isinstance(obj, FakeObject)
- assert obj.key == "foo"
- assert obj.value == "bar"
diff --git a/tests/unit/mixins/test_object_mixins_attributes.py b/tests/unit/mixins/test_object_mixins_attributes.py
deleted file mode 100644
index d54fa3a..0000000
--- a/tests/unit/mixins/test_object_mixins_attributes.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2014 Mika Mäenpää <mika.j.maenpaa@tut.fi>,
-# Tampere University of Technology
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from gitlab.mixins import (
- AccessRequestMixin,
- SetMixin,
- SubscribableMixin,
- TimeTrackingMixin,
- TodoMixin,
- UserAgentDetailMixin,
-)
-
-
-def test_access_request_mixin():
- class TestClass(AccessRequestMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "approve")
-
-
-def test_subscribable_mixin():
- class TestClass(SubscribableMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "subscribe")
- assert hasattr(obj, "unsubscribe")
-
-
-def test_todo_mixin():
- class TestClass(TodoMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "todo")
-
-
-def test_time_tracking_mixin():
- class TestClass(TimeTrackingMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "time_stats")
- assert hasattr(obj, "time_estimate")
- assert hasattr(obj, "reset_time_estimate")
- assert hasattr(obj, "add_spent_time")
- assert hasattr(obj, "reset_spent_time")
-
-
-def test_set_mixin():
- class TestClass(SetMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "set")
-
-
-def test_user_agent_detail_mixin():
- class TestClass(UserAgentDetailMixin):
- pass
-
- obj = TestClass()
- assert hasattr(obj, "user_agent_detail")
diff --git a/tests/unit/objects/__init__.py b/tests/unit/objects/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tests/unit/objects/__init__.py
+++ /dev/null
diff --git a/tests/unit/objects/conftest.py b/tests/unit/objects/conftest.py
deleted file mode 100644
index d8a40d9..0000000
--- a/tests/unit/objects/conftest.py
+++ /dev/null
@@ -1,70 +0,0 @@
-"""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 no_content():
- return {"message": "204 No Content"}
-
-
-@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/tests/unit/objects/test_appearance.py b/tests/unit/objects/test_appearance.py
deleted file mode 100644
index 0de6524..0000000
--- a/tests/unit/objects/test_appearance.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
-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):
- gl.appearance.update(title=new_title, description=new_description)
diff --git a/tests/unit/objects/test_applications.py b/tests/unit/objects/test_applications.py
deleted file mode 100644
index 61de019..0000000
--- a/tests/unit/objects/test_applications.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""
-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/tests/unit/objects/test_audit_events.py b/tests/unit/objects/test_audit_events.py
deleted file mode 100644
index aba778b..0000000
--- a/tests/unit/objects/test_audit_events.py
+++ /dev/null
@@ -1,109 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ee/api/audit_events.html#project-audit-events
-"""
-
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects.audit_events import (
- AuditEvent,
- GroupAuditEvent,
- ProjectAuditEvent,
-)
-
-id = 5
-
-audit_events_content = {
- "id": 5,
- "author_id": 1,
- "entity_id": 7,
- "entity_type": "Project",
- "details": {
- "change": "prevent merge request approval from reviewers",
- "from": "",
- "to": "true",
- "author_name": "Administrator",
- "target_id": 7,
- "target_type": "Project",
- "target_details": "twitter/typeahead-js",
- "ip_address": "127.0.0.1",
- "entity_path": "twitter/typeahead-js",
- },
- "created_at": "2020-05-26T22:55:04.230Z",
-}
-
-audit_events_url = re.compile(
- r"http://localhost/api/v4/((groups|projects)/1/)?audit_events"
-)
-
-audit_events_url_id = re.compile(
- rf"http://localhost/api/v4/((groups|projects)/1/)?audit_events/{id}"
-)
-
-
-@pytest.fixture
-def resp_list_audit_events():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=audit_events_url,
- json=[audit_events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_audit_event():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=audit_events_url_id,
- json=audit_events_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_instance_audit_events(gl, resp_list_audit_events):
- audit_events = gl.audit_events.list()
- assert isinstance(audit_events, list)
- assert isinstance(audit_events[0], AuditEvent)
- assert audit_events[0].id == id
-
-
-def test_get_instance_audit_events(gl, resp_get_audit_event):
- audit_event = gl.audit_events.get(id)
- assert isinstance(audit_event, AuditEvent)
- assert audit_event.id == id
-
-
-def test_list_group_audit_events(group, resp_list_audit_events):
- audit_events = group.audit_events.list()
- assert isinstance(audit_events, list)
- assert isinstance(audit_events[0], GroupAuditEvent)
- assert audit_events[0].id == id
-
-
-def test_get_group_audit_events(group, resp_get_audit_event):
- audit_event = group.audit_events.get(id)
- assert isinstance(audit_event, GroupAuditEvent)
- assert audit_event.id == id
-
-
-def test_list_project_audit_events(project, resp_list_audit_events):
- audit_events = project.audit_events.list()
- assert isinstance(audit_events, list)
- assert isinstance(audit_events[0], ProjectAuditEvent)
- assert audit_events[0].id == id
-
-
-def test_get_project_audit_events(project, resp_get_audit_event):
- audit_event = project.audit_events.get(id)
- assert isinstance(audit_event, ProjectAuditEvent)
- assert audit_event.id == id
diff --git a/tests/unit/objects/test_badges.py b/tests/unit/objects/test_badges.py
deleted file mode 100644
index e226684..0000000
--- a/tests/unit/objects/test_badges.py
+++ /dev/null
@@ -1,210 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/project_badges.html
-GitLab API: https://docs.gitlab.com/ee/api/group_badges.html
-"""
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import GroupBadge, ProjectBadge
-
-link_url = (
- "http://example.com/ci_status.svg?project=example-org/example-project&ref=master"
-)
-image_url = "https://example.io/my/badge"
-
-rendered_link_url = (
- "http://example.com/ci_status.svg?project=example-org/example-project&ref=master"
-)
-rendered_image_url = "https://example.io/my/badge"
-
-new_badge = {
- "link_url": link_url,
- "image_url": image_url,
-}
-
-badge_content = {
- "name": "Coverage",
- "id": 1,
- "link_url": link_url,
- "image_url": image_url,
- "rendered_link_url": rendered_image_url,
- "rendered_image_url": rendered_image_url,
-}
-
-preview_badge_content = {
- "link_url": link_url,
- "image_url": image_url,
- "rendered_link_url": rendered_link_url,
- "rendered_image_url": rendered_image_url,
-}
-
-
-@pytest.fixture()
-def resp_get_badge():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r"http://localhost/api/v4/(projects|groups)/1/badges/1"),
- json=badge_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_list_badges():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r"http://localhost/api/v4/(projects|groups)/1/badges"),
- json=[badge_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_create_badge():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url=re.compile(r"http://localhost/api/v4/(projects|groups)/1/badges"),
- json=badge_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_update_badge():
- updated_content = dict(badge_content)
- updated_content["link_url"] = "http://link_url"
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.PUT,
- url=re.compile(r"http://localhost/api/v4/(projects|groups)/1/badges/1"),
- json=updated_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_delete_badge(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url=re.compile(r"http://localhost/api/v4/(projects|groups)/1/badges/1"),
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_preview_badge():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(
- r"http://localhost/api/v4/(projects|groups)/1/badges/render"
- ),
- json=preview_badge_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_project_badges(project, resp_list_badges):
- badges = project.badges.list()
- assert isinstance(badges, list)
- assert isinstance(badges[0], ProjectBadge)
-
-
-def test_list_group_badges(group, resp_list_badges):
- badges = group.badges.list()
- assert isinstance(badges, list)
- assert isinstance(badges[0], GroupBadge)
-
-
-def test_get_project_badge(project, resp_get_badge):
- badge = project.badges.get(1)
- assert isinstance(badge, ProjectBadge)
- assert badge.name == "Coverage"
- assert badge.id == 1
-
-
-def test_get_group_badge(group, resp_get_badge):
- badge = group.badges.get(1)
- assert isinstance(badge, GroupBadge)
- assert badge.name == "Coverage"
- assert badge.id == 1
-
-
-def test_delete_project_badge(project, resp_delete_badge):
- badge = project.badges.get(1, lazy=True)
- badge.delete()
-
-
-def test_delete_group_badge(group, resp_delete_badge):
- badge = group.badges.get(1, lazy=True)
- badge.delete()
-
-
-def test_create_project_badge(project, resp_create_badge):
- badge = project.badges.create(new_badge)
- assert isinstance(badge, ProjectBadge)
- assert badge.image_url == image_url
-
-
-def test_create_group_badge(group, resp_create_badge):
- badge = group.badges.create(new_badge)
- assert isinstance(badge, GroupBadge)
- assert badge.image_url == image_url
-
-
-def test_preview_project_badge(project, resp_preview_badge):
- output = project.badges.render(
- link_url=link_url,
- image_url=image_url,
- )
- assert isinstance(output, dict)
- assert "rendered_link_url" in output
- assert "rendered_image_url" in output
- assert output["link_url"] == output["rendered_link_url"]
- assert output["image_url"] == output["rendered_image_url"]
-
-
-def test_preview_group_badge(group, resp_preview_badge):
- output = group.badges.render(
- link_url=link_url,
- image_url=image_url,
- )
- assert isinstance(output, dict)
- assert "rendered_link_url" in output
- assert "rendered_image_url" in output
- assert output["link_url"] == output["rendered_link_url"]
- assert output["image_url"] == output["rendered_image_url"]
-
-
-def test_update_project_badge(project, resp_update_badge):
- badge = project.badges.get(1, lazy=True)
- badge.link_url = "http://link_url"
- badge.save()
- assert badge.link_url == "http://link_url"
-
-
-def test_update_group_badge(group, resp_update_badge):
- badge = group.badges.get(1, lazy=True)
- badge.link_url = "http://link_url"
- badge.save()
- assert badge.link_url == "http://link_url"
diff --git a/tests/unit/objects/test_bridges.py b/tests/unit/objects/test_bridges.py
deleted file mode 100644
index 4d39186..0000000
--- a/tests/unit/objects/test_bridges.py
+++ /dev/null
@@ -1,109 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/jobs.html#list-pipeline-bridges
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectPipelineBridge
-
-
-@pytest.fixture
-def resp_list_bridges():
- export_bridges_content = {
- "commit": {
- "author_email": "admin@example.com",
- "author_name": "Administrator",
- "created_at": "2015-12-24T16:51:14.000+01:00",
- "id": "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd",
- "message": "Test the CI integration.",
- "short_id": "0ff3ae19",
- "title": "Test the CI integration.",
- },
- "allow_failure": False,
- "created_at": "2015-12-24T15:51:21.802Z",
- "started_at": "2015-12-24T17:54:27.722Z",
- "finished_at": "2015-12-24T17:58:27.895Z",
- "duration": 240,
- "id": 7,
- "name": "teaspoon",
- "pipeline": {
- "id": 6,
- "ref": "master",
- "sha": "0ff3ae198f8601a285adcf5c0fff204ee6fba5fd",
- "status": "pending",
- "created_at": "2015-12-24T15:50:16.123Z",
- "updated_at": "2015-12-24T18:00:44.432Z",
- "web_url": "https://example.com/foo/bar/pipelines/6",
- },
- "ref": "master",
- "stage": "test",
- "status": "pending",
- "tag": False,
- "web_url": "https://example.com/foo/bar/-/jobs/7",
- "user": {
- "id": 1,
- "name": "Administrator",
- "username": "root",
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://gitlab.dev/root",
- "created_at": "2015-12-21T13:14:24.077Z",
- "public_email": "",
- "skype": "",
- "linkedin": "",
- "twitter": "",
- "website_url": "",
- "organization": "",
- },
- "downstream_pipeline": {
- "id": 5,
- "sha": "f62a4b2fb89754372a346f24659212eb8da13601",
- "ref": "master",
- "status": "pending",
- "created_at": "2015-12-24T17:54:27.722Z",
- "updated_at": "2015-12-24T17:58:27.896Z",
- "web_url": "https://example.com/diaspora/diaspora-client/pipelines/5",
- },
- }
-
- export_pipelines_content = [
- {
- "id": 6,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
- },
- ]
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/pipelines/6/bridges",
- json=[export_bridges_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/pipelines",
- json=export_pipelines_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_projects_pipelines_bridges(project, resp_list_bridges):
- pipeline = project.pipelines.list()[0]
- bridges = pipeline.bridges.list()
-
- assert isinstance(bridges, list)
- assert isinstance(bridges[0], ProjectPipelineBridge)
- assert bridges[0].downstream_pipeline["id"] == 5
- assert (
- bridges[0].downstream_pipeline["sha"]
- == "f62a4b2fb89754372a346f24659212eb8da13601"
- )
diff --git a/tests/unit/objects/test_commits.py b/tests/unit/objects/test_commits.py
deleted file mode 100644
index 6b98117..0000000
--- a/tests/unit/objects/test_commits.py
+++ /dev/null
@@ -1,115 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/commits.html
-"""
-
-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"
-
-
-def test_create_commit(project, resp_create_commit):
- 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"]
-
-
-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"'
-
-
-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"
- assert signature["verification_status"] == "verified"
diff --git a/tests/unit/objects/test_deploy_tokens.py b/tests/unit/objects/test_deploy_tokens.py
deleted file mode 100644
index 66a79fa..0000000
--- a/tests/unit/objects/test_deploy_tokens.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/deploy_tokens.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectDeployToken
-
-create_content = {
- "id": 1,
- "name": "test_deploy_token",
- "username": "custom-user",
- "expires_at": "2022-01-01T00:00:00.000Z",
- "token": "jMRvtPNxrn3crTAGukpZ",
- "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
-
-
-def test_deploy_tokens(gl, resp_deploy_token_create):
- 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/tests/unit/objects/test_deployments.py b/tests/unit/objects/test_deployments.py
deleted file mode 100644
index 3cde8fe..0000000
--- a/tests/unit/objects/test_deployments.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/deployments.html
-"""
-import pytest
-import responses
-
-
-@pytest.fixture
-def resp_deployment():
- content = {"id": 42, "status": "success", "ref": "master"}
-
- 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,
- )
-
- 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
-
-
-def test_deployment(project, resp_deployment):
- 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"
-
- deployment.status = "failed"
- deployment.save()
- assert deployment.status == "failed"
diff --git a/tests/unit/objects/test_environments.py b/tests/unit/objects/test_environments.py
deleted file mode 100644
index b49a1db..0000000
--- a/tests/unit/objects/test_environments.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/environments.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectEnvironment
-
-
-@pytest.fixture
-def resp_get_environment():
- content = {"name": "environment_name", "id": 1, "last_deployment": "sometime"}
-
- 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
-
-
-def test_project_environments(project, resp_get_environment):
- 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/tests/unit/objects/test_groups.py b/tests/unit/objects/test_groups.py
deleted file mode 100644
index 37023d8..0000000
--- a/tests/unit/objects/test_groups.py
+++ /dev/null
@@ -1,155 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/groups.html
-"""
-
-import re
-
-import pytest
-import responses
-
-import gitlab
-from gitlab.v4.objects import GroupDescendantGroup, GroupSubgroup
-
-subgroup_descgroup_content = [
- {
- "id": 2,
- "name": "Bar Group",
- "path": "foo/bar",
- "description": "A subgroup of Foo Group",
- "visibility": "public",
- "share_with_group_lock": False,
- "require_two_factor_authentication": False,
- "two_factor_grace_period": 48,
- "project_creation_level": "developer",
- "auto_devops_enabled": None,
- "subgroup_creation_level": "owner",
- "emails_disabled": None,
- "mentions_disabled": None,
- "lfs_enabled": True,
- "default_branch_protection": 2,
- "avatar_url": "http://gitlab.example.com/uploads/group/avatar/1/bar.jpg",
- "web_url": "http://gitlab.example.com/groups/foo/bar",
- "request_access_enabled": False,
- "full_name": "Bar Group",
- "full_path": "foo/bar",
- "file_template_project_id": 1,
- "parent_id": 123,
- "created_at": "2020-01-15T12:36:29.590Z",
- },
-]
-
-
-@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_list_subgroups_descendant_groups():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(
- r"http://localhost/api/v4/groups/1/(subgroups|descendant_groups)"
- ),
- json=subgroup_descgroup_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"
- assert data.path == "path"
- assert data.id == 1
-
-
-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)
- assert data.name == name
- assert data.path == path
-
-
-def test_create_group_export(group, resp_export):
- export = group.exports.create()
- assert export.message == "202 Accepted"
-
-
-def test_list_group_subgroups(group, resp_list_subgroups_descendant_groups):
- subgroups = group.subgroups.list()
- assert isinstance(subgroups[0], GroupSubgroup)
- assert subgroups[0].path == subgroup_descgroup_content[0]["path"]
-
-
-def test_list_group_descendant_groups(group, resp_list_subgroups_descendant_groups):
- descendant_groups = group.descendant_groups.list()
- assert isinstance(descendant_groups[0], GroupDescendantGroup)
- assert descendant_groups[0].path == subgroup_descgroup_content[0]["path"]
-
-
-@pytest.mark.skip("GitLab API endpoint not implemented")
-def test_refresh_group_export_status(group, resp_export):
- export = group.exports.create()
- export.refresh()
- assert export.export_status == "finished"
-
-
-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
-
-
-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")
-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/tests/unit/objects/test_hooks.py b/tests/unit/objects/test_hooks.py
deleted file mode 100644
index 0f9dbe2..0000000
--- a/tests/unit/objects/test_hooks.py
+++ /dev/null
@@ -1,209 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/system_hooks.html
-GitLab API: https://docs.gitlab.com/ce/api/groups.html#hooks
-GitLab API: https://docs.gitlab.com/ee/api/projects.html#hooks
-"""
-
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import GroupHook, Hook, ProjectHook
-
-hooks_content = [
- {
- "id": 1,
- "url": "testurl",
- "push_events": True,
- "tag_push_events": True,
- },
- {
- "id": 2,
- "url": "testurl_second",
- "push_events": False,
- "tag_push_events": False,
- },
-]
-
-hook_content = hooks_content[0]
-
-
-@pytest.fixture
-def resp_hooks_list():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r"http://localhost/api/v4/((groups|projects)/1/|)hooks"),
- json=hooks_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_hook_get():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r"http://localhost/api/v4/((groups|projects)/1/|)hooks/1"),
- json=hook_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_hook_create():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url=re.compile(r"http://localhost/api/v4/((groups|projects)/1/|)hooks"),
- json=hook_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_hook_update():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r"http://localhost/api/v4/((groups|projects)/1/|)hooks/1")
- rsps.add(
- method=responses.GET,
- url=pattern,
- json=hook_content,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.PUT,
- url=pattern,
- json=hook_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_hook_delete():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r"http://localhost/api/v4/((groups|projects)/1/|)hooks/1")
- rsps.add(
- method=responses.GET,
- url=pattern,
- json=hook_content,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.DELETE,
- url=pattern,
- status=204,
- )
- yield rsps
-
-
-def test_list_system_hooks(gl, resp_hooks_list):
- hooks = gl.hooks.list()
- assert hooks[0].id == 1
- assert hooks[0].url == "testurl"
- assert hooks[1].id == 2
- assert hooks[1].url == "testurl_second"
-
-
-def test_get_system_hook(gl, resp_hook_get):
- data = gl.hooks.get(1)
- assert isinstance(data, Hook)
- assert data.url == "testurl"
- assert data.id == 1
-
-
-def test_create_system_hook(gl, resp_hook_create):
- hook = gl.hooks.create(hook_content)
- assert hook.url == "testurl"
- assert hook.push_events is True
- assert hook.tag_push_events is True
-
-
-# there is no update method for system hooks
-
-
-def test_delete_system_hook(gl, resp_hook_delete):
- hook = gl.hooks.get(1)
- hook.delete()
- gl.hooks.delete(1)
-
-
-def test_list_group_hooks(group, resp_hooks_list):
- hooks = group.hooks.list()
- assert hooks[0].id == 1
- assert hooks[0].url == "testurl"
- assert hooks[1].id == 2
- assert hooks[1].url == "testurl_second"
-
-
-def test_get_group_hook(group, resp_hook_get):
- data = group.hooks.get(1)
- assert isinstance(data, GroupHook)
- assert data.url == "testurl"
- assert data.id == 1
-
-
-def test_create_group_hook(group, resp_hook_create):
- hook = group.hooks.create(hook_content)
- assert hook.url == "testurl"
- assert hook.push_events is True
- assert hook.tag_push_events is True
-
-
-def test_update_group_hook(group, resp_hook_update):
- hook = group.hooks.get(1)
- assert hook.id == 1
- hook.url = "testurl_more"
- hook.save()
-
-
-def test_delete_group_hook(group, resp_hook_delete):
- hook = group.hooks.get(1)
- hook.delete()
- group.hooks.delete(1)
-
-
-def test_list_project_hooks(project, resp_hooks_list):
- hooks = project.hooks.list()
- assert hooks[0].id == 1
- assert hooks[0].url == "testurl"
- assert hooks[1].id == 2
- assert hooks[1].url == "testurl_second"
-
-
-def test_get_project_hook(project, resp_hook_get):
- data = project.hooks.get(1)
- assert isinstance(data, ProjectHook)
- assert data.url == "testurl"
- assert data.id == 1
-
-
-def test_create_project_hook(project, resp_hook_create):
- hook = project.hooks.create(hook_content)
- assert hook.url == "testurl"
- assert hook.push_events is True
- assert hook.tag_push_events is True
-
-
-def test_update_project_hook(project, resp_hook_update):
- hook = project.hooks.get(1)
- assert hook.id == 1
- hook.url = "testurl_more"
- hook.save()
-
-
-def test_delete_project_hook(project, resp_hook_delete):
- hook = project.hooks.get(1)
- hook.delete()
- project.hooks.delete(1)
diff --git a/tests/unit/objects/test_issues.py b/tests/unit/objects/test_issues.py
deleted file mode 100644
index a4e1454..0000000
--- a/tests/unit/objects/test_issues.py
+++ /dev/null
@@ -1,88 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/issues.html
-"""
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import (
- GroupIssuesStatistics,
- IssuesStatistics,
- ProjectIssuesStatistics,
-)
-
-
-@pytest.fixture
-def resp_list_issues():
- 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
-
-
-@pytest.fixture
-def resp_get_issue():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/issues/1",
- json={"name": "name", "id": 1},
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_issue_statistics():
- content = {"statistics": {"counts": {"all": 20, "closed": 5, "opened": 15}}}
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(
- r"http://localhost/api/v4/((groups|projects)/1/)?issues_statistics"
- ),
- json=content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_issues(gl, resp_list_issues):
- data = gl.issues.list()
- assert data[1].id == 2
- assert data[1].name == "other_name"
-
-
-def test_get_issue(gl, resp_get_issue):
- issue = gl.issues.get(1)
- assert issue.id == 1
- assert issue.name == "name"
-
-
-def test_get_issues_statistics(gl, resp_issue_statistics):
- statistics = gl.issues_statistics.get()
- assert isinstance(statistics, IssuesStatistics)
- assert statistics.statistics["counts"]["all"] == 20
-
-
-def test_get_group_issues_statistics(group, resp_issue_statistics):
- statistics = group.issues_statistics.get()
- assert isinstance(statistics, GroupIssuesStatistics)
- assert statistics.statistics["counts"]["all"] == 20
-
-
-def test_get_project_issues_statistics(project, resp_issue_statistics):
- statistics = project.issues_statistics.get()
- assert isinstance(statistics, ProjectIssuesStatistics)
- assert statistics.statistics["counts"]["all"] == 20
diff --git a/tests/unit/objects/test_job_artifacts.py b/tests/unit/objects/test_job_artifacts.py
deleted file mode 100644
index 7c5f1df..0000000
--- a/tests/unit/objects/test_job_artifacts.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/job_artifacts.html
-"""
-
-import pytest
-import responses
-
-ref_name = "master"
-job = "build"
-
-
-@pytest.fixture
-def resp_artifacts_by_ref_name(binary_content):
- url = f"http://localhost/api/v4/projects/1/jobs/artifacts/{ref_name}/download?job={job}"
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=url,
- body=binary_content,
- content_type="application/octet-stream",
- status=200,
- )
- yield rsps
-
-
-def test_download_artifacts_by_ref_name(gl, binary_content, resp_artifacts_by_ref_name):
- project = gl.projects.get(1, lazy=True)
- artifacts = project.artifacts(ref_name=ref_name, job=job)
- assert artifacts == binary_content
diff --git a/tests/unit/objects/test_jobs.py b/tests/unit/objects/test_jobs.py
deleted file mode 100644
index 104d59d..0000000
--- a/tests/unit/objects/test_jobs.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/jobs.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectJob
-
-job_content = {
- "commit": {
- "author_email": "admin@example.com",
- "author_name": "Administrator",
- },
- "coverage": None,
- "allow_failure": False,
- "created_at": "2015-12-24T15:51:21.880Z",
- "started_at": "2015-12-24T17:54:30.733Z",
- "finished_at": "2015-12-24T17:54:31.198Z",
- "duration": 0.465,
- "queued_duration": 0.010,
- "artifacts_expire_at": "2016-01-23T17:54:31.198Z",
- "tag_list": ["docker runner", "macos-10.15"],
- "id": 1,
- "name": "rubocop",
- "pipeline": {
- "id": 1,
- "project_id": 1,
- },
- "ref": "master",
- "artifacts": [],
- "runner": None,
- "stage": "test",
- "status": "failed",
- "tag": False,
- "web_url": "https://example.com/foo/bar/-/jobs/1",
- "user": {"id": 1},
-}
-
-
-@pytest.fixture
-def resp_get_job():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/jobs/1",
- json=job_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_cancel_job():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/jobs/1/cancel",
- json=job_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_retry_job():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/jobs/1/retry",
- json=job_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-def test_get_project_job(project, resp_get_job):
- job = project.jobs.get(1)
- assert isinstance(job, ProjectJob)
- assert job.ref == "master"
-
-
-def test_cancel_project_job(project, resp_cancel_job):
- job = project.jobs.get(1, lazy=True)
-
- output = job.cancel()
- assert output["ref"] == "master"
-
-
-def test_retry_project_job(project, resp_retry_job):
- job = project.jobs.get(1, lazy=True)
-
- output = job.retry()
- assert output["ref"] == "master"
diff --git a/tests/unit/objects/test_keys.py b/tests/unit/objects/test_keys.py
deleted file mode 100644
index 187a309..0000000
--- a/tests/unit/objects/test_keys.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/keys.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import Key
-
-key_content = {"id": 1, "title": "title", "key": "ssh-keytype AAAAC3Nza/key comment"}
-
-
-@pytest.fixture
-def resp_get_key_by_id():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/keys/1",
- json=key_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_key_by_fingerprint():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/keys?fingerprint=foo",
- json=key_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_get_key_by_id(gl, resp_get_key_by_id):
- key = gl.keys.get(1)
- assert isinstance(key, Key)
- assert key.id == 1
- assert key.title == "title"
-
-
-def test_get_key_by_fingerprint(gl, resp_get_key_by_fingerprint):
- key = gl.keys.get(fingerprint="foo")
- assert isinstance(key, Key)
- assert key.id == 1
- assert key.title == "title"
-
-
-def test_get_key_missing_attrs(gl):
- with pytest.raises(AttributeError):
- gl.keys.get()
diff --git a/tests/unit/objects/test_members.py b/tests/unit/objects/test_members.py
deleted file mode 100644
index 6a39369..0000000
--- a/tests/unit/objects/test_members.py
+++ /dev/null
@@ -1,58 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/members.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import GroupBillableMember
-
-billable_members_content = [
- {
- "id": 1,
- "username": "raymond_smith",
- "name": "Raymond Smith",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
- "web_url": "http://192.168.1.8:3000/root",
- "last_activity_on": "2021-01-27",
- "membership_type": "group_member",
- "removable": True,
- }
-]
-
-
-@pytest.fixture
-def resp_list_billable_group_members():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/groups/1/billable_members",
- json=billable_members_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_delete_billable_group_member(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url="http://localhost/api/v4/groups/1/billable_members/1",
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-def test_list_group_billable_members(group, resp_list_billable_group_members):
- billable_members = group.billable_members.list()
- assert isinstance(billable_members, list)
- assert isinstance(billable_members[0], GroupBillableMember)
- assert billable_members[0].removable is True
-
-
-def test_delete_group_billable_member(group, resp_delete_billable_group_member):
- group.billable_members.delete(1)
diff --git a/tests/unit/objects/test_merge_request_pipelines.py b/tests/unit/objects/test_merge_request_pipelines.py
deleted file mode 100644
index 04b04a8..0000000
--- a/tests/unit/objects/test_merge_request_pipelines.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/merge_requests.html#list-mr-pipelines
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectMergeRequestPipeline
-
-pipeline_content = {
- "id": 1,
- "sha": "959e04d7c7a30600c894bd3c0cd0e1ce7f42c11d",
- "ref": "master",
- "status": "success",
-}
-
-
-@pytest.fixture()
-def resp_list_merge_request_pipelines():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines",
- json=[pipeline_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_create_merge_request_pipeline():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines",
- json=pipeline_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-def test_list_merge_requests_pipelines(project, resp_list_merge_request_pipelines):
- pipelines = project.mergerequests.get(1, lazy=True).pipelines.list()
- assert len(pipelines) == 1
- assert isinstance(pipelines[0], ProjectMergeRequestPipeline)
- assert pipelines[0].sha == pipeline_content["sha"]
-
-
-def test_create_merge_requests_pipelines(project, resp_create_merge_request_pipeline):
- pipeline = project.mergerequests.get(1, lazy=True).pipelines.create()
- assert isinstance(pipeline, ProjectMergeRequestPipeline)
- assert pipeline.sha == pipeline_content["sha"]
diff --git a/tests/unit/objects/test_merge_requests.py b/tests/unit/objects/test_merge_requests.py
deleted file mode 100644
index ee11f8a..0000000
--- a/tests/unit/objects/test_merge_requests.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ce/api/merge_requests.html
-https://docs.gitlab.com/ee/api/deployments.html#list-of-merge-requests-associated-with-a-deployment
-"""
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectDeploymentMergeRequest, ProjectMergeRequest
-
-mr_content = {
- "id": 1,
- "iid": 1,
- "project_id": 3,
- "title": "test1",
- "description": "fixed login page css paddings",
- "state": "merged",
- "merged_by": {
- "id": 87854,
- "name": "Douwe Maan",
- "username": "DouweM",
- "state": "active",
- "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
- "web_url": "https://gitlab.com/DouweM",
- },
-}
-
-
-@pytest.fixture
-def resp_list_merge_requests():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(
- r"http://localhost/api/v4/projects/1/(deployments/1/)?merge_requests"
- ),
- json=[mr_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_project_merge_requests(project, resp_list_merge_requests):
- mrs = project.mergerequests.list()
- assert isinstance(mrs[0], ProjectMergeRequest)
- assert mrs[0].iid == mr_content["iid"]
-
-
-def test_list_deployment_merge_requests(project, resp_list_merge_requests):
- deployment = project.deployments.get(1, lazy=True)
- mrs = deployment.mergerequests.list()
- assert isinstance(mrs[0], ProjectDeploymentMergeRequest)
- assert mrs[0].iid == mr_content["iid"]
diff --git a/tests/unit/objects/test_mro.py b/tests/unit/objects/test_mro.py
deleted file mode 100644
index 8f67b77..0000000
--- a/tests/unit/objects/test_mro.py
+++ /dev/null
@@ -1,122 +0,0 @@
-"""
-Ensure objects defined in gitlab.v4.objects have REST* as last item in class
-definition
-
-Original notes by John L. Villalovos
-
-An example of an incorrect definition:
- class ProjectPipeline(RESTObject, RefreshMixin, ObjectDeleteMixin):
- ^^^^^^^^^^ This should be at the end.
-
-Correct way would be:
- class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
- Correctly at the end ^^^^^^^^^^
-
-
-Why this is an issue:
-
- When we do type-checking for gitlab/mixins.py we make RESTObject or
- RESTManager the base class for the mixins
-
- Here is how our classes look when type-checking:
-
- class RESTObject(object):
- def __init__(self, manager: "RESTManager", attrs: Dict[str, Any]) -> None:
- ...
-
- class Mixin(RESTObject):
- ...
-
- # Wrong ordering here
- class Wrongv4Object(RESTObject, RefreshMixin):
- ...
-
- If we actually ran this in Python we would get the following error:
- class Wrongv4Object(RESTObject, Mixin):
- TypeError: Cannot create a consistent method resolution
- order (MRO) for bases RESTObject, Mixin
-
- When we are type-checking it fails to understand the class Wrongv4Object
- and thus we can't type check it correctly.
-
-Almost all classes in gitlab/v4/objects/*py were already correct before this
-check was added.
-"""
-import inspect
-
-import pytest
-
-import gitlab.v4.objects
-
-
-def test_show_issue():
- """Test case to demonstrate the TypeError that occurs"""
-
- class RESTObject(object):
- def __init__(self, manager: str, attrs: int) -> None:
- ...
-
- class Mixin(RESTObject):
- ...
-
- with pytest.raises(TypeError) as exc_info:
- # Wrong ordering here
- class Wrongv4Object(RESTObject, Mixin):
- ...
-
- # The error message in the exception should be:
- # TypeError: Cannot create a consistent method resolution
- # order (MRO) for bases RESTObject, Mixin
-
- # Make sure the exception string contains "MRO"
- assert "MRO" in exc_info.exconly()
-
- # Correctly ordered class, no exception
- class Correctv4Object(Mixin, RESTObject):
- ...
-
-
-def test_mros():
- """Ensure objects defined in gitlab.v4.objects have REST* as last item in
- class definition.
-
- We do this as we need to ensure the MRO (Method Resolution Order) is
- correct.
- """
-
- failed_messages = []
- for module_name, module_value in inspect.getmembers(gitlab.v4.objects):
- if not inspect.ismodule(module_value):
- # We only care about the modules
- continue
- # Iterate through all the classes in our module
- for class_name, class_value in inspect.getmembers(module_value):
- if not inspect.isclass(class_value):
- continue
-
- # Ignore imported classes from gitlab.base
- if class_value.__module__ == "gitlab.base":
- continue
-
- mro = class_value.mro()
-
- # We only check classes which have a 'gitlab.base' class in their MRO
- has_base = False
- for count, obj in enumerate(mro, start=1):
- if obj.__module__ == "gitlab.base":
- has_base = True
- base_classname = obj.__name__
- if has_base:
- filename = inspect.getfile(class_value)
- # NOTE(jlvillal): The very last item 'mro[-1]' is always going
- # to be 'object'. That is why we are checking 'mro[-2]'.
- if mro[-2].__module__ != "gitlab.base":
- failed_messages.append(
- (
- f"class definition for {class_name!r} in file {filename!r} "
- f"must have {base_classname!r} as the last class in the "
- f"class definition"
- )
- )
- failed_msg = "\n".join(failed_messages)
- assert not failed_messages, failed_msg
diff --git a/tests/unit/objects/test_packages.py b/tests/unit/objects/test_packages.py
deleted file mode 100644
index 687054f..0000000
--- a/tests/unit/objects/test_packages.py
+++ /dev/null
@@ -1,252 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/packages.html
-"""
-import re
-from urllib.parse import quote_plus
-
-import pytest
-import responses
-
-from gitlab.v4.objects import (
- GenericPackage,
- GroupPackage,
- ProjectPackage,
- ProjectPackageFile,
-)
-
-package_content = {
- "id": 1,
- "name": "com/mycompany/my-app",
- "version": "1.0-SNAPSHOT",
- "package_type": "maven",
- "_links": {
- "web_path": "/namespace1/project1/-/packages/1",
- "delete_api_path": "/namespace1/project1/-/packages/1",
- },
- "created_at": "2019-11-27T03:37:38.711Z",
- "pipeline": {
- "id": 123,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
- "user": {
- "name": "Administrator",
- "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- },
- },
- "versions": [
- {
- "id": 2,
- "version": "2.0-SNAPSHOT",
- "created_at": "2020-04-28T04:42:11.573Z",
- "pipeline": {
- "id": 234,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/58",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
- "user": {
- "name": "Administrator",
- "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- },
- },
- }
- ],
-}
-
-package_file_content = [
- {
- "id": 25,
- "package_id": 1,
- "created_at": "2018-11-07T15:25:52.199Z",
- "file_name": "my-app-1.5-20181107.152550-1.jar",
- "size": 2421,
- "file_md5": "58e6a45a629910c6ff99145a688971ac",
- "file_sha1": "ebd193463d3915d7e22219f52740056dfd26cbfe",
- "pipelines": [
- {
- "id": 123,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
- "user": {
- "name": "Administrator",
- "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- },
- }
- ],
- },
- {
- "id": 26,
- "package_id": 1,
- "created_at": "2018-11-07T15:25:56.776Z",
- "file_name": "my-app-1.5-20181107.152550-1.pom",
- "size": 1122,
- "file_md5": "d90f11d851e17c5513586b4a7e98f1b2",
- "file_sha1": "9608d068fe88aff85781811a42f32d97feb440b5",
- },
- {
- "id": 27,
- "package_id": 1,
- "created_at": "2018-11-07T15:26:00.556Z",
- "file_name": "maven-metadata.xml",
- "size": 767,
- "file_md5": "6dfd0cce1203145a927fef5e3a1c650c",
- "file_sha1": "d25932de56052d320a8ac156f745ece73f6a8cd2",
- },
-]
-
-package_name = "hello-world"
-package_version = "v1.0.0"
-file_name = "hello.tar.gz"
-file_content = "package content"
-package_url = "http://localhost/api/v4/projects/1/packages/generic/{}/{}/{}".format(
- # https://datatracker.ietf.org/doc/html/rfc3986.html#section-2.3 :(
- quote_plus(package_name).replace(".", "%2E"),
- quote_plus(package_version).replace(".", "%2E"),
- quote_plus(file_name).replace(".", "%2E"),
-)
-
-
-@pytest.fixture
-def resp_list_packages():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r"http://localhost/api/v4/(groups|projects)/1/packages"),
- json=[package_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_package():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/packages/1",
- json=package_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_delete_package(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url="http://localhost/api/v4/projects/1/packages/1",
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_list_package_files():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(
- r"http://localhost/api/v4/projects/1/packages/1/package_files"
- ),
- json=package_file_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_upload_generic_package(created_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.PUT,
- url=package_url,
- json=created_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_download_generic_package(created_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=package_url,
- body=file_content,
- content_type="application/octet-stream",
- status=200,
- )
- yield rsps
-
-
-def test_list_project_packages(project, resp_list_packages):
- packages = project.packages.list()
- assert isinstance(packages, list)
- assert isinstance(packages[0], ProjectPackage)
- assert packages[0].version == "1.0-SNAPSHOT"
-
-
-def test_list_group_packages(group, resp_list_packages):
- packages = group.packages.list()
- assert isinstance(packages, list)
- assert isinstance(packages[0], GroupPackage)
- assert packages[0].version == "1.0-SNAPSHOT"
-
-
-def test_get_project_package(project, resp_get_package):
- package = project.packages.get(1)
- assert isinstance(package, ProjectPackage)
- assert package.version == "1.0-SNAPSHOT"
-
-
-def test_delete_project_package(project, resp_delete_package):
- package = project.packages.get(1, lazy=True)
- package.delete()
-
-
-def test_list_project_package_files(project, resp_list_package_files):
- package = project.packages.get(1, lazy=True)
- package_files = package.package_files.list()
- assert isinstance(package_files, list)
- assert isinstance(package_files[0], ProjectPackageFile)
- assert package_files[0].id == 25
-
-
-def test_upload_generic_package(tmp_path, project, resp_upload_generic_package):
- path = tmp_path / file_name
- path.write_text(file_content)
- package = project.generic_packages.upload(
- package_name=package_name,
- package_version=package_version,
- file_name=file_name,
- path=path,
- )
-
- assert isinstance(package, GenericPackage)
-
-
-def test_download_generic_package(project, resp_download_generic_package):
- package = project.generic_packages.download(
- package_name=package_name,
- package_version=package_version,
- file_name=file_name,
- )
-
- assert isinstance(package, bytes)
diff --git a/tests/unit/objects/test_personal_access_tokens.py b/tests/unit/objects/test_personal_access_tokens.py
deleted file mode 100644
index 065b5c8..0000000
--- a/tests/unit/objects/test_personal_access_tokens.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ee/api/personal_access_tokens.html
-https://docs.gitlab.com/ee/api/users.html#create-a-personal-access-token
-"""
-
-import pytest
-import responses
-
-user_id = 1
-token_id = 1
-token_name = "Test Token"
-
-token_url = "http://localhost/api/v4/personal_access_tokens"
-single_token_url = f"{token_url}/{token_id}"
-user_token_url = f"http://localhost/api/v4/users/{user_id}/personal_access_tokens"
-
-content = {
- "id": token_id,
- "name": token_name,
- "revoked": False,
- "created_at": "2020-07-23T14:31:47.729Z",
- "scopes": ["api"],
- "active": True,
- "user_id": user_id,
- "expires_at": None,
-}
-
-
-@pytest.fixture
-def resp_create_user_personal_access_token():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url=user_token_url,
- json=content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_personal_access_token(no_content):
- with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
- rsps.add(
- method=responses.GET,
- url=token_url,
- json=[content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.DELETE,
- url=single_token_url,
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-def test_create_personal_access_token(gl, resp_create_user_personal_access_token):
- user = gl.users.get(1, lazy=True)
- access_token = user.personal_access_tokens.create(
- {"name": token_name, "scopes": "api"}
- )
- assert access_token.revoked is False
- assert access_token.name == token_name
-
-
-def test_list_personal_access_tokens(gl, resp_personal_access_token):
- access_tokens = gl.personal_access_tokens.list()
- assert len(access_tokens) == 1
- assert access_tokens[0].revoked is False
- assert access_tokens[0].name == token_name
-
-
-def test_list_personal_access_tokens_filter(gl, resp_personal_access_token):
- access_tokens = gl.personal_access_tokens.list(user_id=user_id)
- assert len(access_tokens) == 1
- assert access_tokens[0].revoked is False
- assert access_tokens[0].user_id == user_id
-
-
-def test_revoke_personal_access_token(gl, resp_personal_access_token):
- access_token = gl.personal_access_tokens.list(user_id=user_id)[0]
- access_token.delete()
- assert resp_personal_access_token.assert_call_count(single_token_url, 1)
-
-
-def test_revoke_personal_access_token_by_id(gl, resp_personal_access_token):
- gl.personal_access_tokens.delete(token_id)
- assert resp_personal_access_token.assert_call_count(single_token_url, 1)
diff --git a/tests/unit/objects/test_pipeline_schedules.py b/tests/unit/objects/test_pipeline_schedules.py
deleted file mode 100644
index c5dcc76..0000000
--- a/tests/unit/objects/test_pipeline_schedules.py
+++ /dev/null
@@ -1,62 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/pipeline_schedules.html
-"""
-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",
- },
- }
-
- 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(
- {"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/tests/unit/objects/test_pipelines.py b/tests/unit/objects/test_pipelines.py
deleted file mode 100644
index c0b87f2..0000000
--- a/tests/unit/objects/test_pipelines.py
+++ /dev/null
@@ -1,146 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/pipelines.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectPipeline, ProjectPipelineTestReport
-
-pipeline_content = {
- "id": 46,
- "project_id": 1,
- "status": "pending",
- "ref": "master",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "tag": False,
- "yaml_errors": None,
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://localhost:3000/root",
- },
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
- "started_at": None,
- "finished_at": "2016-08-11T11:32:35.145Z",
- "committed_at": None,
- "duration": None,
- "queued_duration": 0.010,
- "coverage": None,
- "web_url": "https://example.com/foo/bar/pipelines/46",
-}
-
-
-test_report_content = {
- "total_time": 5,
- "total_count": 1,
- "success_count": 1,
- "failed_count": 0,
- "skipped_count": 0,
- "error_count": 0,
- "test_suites": [
- {
- "name": "Secure",
- "total_time": 5,
- "total_count": 1,
- "success_count": 1,
- "failed_count": 0,
- "skipped_count": 0,
- "error_count": 0,
- "test_cases": [
- {
- "status": "success",
- "name": "Security Reports can create an auto-remediation MR",
- "classname": "vulnerability_management_spec",
- "execution_time": 5,
- "system_output": None,
- "stack_trace": None,
- }
- ],
- }
- ],
-}
-
-
-@pytest.fixture
-def resp_get_pipeline():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/pipelines/1",
- json=pipeline_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_cancel_pipeline():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/pipelines/1/cancel",
- json=pipeline_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_retry_pipeline():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/pipelines/1/retry",
- json=pipeline_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_pipeline_test_report():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/pipelines/1/test_report",
- json=test_report_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_get_project_pipeline(project, resp_get_pipeline):
- pipeline = project.pipelines.get(1)
- assert isinstance(pipeline, ProjectPipeline)
- assert pipeline.ref == "master"
-
-
-def test_cancel_project_pipeline(project, resp_cancel_pipeline):
- pipeline = project.pipelines.get(1, lazy=True)
-
- output = pipeline.cancel()
- assert output["ref"] == "master"
-
-
-def test_retry_project_pipeline(project, resp_retry_pipeline):
- pipeline = project.pipelines.get(1, lazy=True)
-
- output = pipeline.retry()
- assert output["ref"] == "master"
-
-
-def test_get_project_pipeline_test_report(project, resp_get_pipeline_test_report):
- pipeline = project.pipelines.get(1, lazy=True)
- test_report = pipeline.test_report.get()
- assert isinstance(test_report, ProjectPipelineTestReport)
- assert test_report.total_time == 5
- assert test_report.test_suites[0]["name"] == "Secure"
diff --git a/tests/unit/objects/test_project_access_tokens.py b/tests/unit/objects/test_project_access_tokens.py
deleted file mode 100644
index 4d4788d..0000000
--- a/tests/unit/objects/test_project_access_tokens.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/resource_access_tokens.html
-"""
-
-import pytest
-import responses
-
-
-@pytest.fixture
-def resp_list_project_access_token():
- content = [
- {
- "user_id": 141,
- "scopes": ["api"],
- "name": "token",
- "expires_at": "2021-01-31",
- "id": 42,
- "active": True,
- "created_at": "2021-01-20T22:11:48.151Z",
- "revoked": False,
- }
- ]
-
- with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/access_tokens",
- json=content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_create_project_access_token():
- content = {
- "user_id": 141,
- "scopes": ["api"],
- "name": "token",
- "expires_at": "2021-01-31",
- "id": 42,
- "active": True,
- "created_at": "2021-01-20T22:11:48.151Z",
- "revoked": False,
- }
-
- with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/access_tokens",
- json=content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_revoke_project_access_token():
- content = [
- {
- "user_id": 141,
- "scopes": ["api"],
- "name": "token",
- "expires_at": "2021-01-31",
- "id": 42,
- "active": True,
- "created_at": "2021-01-20T22:11:48.151Z",
- "revoked": False,
- }
- ]
-
- with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
- rsps.add(
- method=responses.DELETE,
- url="http://localhost/api/v4/projects/1/access_tokens/42",
- json=content,
- content_type="application/json",
- status=204,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/access_tokens",
- json=content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_project_access_tokens(gl, resp_list_project_access_token):
- access_tokens = gl.projects.get(1, lazy=True).access_tokens.list()
- assert len(access_tokens) == 1
- assert access_tokens[0].revoked is False
- assert access_tokens[0].name == "token"
-
-
-def test_create_project_access_token(gl, resp_create_project_access_token):
- access_tokens = gl.projects.get(1, lazy=True).access_tokens.create(
- {"name": "test", "scopes": ["api"]}
- )
- assert access_tokens.revoked is False
- assert access_tokens.user_id == 141
- assert access_tokens.expires_at == "2021-01-31"
-
-
-def test_revoke_project_access_token(
- gl, resp_list_project_access_token, resp_revoke_project_access_token
-):
- gl.projects.get(1, lazy=True).access_tokens.delete(42)
- access_token = gl.projects.get(1, lazy=True).access_tokens.list()[0]
- access_token.delete()
diff --git a/tests/unit/objects/test_project_import_export.py b/tests/unit/objects/test_project_import_export.py
deleted file mode 100644
index 78e51b1..0000000
--- a/tests/unit/objects/test_project_import_export.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""
-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",
- }
-
- 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",
- }
-
- 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"
-
-
-def test_refresh_project_import_status(project, resp_import_status):
- project_import = project.imports.get()
- project_import.refresh()
- assert project_import.import_status == "finished"
-
-
-def test_import_github(gl, resp_import_github):
- 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)
-
-
-def test_create_project_export(project, resp_export):
- export = project.exports.create()
- assert export.message == "202 Accepted"
-
-
-def test_refresh_project_export_status(project, resp_export):
- export = project.exports.create()
- export.refresh()
- assert export.export_status == "finished"
-
-
-def test_download_project_export(project, resp_export, binary_content):
- export = project.exports.create()
- download = export.download()
- assert isinstance(download, bytes)
- assert download == binary_content
diff --git a/tests/unit/objects/test_project_merge_request_approvals.py b/tests/unit/objects/test_project_merge_request_approvals.py
deleted file mode 100644
index 16d58bd..0000000
--- a/tests/unit/objects/test_project_merge_request_approvals.py
+++ /dev/null
@@ -1,317 +0,0 @@
-"""
-Gitlab API: https://docs.gitlab.com/ee/api/merge_request_approvals.html
-"""
-
-import copy
-
-import pytest
-import responses
-
-import gitlab
-
-approval_rule_id = 1
-approval_rule_name = "security"
-approvals_required = 3
-user_ids = [5, 50]
-group_ids = [5]
-
-new_approval_rule_name = "new approval rule"
-new_approval_rule_user_ids = user_ids
-new_approval_rule_approvals_required = 2
-
-updated_approval_rule_user_ids = [5]
-updated_approval_rule_approvals_required = 1
-
-
-@pytest.fixture
-def resp_snippet():
- merge_request_content = [
- {
- "id": 1,
- "iid": 1,
- "project_id": 1,
- "title": "test1",
- "description": "fixed login page css paddings",
- "state": "merged",
- "merged_by": {
- "id": 87854,
- "name": "Douwe Maan",
- "username": "DouweM",
- "state": "active",
- "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
- "web_url": "https://gitlab.com/DouweM",
- },
- "merged_at": "2018-09-07T11:16:17.520Z",
- "closed_by": None,
- "closed_at": None,
- "created_at": "2017-04-29T08:46:00Z",
- "updated_at": "2017-04-29T08:46:00Z",
- "target_branch": "master",
- "source_branch": "test1",
- "upvotes": 0,
- "downvotes": 0,
- "author": {
- "id": 1,
- "name": "Administrator",
- "username": "admin",
- "state": "active",
- "avatar_url": None,
- "web_url": "https://gitlab.example.com/admin",
- },
- "assignee": {
- "id": 1,
- "name": "Administrator",
- "username": "admin",
- "state": "active",
- "avatar_url": None,
- "web_url": "https://gitlab.example.com/admin",
- },
- "assignees": [
- {
- "name": "Miss Monserrate Beier",
- "username": "axel.block",
- "id": 12,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
- "web_url": "https://gitlab.example.com/axel.block",
- }
- ],
- "source_project_id": 2,
- "target_project_id": 3,
- "labels": ["Community contribution", "Manage"],
- "work_in_progress": None,
- "milestone": {
- "id": 5,
- "iid": 1,
- "project_id": 3,
- "title": "v2.0",
- "description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.",
- "state": "closed",
- "created_at": "2015-02-02T19:49:26.013Z",
- "updated_at": "2015-02-02T19:49:26.013Z",
- "due_date": "2018-09-22",
- "start_date": "2018-08-08",
- "web_url": "https://gitlab.example.com/my-group/my-project/milestones/1",
- },
- "merge_when_pipeline_succeeds": None,
- "merge_status": "can_be_merged",
- "sha": "8888888888888888888888888888888888888888",
- "merge_commit_sha": None,
- "squash_commit_sha": None,
- "user_notes_count": 1,
- "discussion_locked": None,
- "should_remove_source_branch": True,
- "force_remove_source_branch": False,
- "allow_collaboration": False,
- "allow_maintainer_to_push": False,
- "web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
- "references": {
- "short": "!1",
- "relative": "my-group/my-project!1",
- "full": "my-group/my-project!1",
- },
- "time_stats": {
- "time_estimate": 0,
- "total_time_spent": 0,
- "human_time_estimate": None,
- "human_total_time_spent": None,
- },
- "squash": False,
- "task_completion_status": {"count": 0, "completed_count": 0},
- }
- ]
- mr_ars_content = [
- {
- "id": approval_rule_id,
- "name": approval_rule_name,
- "rule_type": "regular",
- "eligible_approvers": [
- {
- "id": user_ids[0],
- "name": "John Doe",
- "username": "jdoe",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
- "web_url": "http://localhost/jdoe",
- },
- {
- "id": user_ids[1],
- "name": "Group Member 1",
- "username": "group_member_1",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
- "web_url": "http://localhost/group_member_1",
- },
- ],
- "approvals_required": approvals_required,
- "source_rule": None,
- "users": [
- {
- "id": 5,
- "name": "John Doe",
- "username": "jdoe",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/0?s=80&d=identicon",
- "web_url": "http://localhost/jdoe",
- }
- ],
- "groups": [
- {
- "id": 5,
- "name": "group1",
- "path": "group1",
- "description": "",
- "visibility": "public",
- "lfs_enabled": False,
- "avatar_url": None,
- "web_url": "http://localhost/groups/group1",
- "request_access_enabled": False,
- "full_name": "group1",
- "full_path": "group1",
- "parent_id": None,
- "ldap_cn": None,
- "ldap_access": None,
- }
- ],
- "contains_hidden_groups": False,
- "overridden": False,
- }
- ]
-
- with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests",
- json=merge_request_content,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1",
- json=merge_request_content[0],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules",
- json=mr_ars_content,
- content_type="application/json",
- status=200,
- )
-
- new_mr_ars_content = dict(mr_ars_content[0])
- new_mr_ars_content["name"] = new_approval_rule_name
- new_mr_ars_content["approvals_required"] = new_approval_rule_approvals_required
-
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules",
- json=new_mr_ars_content,
- content_type="application/json",
- status=200,
- )
-
- updated_mr_ars_content = copy.deepcopy(mr_ars_content[0])
- updated_mr_ars_content["eligible_approvers"] = [
- mr_ars_content[0]["eligible_approvers"][0]
- ]
-
- updated_mr_ars_content[
- "approvals_required"
- ] = updated_approval_rule_approvals_required
-
- rsps.add(
- method=responses.PUT,
- url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules/1",
- json=updated_mr_ars_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_project_approval_manager_update_uses_post(project, resp_snippet):
- """Ensure the
- gitlab.v4.objects.merge_request_approvals.ProjectApprovalManager object has
- _update_uses_post set to True"""
- approvals = project.approvals
- assert isinstance(
- approvals, gitlab.v4.objects.merge_request_approvals.ProjectApprovalManager
- )
- assert approvals._update_uses_post is True
-
-
-def test_list_merge_request_approval_rules(project, resp_snippet):
- approval_rules = project.mergerequests.get(1).approval_rules.list()
- assert len(approval_rules) == 1
- assert approval_rules[0].name == approval_rule_name
- assert approval_rules[0].id == approval_rule_id
-
-
-def test_update_merge_request_approvals_set_approvers(project, resp_snippet):
- approvals = project.mergerequests.get(1).approvals
- assert isinstance(
- approvals,
- gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalManager,
- )
- assert approvals._update_uses_post is True
- response = approvals.set_approvers(
- updated_approval_rule_approvals_required,
- approver_ids=updated_approval_rule_user_ids,
- approver_group_ids=group_ids,
- approval_rule_name=approval_rule_name,
- )
-
- assert response.approvals_required == updated_approval_rule_approvals_required
- assert len(response.eligible_approvers) == len(updated_approval_rule_user_ids)
- assert response.eligible_approvers[0]["id"] == updated_approval_rule_user_ids[0]
- assert response.name == approval_rule_name
-
-
-def test_create_merge_request_approvals_set_approvers(project, resp_snippet):
- approvals = project.mergerequests.get(1).approvals
- assert isinstance(
- approvals,
- gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalManager,
- )
- assert approvals._update_uses_post is True
- response = approvals.set_approvers(
- new_approval_rule_approvals_required,
- approver_ids=new_approval_rule_user_ids,
- approver_group_ids=group_ids,
- approval_rule_name=new_approval_rule_name,
- )
- assert response.approvals_required == new_approval_rule_approvals_required
- assert len(response.eligible_approvers) == len(new_approval_rule_user_ids)
- assert response.eligible_approvers[0]["id"] == new_approval_rule_user_ids[0]
- assert response.name == new_approval_rule_name
-
-
-def test_create_merge_request_approval_rule(project, resp_snippet):
- approval_rules = project.mergerequests.get(1).approval_rules
- data = {
- "name": new_approval_rule_name,
- "approvals_required": new_approval_rule_approvals_required,
- "rule_type": "regular",
- "user_ids": new_approval_rule_user_ids,
- "group_ids": group_ids,
- }
- response = approval_rules.create(data)
- assert response.approvals_required == new_approval_rule_approvals_required
- assert len(response.eligible_approvers) == len(new_approval_rule_user_ids)
- assert response.eligible_approvers[0]["id"] == new_approval_rule_user_ids[0]
- assert response.name == new_approval_rule_name
-
-
-def test_update_merge_request_approval_rule(project, resp_snippet):
- approval_rules = project.mergerequests.get(1).approval_rules
- ar_1 = approval_rules.list()[0]
- ar_1.user_ids = updated_approval_rule_user_ids
- ar_1.approvals_required = updated_approval_rule_approvals_required
- ar_1.save()
-
- assert ar_1.approvals_required == updated_approval_rule_approvals_required
- assert len(ar_1.eligible_approvers) == len(updated_approval_rule_user_ids)
- assert ar_1.eligible_approvers[0]["id"] == updated_approval_rule_user_ids[0]
diff --git a/tests/unit/objects/test_project_statistics.py b/tests/unit/objects/test_project_statistics.py
deleted file mode 100644
index 50d9a6d..0000000
--- a/tests/unit/objects/test_project_statistics.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/project_statistics.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectAdditionalStatistics
-
-
-@pytest.fixture
-def resp_project_statistics():
- content = {"fetches": {"total": 50, "days": [{"count": 10, "date": "2018-01-10"}]}}
-
- 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
-
-
-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/tests/unit/objects/test_projects.py b/tests/unit/objects/test_projects.py
deleted file mode 100644
index 039d5ec..0000000
--- a/tests/unit/objects/test_projects.py
+++ /dev/null
@@ -1,237 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/projects.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import Project
-
-project_content = {"name": "name", "id": 1}
-import_content = {
- "id": 1,
- "name": "project",
- "import_status": "scheduled",
-}
-
-
-@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
-
-
-@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
-
-
-@pytest.fixture
-def resp_import_bitbucket_server():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/import/bitbucket_server",
- json=import_content,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-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
-
-
-def test_list_projects(gl, resp_list_projects):
- projects = gl.projects.list()
- assert isinstance(projects[0], Project)
- assert projects[0].name == "name"
-
-
-def test_import_bitbucket_server(gl, resp_import_bitbucket_server):
- res = gl.projects.import_bitbucket_server(
- bitbucket_server_project="project",
- bitbucket_server_repo="repo",
- bitbucket_server_url="url",
- bitbucket_server_username="username",
- personal_access_token="token",
- new_name="new_name",
- target_namespace="namespace",
- )
- assert res["id"] == 1
- assert res["name"] == "project"
- assert res["import_status"] == "scheduled"
-
-
-@pytest.mark.skip(reason="missing test")
-def test_list_user_projects(gl):
- pass
-
-
-@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_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
-
-
-@pytest.mark.skip(reason="missing test")
-def test_project_snapshot(gl):
- pass
-
-
-@pytest.mark.skip(reason="missing test")
-def test_import_github(gl):
- pass
diff --git a/tests/unit/objects/test_releases.py b/tests/unit/objects/test_releases.py
deleted file mode 100644
index 58ab5d0..0000000
--- a/tests/unit/objects/test_releases.py
+++ /dev/null
@@ -1,170 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ee/api/releases/index.html
-https://docs.gitlab.com/ee/api/releases/links.html
-"""
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectReleaseLink
-
-tag_name = "v1.0.0"
-encoded_tag_name = "v1%2E0%2E0"
-release_name = "demo-release"
-release_description = "my-rel-desc"
-released_at = "2019-03-15T08:00:00Z"
-link_name = "hello-world"
-link_url = "https://gitlab.example.com/group/hello/-/jobs/688/artifacts/raw/bin/hello-darwin-amd64"
-direct_url = f"https://gitlab.example.com/group/hello/-/releases/{encoded_tag_name}/downloads/hello-world"
-new_link_type = "package"
-link_content = {
- "id": 2,
- "name": link_name,
- "url": link_url,
- "direct_asset_url": direct_url,
- "external": False,
- "link_type": "other",
-}
-
-release_content = {
- "id": 3,
- "tag_name": tag_name,
- "name": release_name,
- "description": release_description,
- "milestones": [],
- "released_at": released_at,
-}
-
-release_url = re.compile(
- rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}"
-)
-links_url = re.compile(
- rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}/assets/links"
-)
-link_id_url = re.compile(
- rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}/assets/links/1"
-)
-
-
-@pytest.fixture
-def resp_list_links():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=links_url,
- json=[link_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_link():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=link_id_url,
- json=link_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_create_link():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url=links_url,
- json=link_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_update_link():
- updated_content = dict(link_content)
- updated_content["link_type"] = new_link_type
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.PUT,
- url=link_id_url,
- json=updated_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_delete_link(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url=link_id_url,
- json=link_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_update_release():
- updated_content = dict(release_content)
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.PUT,
- url=release_url,
- json=updated_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_release_links(release, resp_list_links):
- links = release.links.list()
- assert isinstance(links, list)
- assert isinstance(links[0], ProjectReleaseLink)
- assert links[0].url == link_url
-
-
-def test_get_release_link(release, resp_get_link):
- link = release.links.get(1)
- assert isinstance(link, ProjectReleaseLink)
- assert link.url == link_url
-
-
-def test_create_release_link(release, resp_create_link):
- link = release.links.create({"url": link_url, "name": link_name})
- assert isinstance(link, ProjectReleaseLink)
- assert link.url == link_url
-
-
-def test_update_release_link(release, resp_update_link):
- link = release.links.get(1, lazy=True)
- link.link_type = new_link_type
- link.save()
- assert link.link_type == new_link_type
-
-
-def test_delete_release_link(release, resp_delete_link):
- link = release.links.get(1, lazy=True)
- link.delete()
-
-
-def test_update_release(release, resp_update_release):
- release.name = release_name
- release.description = release_description
- release.save()
- assert release.name == release_name
- assert release.description == release_description
diff --git a/tests/unit/objects/test_remote_mirrors.py b/tests/unit/objects/test_remote_mirrors.py
deleted file mode 100644
index 1ac35a2..0000000
--- a/tests/unit/objects/test_remote_mirrors.py
+++ /dev/null
@@ -1,72 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/remote_mirrors.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectRemoteMirror
-
-
-@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": "none",
- "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,
- )
-
- 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
-
-
-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
-
-
-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"
-
-
-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()
- assert mirror.update_status == "finished"
- assert mirror.only_protected_branches
diff --git a/tests/unit/objects/test_repositories.py b/tests/unit/objects/test_repositories.py
deleted file mode 100644
index 7c4d77d..0000000
--- a/tests/unit/objects/test_repositories.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ee/api/repositories.html
-https://docs.gitlab.com/ee/api/repository_files.html
-"""
-from urllib.parse import quote
-
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectFile
-
-file_path = "app/models/key.rb"
-ref = "main"
-
-
-@pytest.fixture
-def resp_get_repository_file():
- file_response = {
- "file_name": "key.rb",
- "file_path": file_path,
- "size": 1476,
- "encoding": "base64",
- "content": "IyA9PSBTY2hlbWEgSW5mb3...",
- "content_sha256": "4c294617b60715c1d218e61164a3abd4808a4284cbc30e6728a01ad9aada4481",
- "ref": ref,
- "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
- "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
- "last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- }
-
- # requests also encodes `.`
- encoded_path = quote(file_path, safe="").replace(".", "%2E")
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=f"http://localhost/api/v4/projects/1/repository/files/{encoded_path}",
- json=file_response,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_get_repository_file(project, resp_get_repository_file):
- file = project.files.get(file_path, ref=ref)
- assert isinstance(file, ProjectFile)
- assert file.file_path == file_path
diff --git a/tests/unit/objects/test_resource_label_events.py b/tests/unit/objects/test_resource_label_events.py
deleted file mode 100644
index deea8a0..0000000
--- a/tests/unit/objects/test_resource_label_events.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/resource_label_events.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import (
- GroupEpicResourceLabelEvent,
- ProjectIssueResourceLabelEvent,
- ProjectMergeRequestResourceLabelEvent,
-)
-
-
-@pytest.fixture()
-def resp_group_epic_request_label_events():
- epic_content = {"id": 1}
- events_content = {"id": 1, "resource_type": "Epic"}
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/groups/1/epics",
- json=[epic_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/groups/1/epics/1/resource_label_events",
- json=[events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_merge_request_label_events():
- mr_content = {"iid": 1}
- events_content = {"id": 1, "resource_type": "MergeRequest"}
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests",
- json=[mr_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/resource_label_events",
- json=[events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_project_issue_label_events():
- issue_content = {"iid": 1}
- events_content = {"id": 1, "resource_type": "Issue"}
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues",
- json=[issue_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues/1/resource_label_events",
- json=[events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_project_issue_label_events(project, resp_project_issue_label_events):
- issue = project.issues.list()[0]
- label_events = issue.resourcelabelevents.list()
- assert isinstance(label_events, list)
- label_event = label_events[0]
- assert isinstance(label_event, ProjectIssueResourceLabelEvent)
- assert label_event.resource_type == "Issue"
-
-
-def test_merge_request_label_events(project, resp_merge_request_label_events):
- mr = project.mergerequests.list()[0]
- label_events = mr.resourcelabelevents.list()
- assert isinstance(label_events, list)
- label_event = label_events[0]
- assert isinstance(label_event, ProjectMergeRequestResourceLabelEvent)
- assert label_event.resource_type == "MergeRequest"
-
-
-def test_group_epic_request_label_events(group, resp_group_epic_request_label_events):
- epic = group.epics.list()[0]
- label_events = epic.resourcelabelevents.list()
- assert isinstance(label_events, list)
- label_event = label_events[0]
- assert isinstance(label_event, GroupEpicResourceLabelEvent)
- assert label_event.resource_type == "Epic"
diff --git a/tests/unit/objects/test_resource_milestone_events.py b/tests/unit/objects/test_resource_milestone_events.py
deleted file mode 100644
index 99faeaa..0000000
--- a/tests/unit/objects/test_resource_milestone_events.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/resource_milestone_events.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import (
- ProjectIssueResourceMilestoneEvent,
- ProjectMergeRequestResourceMilestoneEvent,
-)
-
-
-@pytest.fixture()
-def resp_merge_request_milestone_events():
- mr_content = {"iid": 1}
- events_content = {"id": 1, "resource_type": "MergeRequest"}
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests",
- json=[mr_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/resource_milestone_events",
- json=[events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_project_issue_milestone_events():
- issue_content = {"iid": 1}
- events_content = {"id": 1, "resource_type": "Issue"}
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues",
- json=[issue_content],
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues/1/resource_milestone_events",
- json=[events_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_project_issue_milestone_events(project, resp_project_issue_milestone_events):
- issue = project.issues.list()[0]
- milestone_events = issue.resourcemilestoneevents.list()
- assert isinstance(milestone_events, list)
- milestone_event = milestone_events[0]
- assert isinstance(milestone_event, ProjectIssueResourceMilestoneEvent)
- assert milestone_event.resource_type == "Issue"
-
-
-def test_merge_request_milestone_events(project, resp_merge_request_milestone_events):
- mr = project.mergerequests.list()[0]
- milestone_events = mr.resourcemilestoneevents.list()
- assert isinstance(milestone_events, list)
- milestone_event = milestone_events[0]
- assert isinstance(milestone_event, ProjectMergeRequestResourceMilestoneEvent)
- assert milestone_event.resource_type == "MergeRequest"
diff --git a/tests/unit/objects/test_resource_state_events.py b/tests/unit/objects/test_resource_state_events.py
deleted file mode 100644
index bf18193..0000000
--- a/tests/unit/objects/test_resource_state_events.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ee/api/resource_state_events.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import (
- ProjectIssueResourceStateEvent,
- ProjectMergeRequestResourceStateEvent,
-)
-
-issue_event_content = {"id": 1, "resource_type": "Issue"}
-mr_event_content = {"id": 1, "resource_type": "MergeRequest"}
-
-
-@pytest.fixture()
-def resp_list_project_issue_state_events():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues/1/resource_state_events",
- json=[issue_event_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_get_project_issue_state_event():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/issues/1/resource_state_events/1",
- json=issue_event_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_list_merge_request_state_events():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/resource_state_events",
- json=[mr_event_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture()
-def resp_get_merge_request_state_event():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/projects/1/merge_requests/1/resource_state_events/1",
- json=mr_event_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-def test_list_project_issue_state_events(
- project_issue, resp_list_project_issue_state_events
-):
- state_events = project_issue.resourcestateevents.list()
- assert isinstance(state_events, list)
-
- state_event = state_events[0]
- assert isinstance(state_event, ProjectIssueResourceStateEvent)
- assert state_event.resource_type == "Issue"
-
-
-def test_get_project_issue_state_event(
- project_issue, resp_get_project_issue_state_event
-):
- state_event = project_issue.resourcestateevents.get(1)
- assert isinstance(state_event, ProjectIssueResourceStateEvent)
- assert state_event.resource_type == "Issue"
-
-
-def test_list_merge_request_state_events(
- project_merge_request, resp_list_merge_request_state_events
-):
- state_events = project_merge_request.resourcestateevents.list()
- assert isinstance(state_events, list)
-
- state_event = state_events[0]
- assert isinstance(state_event, ProjectMergeRequestResourceStateEvent)
- assert state_event.resource_type == "MergeRequest"
-
-
-def test_get_merge_request_state_event(
- project_merge_request, resp_get_merge_request_state_event
-):
- state_event = project_merge_request.resourcestateevents.get(1)
- assert isinstance(state_event, ProjectMergeRequestResourceStateEvent)
- assert state_event.resource_type == "MergeRequest"
diff --git a/tests/unit/objects/test_runners.py b/tests/unit/objects/test_runners.py
deleted file mode 100644
index 686eec2..0000000
--- a/tests/unit/objects/test_runners.py
+++ /dev/null
@@ -1,282 +0,0 @@
-import re
-
-import pytest
-import responses
-
-import gitlab
-
-runner_detail = {
- "active": True,
- "architecture": "amd64",
- "description": "test-1-20150125",
- "id": 6,
- "ip_address": "127.0.0.1",
- "is_shared": False,
- "contacted_at": "2016-01-25T16:39:48.066Z",
- "name": "test-runner",
- "online": True,
- "status": "online",
- "platform": "linux",
- "projects": [
- {
- "id": 1,
- "name": "GitLab Community Edition",
- "name_with_namespace": "GitLab.org / GitLab Community Edition",
- "path": "gitlab-foss",
- "path_with_namespace": "gitlab-org/gitlab-foss",
- }
- ],
- "revision": "5nj35",
- "tag_list": ["ruby", "mysql"],
- "version": "v13.0.0",
- "access_level": "ref_protected",
- "maximum_timeout": 3600,
-}
-
-runner_shortinfo = {
- "active": True,
- "description": "test-1-20150125",
- "id": 6,
- "is_shared": False,
- "ip_address": "127.0.0.1",
- "name": "test-name",
- "online": True,
- "status": "online",
-}
-
-runner_jobs = [
- {
- "id": 6,
- "ip_address": "127.0.0.1",
- "status": "running",
- "stage": "test",
- "name": "test",
- "ref": "master",
- "tag": False,
- "coverage": "99%",
- "created_at": "2017-11-16T08:50:29.000Z",
- "started_at": "2017-11-16T08:51:29.000Z",
- "finished_at": "2017-11-16T08:53:29.000Z",
- "duration": 120,
- "user": {
- "id": 1,
- "name": "John Doe2",
- "username": "user2",
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon",
- "web_url": "http://localhost/user2",
- "created_at": "2017-11-16T18:38:46.000Z",
- "bio": None,
- "location": None,
- "public_email": "",
- "skype": "",
- "linkedin": "",
- "twitter": "",
- "website_url": "",
- "organization": None,
- },
- }
-]
-
-
-@pytest.fixture
-def resp_get_runners_jobs():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/runners/6/jobs",
- json=runner_jobs,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_runners_list():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=re.compile(r".*?(/runners(/all)?|/(groups|projects)/1/runners)"),
- json=[runner_shortinfo],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_detail():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?/runners/6")
- rsps.add(
- method=responses.GET,
- url=pattern,
- json=runner_detail,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.PUT,
- url=pattern,
- json=runner_detail,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_register():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?/runners")
- rsps.add(
- method=responses.POST,
- url=pattern,
- json={"id": "6", "token": "6337ff461c94fd3fa32ba3b1ff4125"},
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_enable():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?(projects|groups)/1/runners")
- rsps.add(
- method=responses.POST,
- url=pattern,
- json=runner_shortinfo,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_delete():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?/runners/6")
- rsps.add(
- method=responses.GET,
- url=pattern,
- json=runner_detail,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.DELETE,
- url=pattern,
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_disable():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?/(groups|projects)/1/runners/6")
- rsps.add(
- method=responses.DELETE,
- url=pattern,
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_runner_verify():
- with responses.RequestsMock() as rsps:
- pattern = re.compile(r".*?/runners/verify")
- rsps.add(
- method=responses.POST,
- url=pattern,
- status=200,
- )
- yield rsps
-
-
-def test_owned_runners_list(gl: gitlab.Gitlab, resp_get_runners_list):
- runners = gl.runners.list()
- assert runners[0].active is True
- assert runners[0].id == 6
- assert runners[0].name == "test-name"
- assert len(runners) == 1
-
-
-def test_project_runners_list(gl: gitlab.Gitlab, resp_get_runners_list):
- runners = gl.projects.get(1, lazy=True).runners.list()
- assert runners[0].active is True
- assert runners[0].id == 6
- assert runners[0].name == "test-name"
- assert len(runners) == 1
-
-
-def test_group_runners_list(gl: gitlab.Gitlab, resp_get_runners_list):
- runners = gl.groups.get(1, lazy=True).runners.list()
- assert runners[0].active is True
- assert runners[0].id == 6
- assert runners[0].name == "test-name"
- assert len(runners) == 1
-
-
-def test_all_runners_list(gl: gitlab.Gitlab, resp_get_runners_list):
- runners = gl.runners.all()
- assert runners[0].active is True
- assert runners[0].id == 6
- assert runners[0].name == "test-name"
- assert len(runners) == 1
-
-
-def test_create_runner(gl: gitlab.Gitlab, resp_runner_register):
- runner = gl.runners.create({"token": "token"})
- assert runner.id == "6"
- assert runner.token == "6337ff461c94fd3fa32ba3b1ff4125"
-
-
-def test_get_update_runner(gl: gitlab.Gitlab, resp_runner_detail):
- runner = gl.runners.get(6)
- assert runner.active is True
- runner.tag_list.append("new")
- runner.save()
-
-
-def test_remove_runner(gl: gitlab.Gitlab, resp_runner_delete):
- runner = gl.runners.get(6)
- runner.delete()
- gl.runners.delete(6)
-
-
-def test_disable_project_runner(gl: gitlab.Gitlab, resp_runner_disable):
- gl.projects.get(1, lazy=True).runners.delete(6)
-
-
-def test_disable_group_runner(gl: gitlab.Gitlab, resp_runner_disable):
- gl.groups.get(1, lazy=True).runners.delete(6)
-
-
-def test_enable_project_runner(gl: gitlab.Gitlab, resp_runner_enable):
- runner = gl.projects.get(1, lazy=True).runners.create({"runner_id": 6})
- assert runner.active is True
- assert runner.id == 6
- assert runner.name == "test-name"
-
-
-def test_enable_group_runner(gl: gitlab.Gitlab, resp_runner_enable):
- runner = gl.groups.get(1, lazy=True).runners.create({"runner_id": 6})
- assert runner.active is True
- assert runner.id == 6
- assert runner.name == "test-name"
-
-
-def test_verify_runner(gl: gitlab.Gitlab, resp_runner_verify):
- gl.runners.verify("token")
-
-
-def test_runner_jobs(gl: gitlab.Gitlab, resp_get_runners_jobs):
- jobs = gl.runners.get(6, lazy=True).jobs.list()
- assert jobs[0].duration == 120
- assert jobs[0].name == "test"
- assert jobs[0].user.get("name") == "John Doe2"
- assert len(jobs) == 1
diff --git a/tests/unit/objects/test_services.py b/tests/unit/objects/test_services.py
deleted file mode 100644
index 5b2bcb8..0000000
--- a/tests/unit/objects/test_services.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/services.html
-"""
-
-import pytest
-import responses
-
-from gitlab.v4.objects import ProjectService
-
-
-@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,
- }
-
- 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)
- assert services[0].active
- assert services[0].push_events
-
-
-def test_list_available_services(project, resp_service):
- services = project.services.available()
- assert isinstance(services, list)
- assert isinstance(services[0], str)
-
-
-def test_get_service(project, resp_service):
- service = project.services.get("pipelines-email")
- assert isinstance(service, ProjectService)
- assert service.push_events is True
-
-
-def test_update_service(project, resp_service):
- service = project.services.get("pipelines-email")
- service.issues_events = False
- service.save()
- assert service.issues_events is False
diff --git a/tests/unit/objects/test_snippets.py b/tests/unit/objects/test_snippets.py
deleted file mode 100644
index 2540fc3..0000000
--- a/tests/unit/objects/test_snippets.py
+++ /dev/null
@@ -1,89 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/project_snippets.html
- https://docs.gitlab.com/ee/api/snippets.html (todo)
-"""
-
-import pytest
-import responses
-
-title = "Example Snippet Title"
-visibility = "private"
-new_title = "new-title"
-
-
-@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
-
-
-def test_get_project_snippet(project, resp_snippet):
- snippet = project.snippets.get(1)
- assert snippet.title == title
- assert snippet.visibility == visibility
-
-
-def test_create_update_project_snippets(project, resp_snippet):
- 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/tests/unit/objects/test_submodules.py b/tests/unit/objects/test_submodules.py
deleted file mode 100644
index 69c1cd7..0000000
--- a/tests/unit/objects/test_submodules.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/repository_submodules.html
-"""
-import pytest
-import responses
-
-
-@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",
- commit_sha="4c3674f66071e30b3311dac9b9ccc90502a72664",
- commit_message="Message",
- )
- assert isinstance(ret, dict)
- assert ret["message"] == "Message"
- assert ret["id"] == "ed899a2f4b50b4370feeea94676502b42383c746"
diff --git a/tests/unit/objects/test_todos.py b/tests/unit/objects/test_todos.py
deleted file mode 100644
index 058fe33..0000000
--- a/tests/unit/objects/test_todos.py
+++ /dev/null
@@ -1,62 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/todos.html
-"""
-
-import json
-import os
-
-import pytest
-import responses
-
-from gitlab.v4.objects import Todo
-
-with open(os.path.dirname(__file__) + "/../data/todo.json", "r") as json_file:
- todo_content = json_file.read()
- json_content = json.loads(todo_content)
-
-
-@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
- assert todo.target_type == "MergeRequest"
- assert todo.target["assignee"]["username"] == "root"
-
- todo.mark_as_done()
-
-
-def test_todo_mark_all_as_done(gl, resp_mark_all_as_done):
- gl.todos.mark_all_as_done()
diff --git a/tests/unit/objects/test_users.py b/tests/unit/objects/test_users.py
deleted file mode 100644
index e46a315..0000000
--- a/tests/unit/objects/test_users.py
+++ /dev/null
@@ -1,217 +0,0 @@
-"""
-GitLab API: https://docs.gitlab.com/ce/api/users.html
-"""
-import pytest
-import responses
-
-from gitlab.v4.objects import User, UserMembership, UserStatus
-
-
-@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": "<h1>Message</h1>",
- "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
-
-
-@pytest.fixture
-def resp_delete_user_identity(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url="http://localhost/api/v4/users/1/identities/test_provider",
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_follow_unfollow():
- user = {
- "id": 1,
- "username": "john_smith",
- "name": "John Smith",
- "state": "active",
- "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
- "web_url": "http://localhost:3000/john_smith",
- }
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/users/1/follow",
- json=user,
- content_type="application/json",
- status=201,
- )
- rsps.add(
- method=responses.POST,
- url="http://localhost/api/v4/users/1/unfollow",
- json=user,
- content_type="application/json",
- status=201,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_followers_following():
- content = [
- {
- "id": 2,
- "name": "Lennie Donnelly",
- "username": "evette.kilback",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/7955171a55ac4997ed81e5976287890a?s=80&d=identicon",
- "web_url": "http://127.0.0.1:3000/evette.kilback",
- },
- {
- "id": 4,
- "name": "Serena Bradtke",
- "username": "cammy",
- "state": "active",
- "avatar_url": "https://www.gravatar.com/avatar/a2daad869a7b60d3090b7b9bef4baf57?s=80&d=identicon",
- "web_url": "http://127.0.0.1:3000/cammy",
- },
- ]
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/users/1/followers",
- json=content,
- content_type="application/json",
- status=200,
- )
- rsps.add(
- method=responses.GET,
- url="http://localhost/api/v4/users/1/following",
- 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
-
-
-def test_user_memberships(user, resp_get_user_memberships):
- memberships = user.memberships.list()
- assert isinstance(memberships[0], UserMembership)
- assert memberships[0].source_type == "Project"
-
-
-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"
-
-
-def test_user_activate_deactivate(user, resp_activate):
- user.activate()
- user.deactivate()
-
-
-def test_delete_user_identity(user, resp_delete_user_identity):
- user.identityproviders.delete("test_provider")
-
-
-def test_user_follow_unfollow(user, resp_follow_unfollow):
- user.follow()
- user.unfollow()
-
-
-def test_list_followers(user, resp_followers_following):
- followers = user.followers_users.list()
- followings = user.following_users.list()
- assert isinstance(followers[0], User)
- assert followers[0].id == 2
- assert isinstance(followings[0], User)
- assert followings[1].id == 4
diff --git a/tests/unit/objects/test_variables.py b/tests/unit/objects/test_variables.py
deleted file mode 100644
index fae37a8..0000000
--- a/tests/unit/objects/test_variables.py
+++ /dev/null
@@ -1,192 +0,0 @@
-"""
-GitLab API:
-https://docs.gitlab.com/ee/api/instance_level_ci_variables.html
-https://docs.gitlab.com/ee/api/project_level_variables.html
-https://docs.gitlab.com/ee/api/group_level_variables.html
-"""
-
-import re
-
-import pytest
-import responses
-
-from gitlab.v4.objects import GroupVariable, ProjectVariable, Variable
-
-key = "TEST_VARIABLE_1"
-value = "TEST_1"
-new_value = "TEST_2"
-
-variable_content = {
- "key": key,
- "variable_type": "env_var",
- "value": value,
- "protected": False,
- "masked": True,
-}
-variables_url = re.compile(
- r"http://localhost/api/v4/(((groups|projects)/1)|(admin/ci))/variables"
-)
-variables_key_url = re.compile(
- rf"http://localhost/api/v4/(((groups|projects)/1)|(admin/ci))/variables/{key}"
-)
-
-
-@pytest.fixture
-def resp_list_variables():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=variables_url,
- json=[variable_content],
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_get_variable():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.GET,
- url=variables_key_url,
- json=variable_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_create_variable():
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.POST,
- url=variables_url,
- json=variable_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_update_variable():
- updated_content = dict(variable_content)
- updated_content["value"] = new_value
-
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.PUT,
- url=variables_key_url,
- json=updated_content,
- content_type="application/json",
- status=200,
- )
- yield rsps
-
-
-@pytest.fixture
-def resp_delete_variable(no_content):
- with responses.RequestsMock() as rsps:
- rsps.add(
- method=responses.DELETE,
- url=variables_key_url,
- json=no_content,
- content_type="application/json",
- status=204,
- )
- yield rsps
-
-
-def test_list_instance_variables(gl, resp_list_variables):
- variables = gl.variables.list()
- assert isinstance(variables, list)
- assert isinstance(variables[0], Variable)
- assert variables[0].value == value
-
-
-def test_get_instance_variable(gl, resp_get_variable):
- variable = gl.variables.get(key)
- assert isinstance(variable, Variable)
- assert variable.value == value
-
-
-def test_create_instance_variable(gl, resp_create_variable):
- variable = gl.variables.create({"key": key, "value": value})
- assert isinstance(variable, Variable)
- assert variable.value == value
-
-
-def test_update_instance_variable(gl, resp_update_variable):
- variable = gl.variables.get(key, lazy=True)
- variable.value = new_value
- variable.save()
- assert variable.value == new_value
-
-
-def test_delete_instance_variable(gl, resp_delete_variable):
- variable = gl.variables.get(key, lazy=True)
- variable.delete()
-
-
-def test_list_project_variables(project, resp_list_variables):
- variables = project.variables.list()
- assert isinstance(variables, list)
- assert isinstance(variables[0], ProjectVariable)
- assert variables[0].value == value
-
-
-def test_get_project_variable(project, resp_get_variable):
- variable = project.variables.get(key)
- assert isinstance(variable, ProjectVariable)
- assert variable.value == value
-
-
-def test_create_project_variable(project, resp_create_variable):
- variable = project.variables.create({"key": key, "value": value})
- assert isinstance(variable, ProjectVariable)
- assert variable.value == value
-
-
-def test_update_project_variable(project, resp_update_variable):
- variable = project.variables.get(key, lazy=True)
- variable.value = new_value
- variable.save()
- assert variable.value == new_value
-
-
-def test_delete_project_variable(project, resp_delete_variable):
- variable = project.variables.get(key, lazy=True)
- variable.delete()
-
-
-def test_list_group_variables(group, resp_list_variables):
- variables = group.variables.list()
- assert isinstance(variables, list)
- assert isinstance(variables[0], GroupVariable)
- assert variables[0].value == value
-
-
-def test_get_group_variable(group, resp_get_variable):
- variable = group.variables.get(key)
- assert isinstance(variable, GroupVariable)
- assert variable.value == value
-
-
-def test_create_group_variable(group, resp_create_variable):
- variable = group.variables.create({"key": key, "value": value})
- assert isinstance(variable, GroupVariable)
- assert variable.value == value
-
-
-def test_update_group_variable(group, resp_update_variable):
- variable = group.variables.get(key, lazy=True)
- variable.value = new_value
- variable.save()
- assert variable.value == new_value
-
-
-def test_delete_group_variable(group, resp_delete_variable):
- variable = group.variables.get(key, lazy=True)
- variable.delete()
diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py
deleted file mode 100644
index cccdfad..0000000
--- a/tests/unit/test_base.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2017 Gauvain Pocentek <gauvain@pocentek.net>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import pickle
-
-import pytest
-
-import gitlab
-from gitlab import base
-
-
-class FakeGitlab(object):
- pass
-
-
-class FakeObject(base.RESTObject):
- pass
-
-
-class FakeManager(base.RESTManager):
- _obj_cls = FakeObject
- _path = "/tests"
-
-
-@pytest.fixture
-def fake_gitlab():
- return FakeGitlab()
-
-
-@pytest.fixture
-def fake_manager(fake_gitlab):
- return FakeManager(fake_gitlab)
-
-
-class TestRESTManager:
- def test_computed_path_simple(self):
- class MGR(base.RESTManager):
- _path = "/tests"
- _obj_cls = object
-
- mgr = MGR(FakeGitlab())
- assert mgr._computed_path == "/tests"
-
- def test_computed_path_with_parent(self):
- class MGR(base.RESTManager):
- _path = "/tests/%(test_id)s/cases"
- _obj_cls = object
- _from_parent_attrs = {"test_id": "id"}
-
- class Parent(object):
- id = 42
-
- mgr = MGR(FakeGitlab(), parent=Parent())
- assert mgr._computed_path == "/tests/42/cases"
-
- def test_path_property(self):
- class MGR(base.RESTManager):
- _path = "/tests"
- _obj_cls = object
-
- mgr = MGR(FakeGitlab())
- assert mgr.path == "/tests"
-
-
-class TestRESTObject:
- def test_instantiate(self, fake_gitlab, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "bar"})
-
- assert {"foo": "bar"} == obj._attrs
- assert {} == obj._updated_attrs
- assert obj._create_managers() is None
- assert fake_manager == obj.manager
- assert fake_gitlab == obj.manager.gitlab
-
- def test_instantiate_non_dict(self, fake_gitlab, fake_manager):
- with pytest.raises(gitlab.exceptions.GitlabParsingError):
- FakeObject(fake_manager, ["a", "list", "fails"])
-
- def test_picklability(self, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "bar"})
- original_obj_module = obj._module
- pickled = pickle.dumps(obj)
- unpickled = pickle.loads(pickled)
- assert isinstance(unpickled, FakeObject)
- assert hasattr(unpickled, "_module")
- assert unpickled._module == original_obj_module
- pickle.dumps(unpickled)
-
- def test_attrs(self, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "bar"})
-
- assert "bar" == obj.foo
- with pytest.raises(AttributeError):
- getattr(obj, "bar")
-
- obj.bar = "baz"
- assert "baz" == obj.bar
- assert {"foo": "bar"} == obj._attrs
- assert {"bar": "baz"} == obj._updated_attrs
-
- def test_get_id(self, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "bar"})
- obj.id = 42
- assert 42 == obj.get_id()
-
- obj.id = None
- assert obj.get_id() is None
-
- def test_custom_id_attr(self, fake_manager):
- class OtherFakeObject(FakeObject):
- _id_attr = "foo"
-
- obj = OtherFakeObject(fake_manager, {"foo": "bar"})
- assert "bar" == obj.get_id()
-
- def test_update_attrs(self, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "bar"})
- obj.bar = "baz"
- obj._update_attrs({"foo": "foo", "bar": "bar"})
- assert {"foo": "foo", "bar": "bar"} == obj._attrs
- assert {} == obj._updated_attrs
-
- def test_update_attrs_deleted(self, fake_manager):
- obj = FakeObject(fake_manager, {"foo": "foo", "bar": "bar"})
- obj.bar = "baz"
- obj._update_attrs({"foo": "foo"})
- assert {"foo": "foo"} == obj._attrs
- assert {} == obj._updated_attrs
-
- def test_dir_unique(self, fake_manager):
- obj = FakeObject(fake_manager, {"manager": "foo"})
- assert len(dir(obj)) == len(set(dir(obj)))
-
- def test_create_managers(self, fake_gitlab, fake_manager):
- class ObjectWithManager(FakeObject):
- fakes: "FakeManager"
-
- obj = ObjectWithManager(fake_manager, {"foo": "bar"})
- obj.id = 42
- assert isinstance(obj.fakes, FakeManager)
- assert obj.fakes.gitlab == fake_gitlab
- assert obj.fakes._parent == obj
-
- def test_equality(self, fake_manager):
- obj1 = FakeObject(fake_manager, {"id": "foo"})
- obj2 = FakeObject(fake_manager, {"id": "foo", "other_attr": "bar"})
- assert obj1 == obj2
-
- def test_equality_custom_id(self, fake_manager):
- class OtherFakeObject(FakeObject):
- _id_attr = "foo"
-
- obj1 = OtherFakeObject(fake_manager, {"foo": "bar"})
- obj2 = OtherFakeObject(fake_manager, {"foo": "bar", "other_attr": "baz"})
- assert obj1 == obj2
-
- def test_inequality(self, fake_manager):
- obj1 = FakeObject(fake_manager, {"id": "foo"})
- obj2 = FakeObject(fake_manager, {"id": "bar"})
- assert obj1 != obj2
-
- def test_inequality_no_id(self, fake_manager):
- obj1 = FakeObject(fake_manager, {"attr1": "foo"})
- obj2 = FakeObject(fake_manager, {"attr1": "bar"})
- assert obj1 != obj2
diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py
deleted file mode 100644
index a9ca958..0000000
--- a/tests/unit/test_cli.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2016-2017 Gauvain Pocentek <gauvain@pocentek.net>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import argparse
-import io
-import os
-import tempfile
-from contextlib import redirect_stderr # noqa: H302
-
-import pytest
-
-from gitlab import cli
-
-
-@pytest.mark.parametrize(
- "what,expected_class",
- [
- ("class", "Class"),
- ("test-class", "TestClass"),
- ("test-longer-class", "TestLongerClass"),
- ("current-user-gpg-key", "CurrentUserGPGKey"),
- ("user-gpg-key", "UserGPGKey"),
- ("ldap-group", "LDAPGroup"),
- ],
-)
-def test_what_to_cls(what, expected_class):
- def _namespace():
- pass
-
- ExpectedClass = type(expected_class, (), {})
- _namespace.__dict__[expected_class] = ExpectedClass
-
- assert cli.what_to_cls(what, _namespace) == ExpectedClass
-
-
-@pytest.mark.parametrize(
- "class_name,expected_what",
- [
- ("Class", "class"),
- ("TestClass", "test-class"),
- ("TestUPPERCASEClass", "test-uppercase-class"),
- ("UPPERCASETestClass", "uppercase-test-class"),
- ("CurrentUserGPGKey", "current-user-gpg-key"),
- ("UserGPGKey", "user-gpg-key"),
- ("LDAPGroup", "ldap-group"),
- ],
-)
-def test_cls_to_what(class_name, expected_what):
- TestClass = type(class_name, (), {})
-
- assert cli.cls_to_what(TestClass) == expected_what
-
-
-def test_die():
- fl = io.StringIO()
- with redirect_stderr(fl):
- with pytest.raises(SystemExit) as test:
- cli.die("foobar")
- assert fl.getvalue() == "foobar\n"
- assert test.value.code == 1
-
-
-def test_parse_value():
- ret = cli._parse_value("foobar")
- assert ret == "foobar"
-
- ret = cli._parse_value(True)
- assert ret is True
-
- ret = cli._parse_value(1)
- assert ret == 1
-
- ret = cli._parse_value(None)
- assert ret is None
-
- fd, temp_path = tempfile.mkstemp()
- os.write(fd, b"content")
- os.close(fd)
- ret = cli._parse_value("@%s" % temp_path)
- assert ret == "content"
- os.unlink(temp_path)
-
- fl = io.StringIO()
- with redirect_stderr(fl):
- with pytest.raises(SystemExit) as exc:
- cli._parse_value("@/thisfileprobablydoesntexist")
- assert (
- fl.getvalue() == "[Errno 2] No such file or directory:"
- " '/thisfileprobablydoesntexist'\n"
- )
- assert exc.value.code == 1
-
-
-def test_base_parser():
- parser = cli._get_base_parser()
- args = parser.parse_args(["-v", "-g", "gl_id", "-c", "foo.cfg", "-c", "bar.cfg"])
- assert args.verbose
- assert args.gitlab == "gl_id"
- assert args.config_file == ["foo.cfg", "bar.cfg"]
-
-
-def test_v4_parse_args():
- parser = cli._get_parser()
- args = parser.parse_args(["project", "list"])
- assert args.what == "project"
- assert args.whaction == "list"
-
-
-def test_v4_parser():
- parser = cli._get_parser()
- subparsers = next(
- action
- for action in parser._actions
- if isinstance(action, argparse._SubParsersAction)
- )
- assert subparsers is not None
- assert "project" in subparsers.choices
-
- user_subparsers = next(
- action
- for action in subparsers.choices["project"]._actions
- if isinstance(action, argparse._SubParsersAction)
- )
- assert user_subparsers is not None
- assert "list" in user_subparsers.choices
- assert "get" in user_subparsers.choices
- assert "delete" in user_subparsers.choices
- assert "update" in user_subparsers.choices
- assert "create" in user_subparsers.choices
- assert "archive" in user_subparsers.choices
- assert "unarchive" in user_subparsers.choices
-
- actions = user_subparsers.choices["create"]._option_string_actions
- assert not actions["--description"].required
-
- user_subparsers = next(
- action
- for action in subparsers.choices["group"]._actions
- if isinstance(action, argparse._SubParsersAction)
- )
- actions = user_subparsers.choices["create"]._option_string_actions
- assert actions["--name"].required
diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py
deleted file mode 100644
index a62106b..0000000
--- a/tests/unit/test_config.py
+++ /dev/null
@@ -1,317 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2016-2017 Gauvain Pocentek <gauvain@pocentek.net>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import io
-import os
-from textwrap import dedent
-
-import mock
-import pytest
-
-from gitlab import config, USER_AGENT
-
-custom_user_agent = "my-package/1.0.0"
-
-valid_config = u"""[global]
-default = one
-ssl_verify = true
-timeout = 2
-
-[one]
-url = http://one.url
-private_token = ABCDEF
-
-[two]
-url = https://two.url
-private_token = GHIJKL
-ssl_verify = false
-timeout = 10
-
-[three]
-url = https://three.url
-private_token = MNOPQR
-ssl_verify = /path/to/CA/bundle.crt
-per_page = 50
-
-[four]
-url = https://four.url
-oauth_token = STUV
-"""
-
-custom_user_agent_config = """[global]
-default = one
-user_agent = {}
-
-[one]
-url = http://one.url
-private_token = ABCDEF
-""".format(
- custom_user_agent
-)
-
-no_default_config = u"""[global]
-[there]
-url = http://there.url
-private_token = ABCDEF
-"""
-
-missing_attr_config = u"""[global]
-[one]
-url = http://one.url
-
-[two]
-private_token = ABCDEF
-
-[three]
-meh = hem
-
-[four]
-url = http://four.url
-private_token = ABCDEF
-per_page = 200
-"""
-
-
-def global_retry_transient_errors(value: bool) -> str:
- return u"""[global]
-default = one
-retry_transient_errors={}
-[one]
-url = http://one.url
-private_token = ABCDEF""".format(
- value
- )
-
-
-def global_and_gitlab_retry_transient_errors(
- global_value: bool, gitlab_value: bool
-) -> str:
- return u"""[global]
- default = one
- retry_transient_errors={global_value}
- [one]
- url = http://one.url
- private_token = ABCDEF
- retry_transient_errors={gitlab_value}""".format(
- global_value=global_value, gitlab_value=gitlab_value
- )
-
-
-@mock.patch.dict(os.environ, {"PYTHON_GITLAB_CFG": "/some/path"})
-def test_env_config_present():
- assert ["/some/path"] == config._env_config()
-
-
-@mock.patch.dict(os.environ, {}, clear=True)
-def test_env_config_missing():
- assert [] == config._env_config()
-
-
-@mock.patch("os.path.exists")
-def test_missing_config(path_exists):
- path_exists.return_value = False
- with pytest.raises(config.GitlabConfigMissingError):
- config.GitlabConfigParser("test")
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-def test_invalid_id(m_open, path_exists):
- fd = io.StringIO(no_default_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- path_exists.return_value = True
- config.GitlabConfigParser("there")
- with pytest.raises(config.GitlabIDError):
- config.GitlabConfigParser()
-
- fd = io.StringIO(valid_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- with pytest.raises(config.GitlabDataError):
- config.GitlabConfigParser(gitlab_id="not_there")
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-def test_invalid_data(m_open, path_exists):
- fd = io.StringIO(missing_attr_config)
- fd.close = mock.Mock(return_value=None, side_effect=lambda: fd.seek(0))
- m_open.return_value = fd
- path_exists.return_value = True
-
- config.GitlabConfigParser("one")
- config.GitlabConfigParser("one")
- with pytest.raises(config.GitlabDataError):
- config.GitlabConfigParser(gitlab_id="two")
- with pytest.raises(config.GitlabDataError):
- config.GitlabConfigParser(gitlab_id="three")
- with pytest.raises(config.GitlabDataError) as emgr:
- config.GitlabConfigParser("four")
- assert "Unsupported per_page number: 200" == emgr.value.args[0]
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-def test_valid_data(m_open, path_exists):
- fd = io.StringIO(valid_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- path_exists.return_value = True
-
- cp = config.GitlabConfigParser()
- assert "one" == cp.gitlab_id
- assert "http://one.url" == cp.url
- assert "ABCDEF" == cp.private_token
- assert cp.oauth_token is None
- assert 2 == cp.timeout
- assert cp.ssl_verify is True
- assert cp.per_page is None
-
- fd = io.StringIO(valid_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- cp = config.GitlabConfigParser(gitlab_id="two")
- assert "two" == cp.gitlab_id
- assert "https://two.url" == cp.url
- assert "GHIJKL" == cp.private_token
- assert cp.oauth_token is None
- assert 10 == cp.timeout
- assert cp.ssl_verify is False
-
- fd = io.StringIO(valid_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- cp = config.GitlabConfigParser(gitlab_id="three")
- assert "three" == cp.gitlab_id
- assert "https://three.url" == cp.url
- assert "MNOPQR" == cp.private_token
- assert cp.oauth_token is None
- assert 2 == cp.timeout
- assert "/path/to/CA/bundle.crt" == cp.ssl_verify
- assert 50 == cp.per_page
-
- fd = io.StringIO(valid_config)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- cp = config.GitlabConfigParser(gitlab_id="four")
- assert "four" == cp.gitlab_id
- assert "https://four.url" == cp.url
- assert cp.private_token is None
- assert "STUV" == cp.oauth_token
- assert 2 == cp.timeout
- assert cp.ssl_verify is True
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-def test_data_from_helper(m_open, path_exists, tmp_path):
- helper = tmp_path / "helper.sh"
- helper.write_text(
- dedent(
- """\
- #!/bin/sh
- echo "secret"
- """
- )
- )
- helper.chmod(0o755)
-
- fd = io.StringIO(
- dedent(
- """\
- [global]
- default = helper
-
- [helper]
- url = https://helper.url
- oauth_token = helper: %s
- """
- )
- % helper
- )
-
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
- cp = config.GitlabConfigParser(gitlab_id="helper")
- assert "helper" == cp.gitlab_id
- assert "https://helper.url" == cp.url
- assert cp.private_token is None
- assert "secret" == cp.oauth_token
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-@pytest.mark.parametrize(
- "config_string,expected_agent",
- [
- (valid_config, USER_AGENT),
- (custom_user_agent_config, custom_user_agent),
- ],
-)
-def test_config_user_agent(m_open, path_exists, config_string, expected_agent):
- fd = io.StringIO(config_string)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
-
- cp = config.GitlabConfigParser()
- assert cp.user_agent == expected_agent
-
-
-@mock.patch("os.path.exists")
-@mock.patch("builtins.open")
-@pytest.mark.parametrize(
- "config_string,expected",
- [
- pytest.param(valid_config, False, id="default_value"),
- pytest.param(
- global_retry_transient_errors(True), True, id="global_config_true"
- ),
- pytest.param(
- global_retry_transient_errors(False), False, id="global_config_false"
- ),
- pytest.param(
- global_and_gitlab_retry_transient_errors(False, True),
- True,
- id="gitlab_overrides_global_true",
- ),
- pytest.param(
- global_and_gitlab_retry_transient_errors(True, False),
- False,
- id="gitlab_overrides_global_false",
- ),
- pytest.param(
- global_and_gitlab_retry_transient_errors(True, True),
- True,
- id="gitlab_equals_global_true",
- ),
- pytest.param(
- global_and_gitlab_retry_transient_errors(False, False),
- False,
- id="gitlab_equals_global_false",
- ),
- ],
-)
-def test_config_retry_transient_errors_when_global_config_is_set(
- m_open, path_exists, config_string, expected
-):
- fd = io.StringIO(config_string)
- fd.close = mock.Mock(return_value=None)
- m_open.return_value = fd
-
- cp = config.GitlabConfigParser()
- assert cp.retry_transient_errors == expected
diff --git a/tests/unit/test_exceptions.py b/tests/unit/test_exceptions.py
deleted file mode 100644
index 57b394b..0000000
--- a/tests/unit/test_exceptions.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import pytest
-
-from gitlab import exceptions
-
-
-def test_error_raises_from_http_error():
- """Methods decorated with @on_http_error should raise from GitlabHttpError."""
-
- class TestError(Exception):
- pass
-
- @exceptions.on_http_error(TestError)
- def raise_error_from_http_error():
- raise exceptions.GitlabHttpError
-
- with pytest.raises(TestError) as context:
- raise_error_from_http_error()
- assert isinstance(context.value.__cause__, exceptions.GitlabHttpError)
diff --git a/tests/unit/test_gitlab.py b/tests/unit/test_gitlab.py
deleted file mode 100644
index 2bd7d4d..0000000
--- a/tests/unit/test_gitlab.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2014 Mika Mäenpää <mika.j.maenpaa@tut.fi>,
-# Tampere University of Technology
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or`
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import pickle
-
-import pytest
-from httmock import HTTMock, response, urlmatch, with_httmock # noqa
-
-from gitlab import DEFAULT_URL, Gitlab, GitlabList, USER_AGENT
-from gitlab.v4.objects import CurrentUser
-
-localhost = "http://localhost"
-username = "username"
-user_id = 1
-token = "abc123"
-
-
-@urlmatch(scheme="http", netloc="localhost", path="/api/v4/user", method="get")
-def resp_get_user(url, request):
- headers = {"content-type": "application/json"}
- content = '{{"id": {0:d}, "username": "{1:s}"}}'.format(user_id, username).encode(
- "utf-8"
- )
- return response(200, content, headers, None, 5, request)
-
-
-@urlmatch(scheme="http", netloc="localhost", path="/api/v4/tests", method="get")
-def resp_page_1(url, request):
- headers = {
- "content-type": "application/json",
- "X-Page": 1,
- "X-Next-Page": 2,
- "X-Per-Page": 1,
- "X-Total-Pages": 2,
- "X-Total": 2,
- "Link": ("<http://localhost/api/v4/tests?per_page=1&page=2>;" ' rel="next"'),
- }
- content = '[{"a": "b"}]'
- return response(200, content, headers, None, 5, request)
-
-
-@urlmatch(
- scheme="http",
- netloc="localhost",
- path="/api/v4/tests",
- method="get",
- query=r".*page=2",
-)
-def resp_page_2(url, request):
- headers = {
- "content-type": "application/json",
- "X-Page": 2,
- "X-Next-Page": 2,
- "X-Per-Page": 1,
- "X-Total-Pages": 2,
- "X-Total": 2,
- }
- content = '[{"c": "d"}]'
- return response(200, content, headers, None, 5, request)
-
-
-def test_gitlab_build_list(gl):
- with HTTMock(resp_page_1):
- obj = gl.http_list("/tests", as_list=False)
- assert len(obj) == 2
- assert obj._next_url == "http://localhost/api/v4/tests?per_page=1&page=2"
- assert obj.current_page == 1
- assert obj.prev_page is None
- assert obj.next_page == 2
- assert obj.per_page == 1
- assert obj.total_pages == 2
- assert obj.total == 2
-
- with HTTMock(resp_page_2):
- test_list = list(obj)
- assert len(test_list) == 2
- assert test_list[0]["a"] == "b"
- assert test_list[1]["c"] == "d"
-
-
-@with_httmock(resp_page_1, resp_page_2)
-def test_gitlab_all_omitted_when_as_list(gl):
- result = gl.http_list("/tests", as_list=False, all=True)
- assert isinstance(result, GitlabList)
-
-
-def test_gitlab_strip_base_url(gl_trailing):
- assert gl_trailing.url == "http://localhost"
-
-
-def test_gitlab_strip_api_url(gl_trailing):
- assert gl_trailing.api_url == "http://localhost/api/v4"
-
-
-def test_gitlab_build_url(gl_trailing):
- r = gl_trailing._build_url("/projects")
- assert r == "http://localhost/api/v4/projects"
-
-
-def test_gitlab_pickability(gl):
- original_gl_objects = gl._objects
- pickled = pickle.dumps(gl)
- unpickled = pickle.loads(pickled)
- assert isinstance(unpickled, Gitlab)
- assert hasattr(unpickled, "_objects")
- assert unpickled._objects == original_gl_objects
-
-
-@with_httmock(resp_get_user)
-def test_gitlab_token_auth(gl, callback=None):
- gl.auth()
- assert gl.user.username == username
- assert gl.user.id == user_id
- assert isinstance(gl.user, CurrentUser)
-
-
-def test_gitlab_default_url():
- gl = Gitlab()
- assert gl.url == DEFAULT_URL
-
-
-@pytest.mark.parametrize(
- "args, kwargs, expected_url, expected_private_token, expected_oauth_token",
- [
- ([], {}, DEFAULT_URL, None, None),
- ([None, token], {}, DEFAULT_URL, token, None),
- ([localhost], {}, localhost, None, None),
- ([localhost, token], {}, localhost, token, None),
- ([localhost, None, token], {}, localhost, None, token),
- ([], {"private_token": token}, DEFAULT_URL, token, None),
- ([], {"oauth_token": token}, DEFAULT_URL, None, token),
- ([], {"url": localhost}, localhost, None, None),
- ([], {"url": localhost, "private_token": token}, localhost, token, None),
- ([], {"url": localhost, "oauth_token": token}, localhost, None, token),
- ],
- ids=[
- "no_args",
- "args_private_token",
- "args_url",
- "args_url_private_token",
- "args_url_oauth_token",
- "kwargs_private_token",
- "kwargs_oauth_token",
- "kwargs_url",
- "kwargs_url_private_token",
- "kwargs_url_oauth_token",
- ],
-)
-def test_gitlab_args_kwargs(
- args, kwargs, expected_url, expected_private_token, expected_oauth_token
-):
- gl = Gitlab(*args, **kwargs)
- assert gl.url == expected_url
- assert gl.private_token == expected_private_token
- assert gl.oauth_token == expected_oauth_token
-
-
-def test_gitlab_from_config(default_config):
- config_path = default_config
- Gitlab.from_config("one", [config_path])
-
-
-def test_gitlab_subclass_from_config(default_config):
- class MyGitlab(Gitlab):
- pass
-
- config_path = default_config
- gl = MyGitlab.from_config("one", [config_path])
- assert isinstance(gl, MyGitlab)
-
-
-@pytest.mark.parametrize(
- "kwargs,expected_agent",
- [
- ({}, USER_AGENT),
- ({"user_agent": "my-package/1.0.0"}, "my-package/1.0.0"),
- ],
-)
-def test_gitlab_user_agent(kwargs, expected_agent):
- gl = Gitlab("http://localhost", **kwargs)
- assert gl.headers["User-Agent"] == expected_agent
diff --git a/tests/unit/test_gitlab_auth.py b/tests/unit/test_gitlab_auth.py
deleted file mode 100644
index 314fbed..0000000
--- a/tests/unit/test_gitlab_auth.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import pytest
-import requests
-
-from gitlab import Gitlab
-
-
-def test_invalid_auth_args():
- with pytest.raises(ValueError):
- Gitlab(
- "http://localhost",
- api_version="4",
- private_token="private_token",
- oauth_token="bearer",
- )
- with pytest.raises(ValueError):
- Gitlab(
- "http://localhost",
- api_version="4",
- oauth_token="bearer",
- http_username="foo",
- http_password="bar",
- )
- with pytest.raises(ValueError):
- Gitlab(
- "http://localhost",
- api_version="4",
- private_token="private_token",
- http_password="bar",
- )
- with pytest.raises(ValueError):
- Gitlab(
- "http://localhost",
- api_version="4",
- private_token="private_token",
- http_username="foo",
- )
-
-
-def test_private_token_auth():
- gl = Gitlab("http://localhost", private_token="private_token", api_version="4")
- assert gl.private_token == "private_token"
- assert gl.oauth_token is None
- assert gl.job_token is None
- assert gl._http_auth is None
- assert "Authorization" not in gl.headers
- assert gl.headers["PRIVATE-TOKEN"] == "private_token"
- assert "JOB-TOKEN" not in gl.headers
-
-
-def test_oauth_token_auth():
- gl = Gitlab("http://localhost", oauth_token="oauth_token", api_version="4")
- assert gl.private_token is None
- assert gl.oauth_token == "oauth_token"
- assert gl.job_token is None
- assert gl._http_auth is None
- assert gl.headers["Authorization"] == "Bearer oauth_token"
- assert "PRIVATE-TOKEN" not in gl.headers
- assert "JOB-TOKEN" not in gl.headers
-
-
-def test_job_token_auth():
- gl = Gitlab("http://localhost", job_token="CI_JOB_TOKEN", api_version="4")
- assert gl.private_token is None
- assert gl.oauth_token is None
- assert gl.job_token == "CI_JOB_TOKEN"
- assert gl._http_auth is None
- assert "Authorization" not in gl.headers
- assert "PRIVATE-TOKEN" not in gl.headers
- assert gl.headers["JOB-TOKEN"] == "CI_JOB_TOKEN"
-
-
-def test_http_auth():
- gl = Gitlab(
- "http://localhost",
- private_token="private_token",
- http_username="foo",
- http_password="bar",
- api_version="4",
- )
- assert gl.private_token == "private_token"
- assert gl.oauth_token is None
- assert gl.job_token is None
- assert isinstance(gl._http_auth, requests.auth.HTTPBasicAuth)
- assert gl.headers["PRIVATE-TOKEN"] == "private_token"
- assert "Authorization" not in gl.headers
diff --git a/tests/unit/test_gitlab_http_methods.py b/tests/unit/test_gitlab_http_methods.py
deleted file mode 100644
index ba57c31..0000000
--- a/tests/unit/test_gitlab_http_methods.py
+++ /dev/null
@@ -1,406 +0,0 @@
-import pytest
-import requests
-from httmock import HTTMock, response, urlmatch
-
-from gitlab import GitlabHttpError, GitlabList, GitlabParsingError, RedirectError
-
-
-def test_build_url(gl):
- r = gl._build_url("http://localhost/api/v4")
- assert r == "http://localhost/api/v4"
- r = gl._build_url("https://localhost/api/v4")
- assert r == "https://localhost/api/v4"
- r = gl._build_url("/projects")
- assert r == "http://localhost/api/v4/projects"
-
-
-def test_http_request(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '[{"name": "project1"}]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- http_r = gl.http_request("get", "/projects")
- http_r.json()
- assert http_r.status_code == 200
-
-
-def test_http_request_404(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/not_there", method="get")
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_request("get", "/not_there")
-
-
-@pytest.mark.parametrize("status_code", [500, 502, 503, 504])
-def test_http_request_with_only_failures(gl, status_code):
- call_count = 0
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- nonlocal call_count
- call_count += 1
- return response(status_code, {"Here is why it failed"}, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_request("get", "/projects")
-
- assert call_count == 1
-
-
-def test_http_request_with_retry_on_method_for_transient_failures(gl):
- call_count = 0
- calls_before_success = 3
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- nonlocal call_count
- call_count += 1
- status_code = 200 if call_count == calls_before_success else 500
- return response(
- status_code,
- {"Failure is the stepping stone to success"},
- {},
- None,
- 5,
- request,
- )
-
- with HTTMock(resp_cont):
- http_r = gl.http_request("get", "/projects", retry_transient_errors=True)
-
- assert http_r.status_code == 200
- assert call_count == calls_before_success
-
-
-def test_http_request_with_retry_on_class_for_transient_failures(gl_retry):
- call_count = 0
- calls_before_success = 3
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- nonlocal call_count
- call_count += 1
- status_code = 200 if call_count == calls_before_success else 500
- return response(
- status_code,
- {"Failure is the stepping stone to success"},
- {},
- None,
- 5,
- request,
- )
-
- with HTTMock(resp_cont):
- http_r = gl_retry.http_request("get", "/projects")
-
- assert http_r.status_code == 200
- assert call_count == calls_before_success
-
-
-def test_http_request_with_retry_on_class_and_method_for_transient_failures(gl_retry):
- call_count = 0
- calls_before_success = 3
-
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- nonlocal call_count
- call_count += 1
- status_code = 200 if call_count == calls_before_success else 500
- return response(status_code, {"Here is why it failed"}, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl_retry.http_request("get", "/projects", retry_transient_errors=False)
-
- assert call_count == 1
-
-
-def create_redirect_response(
- *, request: requests.models.PreparedRequest, http_method: str, api_path: str
-) -> requests.models.Response:
- """Create a Requests response object that has a redirect in it"""
-
- assert api_path.startswith("/")
- http_method = http_method.upper()
-
- # Create a history which contains our original request which is redirected
- history = [
- response(
- status_code=302,
- content="",
- headers={"Location": f"http://example.com/api/v4{api_path}"},
- reason="Moved Temporarily",
- request=request,
- )
- ]
-
- # Create a "prepped" Request object to be the final redirect. The redirect
- # will be a "GET" method as Requests changes the method to "GET" when there
- # is a 301/302 redirect code.
- req = requests.Request(
- method="GET",
- url=f"http://example.com/api/v4{api_path}",
- )
- prepped = req.prepare()
-
- resp_obj = response(
- status_code=200,
- content="",
- headers={},
- reason="OK",
- elapsed=5,
- request=prepped,
- )
- resp_obj.history = history
- return resp_obj
-
-
-def test_http_request_302_get_does_not_raise(gl):
- """Test to show that a redirect of a GET will not cause an error"""
-
- method = "get"
- api_path = "/user/status"
-
- @urlmatch(
- scheme="http", netloc="localhost", path=f"/api/v4{api_path}", method=method
- )
- def resp_cont(
- url: str, request: requests.models.PreparedRequest
- ) -> requests.models.Response:
- resp_obj = create_redirect_response(
- request=request, http_method=method, api_path=api_path
- )
- return resp_obj
-
- with HTTMock(resp_cont):
- gl.http_request(verb=method, path=api_path)
-
-
-def test_http_request_302_put_raises_redirect_error(gl):
- """Test to show that a redirect of a PUT will cause an error"""
-
- method = "put"
- api_path = "/user/status"
-
- @urlmatch(
- scheme="http", netloc="localhost", path=f"/api/v4{api_path}", method=method
- )
- def resp_cont(
- url: str, request: requests.models.PreparedRequest
- ) -> requests.models.Response:
- resp_obj = create_redirect_response(
- request=request, http_method=method, api_path=api_path
- )
- return resp_obj
-
- with HTTMock(resp_cont):
- with pytest.raises(RedirectError) as exc:
- gl.http_request(verb=method, path=api_path)
- error_message = exc.value.error_message
- assert "Moved Temporarily" in error_message
- assert "http://localhost/api/v4/user/status" in error_message
- assert "http://example.com/api/v4/user/status" in error_message
-
-
-def test_get_request(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url: str, request: requests.models.PreparedRequest):
- headers = {"content-type": "application/json"}
- content = '{"name": "project1"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_get("/projects")
- assert isinstance(result, dict)
- assert result["name"] == "project1"
-
-
-def test_get_request_raw(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- headers = {"content-type": "application/octet-stream"}
- content = "content"
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_get("/projects")
- assert result.content.decode("utf-8") == "content"
-
-
-def test_get_request_404(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/not_there", method="get")
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_get("/not_there")
-
-
-def test_get_request_invalid_data(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '["name": "project1"]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabParsingError):
- gl.http_get("/projects")
-
-
-def test_list_request(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- headers = {"content-type": "application/json", "X-Total": 1}
- content = '[{"name": "project1"}]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_list("/projects", as_list=True)
- assert isinstance(result, list)
- assert len(result) == 1
-
- with HTTMock(resp_cont):
- result = gl.http_list("/projects", as_list=False)
- assert isinstance(result, GitlabList)
- assert len(result) == 1
-
- with HTTMock(resp_cont):
- result = gl.http_list("/projects", all=True)
- assert isinstance(result, list)
- assert len(result) == 1
-
-
-def test_list_request_404(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/not_there", method="get")
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_list("/not_there")
-
-
-def test_list_request_invalid_data(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '["name": "project1"]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabParsingError):
- gl.http_list("/projects")
-
-
-def test_post_request(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="post")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '{"name": "project1"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_post("/projects")
- assert isinstance(result, dict)
- assert result["name"] == "project1"
-
-
-def test_post_request_404(gl):
- @urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/not_there", method="post"
- )
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_post("/not_there")
-
-
-def test_post_request_invalid_data(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="post")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '["name": "project1"]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabParsingError):
- gl.http_post("/projects")
-
-
-def test_put_request(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="put")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '{"name": "project1"}'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_put("/projects")
- assert isinstance(result, dict)
- assert result["name"] == "project1"
-
-
-def test_put_request_404(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/not_there", method="put")
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_put("/not_there")
-
-
-def test_put_request_invalid_data(gl):
- @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="put")
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = '["name": "project1"]'
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabParsingError):
- gl.http_put("/projects")
-
-
-def test_delete_request(gl):
- @urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/projects", method="delete"
- )
- def resp_cont(url, request):
- headers = {"content-type": "application/json"}
- content = "true"
- return response(200, content, headers, None, 5, request)
-
- with HTTMock(resp_cont):
- result = gl.http_delete("/projects")
- assert isinstance(result, requests.Response)
- assert result.json() is True
-
-
-def test_delete_request_404(gl):
- @urlmatch(
- scheme="http", netloc="localhost", path="/api/v4/not_there", method="delete"
- )
- def resp_cont(url, request):
- content = {"Here is why it failed"}
- return response(404, content, {}, None, 5, request)
-
- with HTTMock(resp_cont):
- with pytest.raises(GitlabHttpError):
- gl.http_delete("/not_there")
diff --git a/tests/unit/test_types.py b/tests/unit/test_types.py
deleted file mode 100644
index a2e5ff5..0000000
--- a/tests/unit/test_types.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2018 Gauvain Pocentek <gauvain@pocentek.net>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from gitlab import types
-
-
-def test_gitlab_attribute_get():
- o = types.GitlabAttribute("whatever")
- assert o.get() == "whatever"
-
- o.set_from_cli("whatever2")
- assert o.get() == "whatever2"
- assert o.get_for_api() == "whatever2"
-
- o = types.GitlabAttribute()
- assert o._value is None
-
-
-def test_list_attribute_input():
- o = types.ListAttribute()
- o.set_from_cli("foo,bar,baz")
- assert o.get() == ["foo", "bar", "baz"]
-
- o.set_from_cli("foo")
- assert o.get() == ["foo"]
-
-
-def test_list_attribute_empty_input():
- o = types.ListAttribute()
- o.set_from_cli("")
- assert o.get() == []
-
- o.set_from_cli(" ")
- assert o.get() == []
-
-
-def test_list_attribute_get_for_api_from_cli():
- o = types.ListAttribute()
- o.set_from_cli("foo,bar,baz")
- assert o.get_for_api() == "foo,bar,baz"
-
-
-def test_list_attribute_get_for_api_from_list():
- o = types.ListAttribute(["foo", "bar", "baz"])
- assert o.get_for_api() == "foo,bar,baz"
-
-
-def test_list_attribute_get_for_api_from_int_list():
- o = types.ListAttribute([1, 9, 7])
- assert o.get_for_api() == "1,9,7"
-
-
-def test_list_attribute_does_not_split_string():
- o = types.ListAttribute("foo")
- assert o.get_for_api() == "foo"
-
-
-def test_lowercase_string_attribute_get_for_api():
- o = types.LowercaseStringAttribute("FOO")
- assert o.get_for_api() == "foo"
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
deleted file mode 100644
index dbe0838..0000000
--- a/tests/unit/test_utils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2019 Gauvain Pocentek <gauvain@pocentek.net>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from gitlab import utils
-
-
-def test_clean_str_id():
- src = "nothing_special"
- dest = "nothing_special"
- assert dest == utils.clean_str_id(src)
-
- src = "foo#bar/baz/"
- dest = "foo%23bar%2Fbaz%2F"
- assert dest == utils.clean_str_id(src)
-
- src = "foo%bar/baz/"
- dest = "foo%25bar%2Fbaz%2F"
- assert dest == utils.clean_str_id(src)
-
-
-def test_sanitized_url():
- src = "http://localhost/foo/bar"
- dest = "http://localhost/foo/bar"
- assert dest == utils.sanitized_url(src)
-
- src = "http://localhost/foo.bar.baz"
- dest = "http://localhost/foo%2Ebar%2Ebaz"
- assert dest == utils.sanitized_url(src)