summaryrefslogtreecommitdiff
path: root/gitlab/tests/mixins
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2020-04-17 02:26:28 +0200
committerNejc Habjan <nejc.habjan@siemens.com>2020-08-22 20:09:52 +0200
commit76b2cadf1418e4ea2ac420ebba5a4b4f16fbd4c7 (patch)
tree4dbe6ae57c4f03e1351f7a49e590cbbc6d31121a /gitlab/tests/mixins
parent11383e70f74c70e6fe8a56f18b5b170db982f402 (diff)
downloadgitlab-76b2cadf1418e4ea2ac420ebba5a4b4f16fbd4c7.tar.gz
refactor: split unit tests by GitLab API resources
Diffstat (limited to 'gitlab/tests/mixins')
-rw-r--r--gitlab/tests/mixins/test_meta_mixins.py58
-rw-r--r--gitlab/tests/mixins/test_mixin_methods.py331
-rw-r--r--gitlab/tests/mixins/test_object_mixins_attributes.py79
3 files changed, 468 insertions, 0 deletions
diff --git a/gitlab/tests/mixins/test_meta_mixins.py b/gitlab/tests/mixins/test_meta_mixins.py
new file mode 100644
index 0000000..025e9f4
--- /dev/null
+++ b/gitlab/tests/mixins/test_meta_mixins.py
@@ -0,0 +1,58 @@
+from gitlab.mixins import (
+ CreateMixin,
+ CRUDMixin,
+ DeleteMixin,
+ GetMixin,
+ ListMixin,
+ NoUpdateMixin,
+ UpdateMixin,
+ RetrieveMixin,
+)
+
+
+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/gitlab/tests/mixins/test_mixin_methods.py b/gitlab/tests/mixins/test_mixin_methods.py
new file mode 100644
index 0000000..171e90c
--- /dev/null
+++ b/gitlab/tests/mixins/test_mixin_methods.py
@@ -0,0 +1,331 @@
+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 O(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 = O(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_get_attrs(gl):
+ class M1(CreateMixin, FakeManager):
+ pass
+
+ class M2(CreateMixin, FakeManager):
+ _create_attrs = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("bam",))
+
+ mgr = M1(gl)
+ required, optional = mgr.get_create_attrs()
+ assert len(required) == 0
+ assert len(optional) == 0
+
+ mgr = M2(gl)
+ required, optional = mgr.get_create_attrs()
+ assert "foo" in required
+ assert "bar" in optional
+ assert "baz" in optional
+ assert "bam" not in optional
+
+
+def test_create_mixin_missing_attrs(gl):
+ class M(CreateMixin, FakeManager):
+ _create_attrs = (("foo",), ("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 = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("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 = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("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_get_attrs(gl):
+ class M1(UpdateMixin, FakeManager):
+ pass
+
+ class M2(UpdateMixin, FakeManager):
+ _create_attrs = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("bam",))
+
+ mgr = M1(gl)
+ required, optional = mgr.get_update_attrs()
+ assert len(required) == 0
+ assert len(optional) == 0
+
+ mgr = M2(gl)
+ required, optional = mgr.get_update_attrs()
+ assert "foo" in required
+ assert "bam" in optional
+ assert "bar" not in optional
+ assert "baz" not in optional
+
+
+def test_update_mixin_missing_attrs(gl):
+ class M(UpdateMixin, FakeManager):
+ _update_attrs = (("foo",), ("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 = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("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 = (("foo",), ("bar", "baz"))
+ _update_attrs = (("foo",), ("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 O(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 = O(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/gitlab/tests/mixins/test_object_mixins_attributes.py b/gitlab/tests/mixins/test_object_mixins_attributes.py
new file mode 100644
index 0000000..3502a93
--- /dev/null
+++ b/gitlab/tests/mixins/test_object_mixins_attributes.py
@@ -0,0 +1,79 @@
+# -*- 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 O(AccessRequestMixin):
+ pass
+
+ obj = O()
+ assert hasattr(obj, "approve")
+
+
+def test_subscribable_mixin():
+ class O(SubscribableMixin):
+ pass
+
+ obj = O()
+ assert hasattr(obj, "subscribe")
+ assert hasattr(obj, "unsubscribe")
+
+
+def test_todo_mixin():
+ class O(TodoMixin):
+ pass
+
+ obj = O()
+ assert hasattr(obj, "todo")
+
+
+def test_time_tracking_mixin():
+ class O(TimeTrackingMixin):
+ pass
+
+ obj = O()
+ 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 O(SetMixin):
+ pass
+
+ obj = O()
+ assert hasattr(obj, "set")
+
+
+def test_user_agent_detail_mixin():
+ class O(UserAgentDetailMixin):
+ pass
+
+ obj = O()
+ assert hasattr(obj, "user_agent_detail")