Skip to content

Commit fb8bed4

Browse files
committed
test: generate actions clients tests for each resource client
1 parent 8de4107 commit fb8bed4

File tree

1 file changed

+147
-27
lines changed

1 file changed

+147
-27
lines changed

tests/unit/actions/test_client.py

Lines changed: 147 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import inspect
34
from unittest import mock
45

56
import pytest
@@ -12,6 +13,7 @@
1213
BoundAction,
1314
ResourceActionsClient,
1415
)
16+
from hcloud.core import ResourceClientBase
1517

1618
from ..conftest import assert_bound_action1, assert_bound_action2
1719

@@ -89,86 +91,198 @@ def test_wait_until_finished_max_retries(
8991
assert request_mock.call_count == 1
9092

9193

94+
def resource_clients_with_actions() -> list[str]:
95+
"""
96+
Return the names of all resource clients that support actions.
97+
98+
Allows us to run TestResourceActionsClient against all resource clients that have an
99+
resource actions client.
100+
"""
101+
members = inspect.getmembers(
102+
Client("TOKEN"),
103+
predicate=lambda p: isinstance(p, ResourceClientBase) and hasattr(p, "actions"),
104+
)
105+
return [name for name, _, in members]
106+
107+
92108
class TestResourceActionsClient:
109+
"""
110+
/<resource>/actions
111+
/<resource>/actions/<id>
112+
"""
113+
114+
@pytest.fixture(params=resource_clients_with_actions())
115+
def resource(self, request) -> str:
116+
return request.param
117+
93118
@pytest.fixture()
94-
def actions_client(self, client: Client):
95-
return ResourceActionsClient(client, resource="/resource")
119+
def resource_client(self, client: Client, resource: str) -> ResourceActionsClient:
120+
"""
121+
Extract the resource actions client from the client.
122+
"""
123+
return getattr(client, resource).actions
96124

97125
def test_get_by_id(
98126
self,
99127
request_mock: mock.MagicMock,
100-
actions_client: ActionsClient,
128+
resource_client: ResourceActionsClient,
129+
resource: str,
101130
action_response,
102131
):
103132
request_mock.return_value = action_response
104133

105-
action = actions_client.get_by_id(1)
134+
action = resource_client.get_by_id(1)
106135

107136
request_mock.assert_called_with(
108137
method="GET",
109-
url="/resource/actions/1",
138+
url=f"/{resource}/actions/1",
110139
)
111140

112-
assert_bound_action1(action, actions_client._parent.actions)
141+
assert_bound_action1(action, resource_client._parent.actions)
113142

114143
@pytest.mark.parametrize(
115144
"params",
116145
[
117146
{},
118-
{"status": ["active"], "sort": ["status"], "page": 2, "per_page": 10},
147+
{"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10},
119148
],
120149
)
121150
def test_get_list(
122151
self,
123152
request_mock: mock.MagicMock,
124-
actions_client: ActionsClient,
153+
resource_client: ResourceActionsClient,
154+
resource: str,
125155
action_list_response,
126156
params,
127157
):
128158
request_mock.return_value = action_list_response
129159

130-
result = actions_client.get_list(**params)
160+
result = resource_client.get_list(**params)
131161

132162
request_mock.assert_called_with(
133163
method="GET",
134-
url="/resource/actions",
164+
url=f"/{resource}/actions",
135165
params=params,
136166
)
137167

138168
assert result.meta is not None
139169

140170
actions = result.actions
141171
assert len(actions) == 2
142-
assert_bound_action1(actions[0], actions_client._parent.actions)
143-
assert_bound_action2(actions[1], actions_client._parent.actions)
172+
assert_bound_action1(actions[0], resource_client._parent.actions)
173+
assert_bound_action2(actions[1], resource_client._parent.actions)
144174

145-
@pytest.mark.parametrize("params", [{}, {"status": ["active"], "sort": ["status"]}])
175+
@pytest.mark.parametrize(
176+
"params",
177+
[
178+
{},
179+
{"status": ["running"], "sort": ["status"]},
180+
],
181+
)
146182
def test_get_all(
147183
self,
148184
request_mock: mock.MagicMock,
149-
actions_client: ActionsClient,
185+
resource_client: ResourceActionsClient,
186+
resource: str,
187+
action_list_response,
188+
params,
189+
):
190+
request_mock.return_value = action_list_response
191+
192+
actions = resource_client.get_all(**params)
193+
194+
request_mock.assert_called_with(
195+
method="GET",
196+
url=f"/{resource}/actions",
197+
params={**params, "page": 1, "per_page": 50},
198+
)
199+
200+
assert len(actions) == 2
201+
assert_bound_action1(actions[0], resource_client._parent.actions)
202+
assert_bound_action2(actions[1], resource_client._parent.actions)
203+
204+
205+
class TestResourceObjectActionsClient:
206+
"""
207+
/<resource>/<id>/actions
208+
"""
209+
210+
@pytest.fixture(params=resource_clients_with_actions())
211+
def resource(self, request):
212+
if request.param == "primary_ips":
213+
pytest.skip("not implemented yet")
214+
return request.param
215+
216+
@pytest.fixture()
217+
def resource_client(self, client: Client, resource: str) -> ResourceClientBase:
218+
return getattr(client, resource)
219+
220+
@pytest.mark.parametrize(
221+
"params",
222+
[
223+
{},
224+
{"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10},
225+
],
226+
)
227+
def test_get_actions_list(
228+
self,
229+
request_mock: mock.MagicMock,
230+
resource_client: ResourceClientBase,
231+
resource: str,
232+
action_list_response,
233+
params,
234+
):
235+
request_mock.return_value = action_list_response
236+
237+
result = resource_client.get_actions_list(mock.MagicMock(id=1), **params)
238+
239+
request_mock.assert_called_with(
240+
method="GET",
241+
url=f"/{resource}/1/actions",
242+
params=params,
243+
)
244+
245+
assert result.meta is not None
246+
247+
actions = result.actions
248+
assert len(actions) == 2
249+
assert_bound_action1(actions[0], resource_client._parent.actions)
250+
assert_bound_action2(actions[1], resource_client._parent.actions)
251+
252+
@pytest.mark.parametrize(
253+
"params",
254+
[
255+
{},
256+
{"status": ["running"], "sort": ["status"]},
257+
],
258+
)
259+
def test_get_actions(
260+
self,
261+
request_mock: mock.MagicMock,
262+
resource_client: ResourceClientBase,
263+
resource: str,
150264
action_list_response,
151265
params,
152266
):
153267
request_mock.return_value = action_list_response
154268

155-
actions = actions_client.get_all(**params)
269+
actions = resource_client.get_actions(mock.MagicMock(id=1), **params)
156270

157271
request_mock.assert_called_with(
158272
method="GET",
159-
url="/resource/actions",
273+
url=f"/{resource}/1/actions",
160274
params={**params, "page": 1, "per_page": 50},
161275
)
162276

163277
assert len(actions) == 2
164-
assert_bound_action1(actions[0], actions_client._parent.actions)
165-
assert_bound_action2(actions[1], actions_client._parent.actions)
278+
assert_bound_action1(actions[0], resource_client._parent.actions)
279+
assert_bound_action2(actions[1], resource_client._parent.actions)
166280

167281

168282
class TestActionsClient:
169283
@pytest.fixture()
170-
def actions_client(self, client: Client):
171-
return ActionsClient(client)
284+
def actions_client(self, client: Client) -> ActionsClient:
285+
return client.actions
172286

173287
def test_get_by_id(
174288
self,
@@ -184,13 +298,13 @@ def test_get_by_id(
184298
method="GET",
185299
url="/actions/1",
186300
)
187-
assert_bound_action1(action, actions_client._parent.actions)
301+
assert_bound_action1(action, actions_client)
188302

189303
@pytest.mark.parametrize(
190304
"params",
191305
[
192306
{},
193-
{"status": ["active"], "sort": ["status"], "page": 2, "per_page": 10},
307+
{"status": ["running"], "sort": ["status"], "page": 2, "per_page": 10},
194308
],
195309
)
196310
def test_get_list(
@@ -215,10 +329,16 @@ def test_get_list(
215329

216330
actions = result.actions
217331
assert len(actions) == 2
218-
assert_bound_action1(actions[0], actions_client._parent.actions)
219-
assert_bound_action2(actions[1], actions_client._parent.actions)
332+
assert_bound_action1(actions[0], actions_client)
333+
assert_bound_action2(actions[1], actions_client)
220334

221-
@pytest.mark.parametrize("params", [{}, {"status": ["active"], "sort": ["status"]}])
335+
@pytest.mark.parametrize(
336+
"params",
337+
[
338+
{},
339+
{"status": ["running"], "sort": ["status"]},
340+
],
341+
)
222342
def test_get_all(
223343
self,
224344
request_mock: mock.MagicMock,
@@ -238,5 +358,5 @@ def test_get_all(
238358
)
239359

240360
assert len(actions) == 2
241-
assert_bound_action1(actions[0], actions_client._parent.actions)
242-
assert_bound_action2(actions[1], actions_client._parent.actions)
361+
assert_bound_action1(actions[0], actions_client)
362+
assert_bound_action2(actions[1], actions_client)

0 commit comments

Comments
 (0)