Skip to content

Commit f694b20

Browse files
committed
test: transfer all test_mixins to async
1 parent 882cc2c commit f694b20

File tree

3 files changed

+271
-244
lines changed

3 files changed

+271
-244
lines changed

gitlab/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,17 @@ def __init__(self, manager, obj_cls, _list):
174174
self._obj_cls = obj_cls
175175
self._list = _list
176176

177-
def __iter__(self):
177+
def __aiter__(self):
178178
return self
179179

180180
def __len__(self):
181181
return len(self._list)
182182

183-
def __next__(self):
184-
return self.next()
183+
async def __anext__(self):
184+
return await self.next()
185185

186-
def next(self):
187-
data = self._list.next()
186+
async def next(self):
187+
data = await self._list.next()
188188
return self._obj_cls(self.manager, data)
189189

190190
@property

gitlab/tests/test_async_mixins.py

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
import pytest
2+
import respx
3+
from httpx.status_codes import StatusCode
4+
5+
from gitlab import Gitlab
6+
from gitlab.base import RESTObject, RESTObjectList
7+
from gitlab.mixins import (
8+
CreateMixin,
9+
DeleteMixin,
10+
GetMixin,
11+
GetWithoutIdMixin,
12+
ListMixin,
13+
RefreshMixin,
14+
SaveMixin,
15+
SetMixin,
16+
UpdateMixin,
17+
)
18+
19+
from .test_mixins import FakeManager, FakeObject
20+
21+
22+
class TestMixinMethods:
23+
@pytest.fixture
24+
def gl(self):
25+
return Gitlab("http://localhost", private_token="private_token", api_version=4)
26+
27+
@respx.mock
28+
@pytest.mark.asyncio
29+
async def test_get_mixin(self, gl):
30+
class M(GetMixin, FakeManager):
31+
pass
32+
33+
request = respx.get(
34+
"http://localhost/api/v4/tests/42",
35+
headers={"Content-Type": "application/json"},
36+
content={"id": 42, "foo": "bar"},
37+
status_code=StatusCode.OK,
38+
)
39+
mgr = M(gl)
40+
obj = await mgr.get(42)
41+
assert isinstance(obj, FakeObject)
42+
assert obj.foo == "bar"
43+
assert obj.id == 42
44+
45+
@respx.mock
46+
@pytest.mark.asyncio
47+
async def test_refresh_mixin(self, gl):
48+
class O(RefreshMixin, FakeObject):
49+
pass
50+
51+
request = respx.get(
52+
"http://localhost/api/v4/tests/42",
53+
headers={"Content-Type": "application/json"},
54+
content={"id": 42, "foo": "bar"},
55+
status_code=StatusCode.OK,
56+
)
57+
mgr = FakeManager(gl)
58+
obj = O(mgr, {"id": 42})
59+
res = await obj.refresh()
60+
assert res is None
61+
assert obj.foo == "bar"
62+
assert obj.id == 42
63+
64+
@respx.mock
65+
@pytest.mark.asyncio
66+
async def test_get_without_id_mixin(self, gl):
67+
class M(GetWithoutIdMixin, FakeManager):
68+
pass
69+
70+
request = respx.get(
71+
"http://localhost/api/v4/tests",
72+
headers={"Content-Type": "application/json"},
73+
content='{"foo": "bar"}',
74+
status_code=StatusCode.OK,
75+
)
76+
77+
mgr = M(gl)
78+
obj = await mgr.get()
79+
assert isinstance(obj, FakeObject)
80+
assert obj.foo == "bar"
81+
assert not hasattr(obj, "id")
82+
83+
@respx.mock
84+
@pytest.mark.asyncio
85+
async def test_list_mixin(self, gl):
86+
class M(ListMixin, FakeManager):
87+
pass
88+
89+
request = respx.get(
90+
"http://localhost/api/v4/tests",
91+
headers={"Content-Type": "application/json"},
92+
content='[{"id": 42, "foo": "bar"},{"id": 43, "foo": "baz"}]',
93+
status_code=StatusCode.OK,
94+
)
95+
96+
mgr = M(gl)
97+
obj_list = await mgr.list(as_list=False)
98+
assert isinstance(obj_list, RESTObjectList)
99+
async for obj in obj_list:
100+
assert isinstance(obj, FakeObject)
101+
assert obj.id in (42, 43)
102+
103+
obj_list = await mgr.list(all=True)
104+
assert isinstance(obj_list, list)
105+
assert obj_list[0].id == 42
106+
assert obj_list[1].id == 43
107+
assert isinstance(obj_list[0], FakeObject)
108+
assert len(obj_list) == 2
109+
110+
@respx.mock
111+
@pytest.mark.asyncio
112+
async def test_list_other_url(self, gl):
113+
class M(ListMixin, FakeManager):
114+
pass
115+
116+
request = respx.get(
117+
"http://localhost/api/v4/others",
118+
headers={"Content-Type": "application/json"},
119+
content='[{"id": 42, "foo": "bar"}]',
120+
status_code=StatusCode.OK,
121+
)
122+
123+
mgr = M(gl)
124+
obj_list = await mgr.list(path="/others", as_list=False)
125+
assert isinstance(obj_list, RESTObjectList)
126+
obj = await obj_list.next()
127+
assert obj.id == 42
128+
assert obj.foo == "bar"
129+
with pytest.raises(StopAsyncIteration):
130+
await obj_list.next()
131+
132+
@respx.mock
133+
@pytest.mark.asyncio
134+
async def test_create_mixin(self, gl):
135+
class M(CreateMixin, FakeManager):
136+
_create_attrs = (("foo",), ("bar", "baz"))
137+
_update_attrs = (("foo",), ("bam",))
138+
139+
reqeust = respx.post(
140+
"http://localhost/api/v4/tests",
141+
headers={"Content-Type": "application/json"},
142+
content='{"id": 42, "foo": "bar"}',
143+
status_code=StatusCode.OK,
144+
)
145+
146+
mgr = M(gl)
147+
obj = await mgr.create({"foo": "bar"})
148+
assert isinstance(obj, FakeObject)
149+
assert obj.id == 42
150+
assert obj.foo == "bar"
151+
152+
@respx.mock
153+
@pytest.mark.asyncio
154+
async def test_create_mixin_custom_path(self, gl):
155+
class M(CreateMixin, FakeManager):
156+
_create_attrs = (("foo",), ("bar", "baz"))
157+
_update_attrs = (("foo",), ("bam",))
158+
159+
request = respx.post(
160+
"http://localhost/api/v4/others",
161+
headers={"Content-Type": "application/json"},
162+
content='{"id": 42, "foo": "bar"}',
163+
status_code=StatusCode.OK,
164+
)
165+
166+
mgr = M(gl)
167+
obj = await mgr.create({"foo": "bar"}, path="/others")
168+
assert isinstance(obj, FakeObject)
169+
assert obj.id == 42
170+
assert obj.foo == "bar"
171+
172+
@respx.mock
173+
@pytest.mark.asyncio
174+
async def test_update_mixin(self, gl):
175+
class M(UpdateMixin, FakeManager):
176+
_create_attrs = (("foo",), ("bar", "baz"))
177+
_update_attrs = (("foo",), ("bam",))
178+
179+
request = respx.put(
180+
"http://localhost/api/v4/tests/42",
181+
headers={"Content-Type": "application/json"},
182+
content='{"id": 42, "foo": "baz"}',
183+
status_code=StatusCode.OK,
184+
)
185+
186+
mgr = M(gl)
187+
server_data = await mgr.update(42, {"foo": "baz"})
188+
assert isinstance(server_data, dict)
189+
assert server_data["id"] == 42
190+
assert server_data["foo"] == "baz"
191+
192+
@respx.mock
193+
@pytest.mark.asyncio
194+
async def test_update_mixin_no_id(self, gl):
195+
class M(UpdateMixin, FakeManager):
196+
_create_attrs = (("foo",), ("bar", "baz"))
197+
_update_attrs = (("foo",), ("bam",))
198+
199+
request = respx.put(
200+
"http://localhost/api/v4/tests",
201+
headers={"Content-Type": "application/json"},
202+
content='{"foo": "baz"}',
203+
status_code=StatusCode.OK,
204+
)
205+
mgr = M(gl)
206+
server_data = await mgr.update(new_data={"foo": "baz"})
207+
assert isinstance(server_data, dict)
208+
assert server_data["foo"] == "baz"
209+
210+
@respx.mock
211+
@pytest.mark.asyncio
212+
async def test_delete_mixin(self, gl):
213+
class M(DeleteMixin, FakeManager):
214+
pass
215+
216+
request = respx.delete(
217+
"http://localhost/api/v4/tests/42",
218+
headers={"Content-Type": "application/json"},
219+
content="",
220+
status_code=StatusCode.OK,
221+
)
222+
223+
mgr = M(gl)
224+
await mgr.delete(42)
225+
226+
@respx.mock
227+
@pytest.mark.asyncio
228+
async def test_save_mixin(self, gl):
229+
class M(UpdateMixin, FakeManager):
230+
pass
231+
232+
class O(SaveMixin, RESTObject):
233+
pass
234+
235+
request = respx.put(
236+
"http://localhost/api/v4/tests/42",
237+
headers={"Content-Type": "application/json"},
238+
content='{"id": 42, "foo": "baz"}',
239+
status_code=StatusCode.OK,
240+
)
241+
242+
mgr = M(gl)
243+
obj = O(mgr, {"id": 42, "foo": "bar"})
244+
obj.foo = "baz"
245+
await obj.save()
246+
assert obj._attrs["foo"] == "baz"
247+
assert obj._updated_attrs == {}
248+
249+
@respx.mock
250+
@pytest.mark.asyncio
251+
async def test_set_mixin(self, gl):
252+
class M(SetMixin, FakeManager):
253+
pass
254+
255+
request = respx.put(
256+
"http://localhost/api/v4/tests/foo",
257+
headers={"Content-Type": "application/json"},
258+
content='{"key": "foo", "value": "bar"}',
259+
status_code=StatusCode.OK,
260+
)
261+
262+
mgr = M(gl)
263+
obj = await mgr.set("foo", "bar")
264+
assert isinstance(obj, FakeObject)
265+
assert obj.key == "foo"
266+
assert obj.value == "bar"

0 commit comments

Comments
 (0)