11from __future__ import annotations
22
3+ import inspect
34from unittest import mock
45
56import pytest
1213 BoundAction ,
1314 ResourceActionsClient ,
1415)
16+ from hcloud .certificates import CertificatesClient
17+ from hcloud .core import ResourceClientBase
18+ from hcloud .firewalls import FirewallsClient
19+ from hcloud .floating_ips import FloatingIPsClient
20+ from hcloud .images import ImagesClient
21+ from hcloud .load_balancers import LoadBalancersClient
22+ from hcloud .networks import NetworksClient
23+ from hcloud .primary_ips import PrimaryIPsClient
24+ from hcloud .servers import ServersClient
25+ from hcloud .volumes import VolumesClient
1526
1627from ..conftest import assert_bound_action1 , assert_bound_action2
1728
29+ resource_clients_with_actions = {
30+ "certificates" : CertificatesClient ,
31+ "firewalls" : FirewallsClient ,
32+ "floating_ips" : FloatingIPsClient ,
33+ "images" : ImagesClient ,
34+ "load_balancers" : LoadBalancersClient ,
35+ "networks" : NetworksClient ,
36+ "primary_ips" : PrimaryIPsClient ,
37+ "servers" : ServersClient ,
38+ "volumes" : VolumesClient ,
39+ }
40+
41+
42+ def test_resource_clients_with_actions (client : Client ):
43+ members = inspect .getmembers (
44+ client ,
45+ predicate = lambda p : isinstance (p , ResourceClientBase ) and hasattr (p , "actions" ),
46+ )
47+ for name , member in members :
48+ assert name in resource_clients_with_actions
49+ assert member .__class__ is resource_clients_with_actions [name ]
50+
51+ assert len (members ) == len (resource_clients_with_actions )
52+
1853
1954class TestBoundAction :
2055 @pytest .fixture ()
@@ -90,85 +125,183 @@ def test_wait_until_finished_max_retries(
90125
91126
92127class TestResourceActionsClient :
128+ """
129+ /<resource>/actions
130+ /<resource>/actions/<id>
131+ """
132+
133+ @pytest .fixture (params = resource_clients_with_actions .keys ())
134+ def resource (self , request ) -> str :
135+ return request .param
136+
93137 @pytest .fixture ()
94- def actions_client (self , client : Client ):
95- return ResourceActionsClient (client , resource = "/resource" )
138+ def resource_client (self , client : Client , resource : str ) -> ResourceActionsClient :
139+ """
140+ Extract the resource actions client from the client.
141+ """
142+ return getattr (client , resource ).actions
96143
97144 def test_get_by_id (
98145 self ,
99146 request_mock : mock .MagicMock ,
100- actions_client : ActionsClient ,
147+ resource_client : ResourceActionsClient ,
148+ resource : str ,
101149 action_response ,
102150 ):
103151 request_mock .return_value = action_response
104152
105- action = actions_client .get_by_id (1 )
153+ action = resource_client .get_by_id (1 )
106154
107155 request_mock .assert_called_with (
108156 method = "GET" ,
109- url = "/ resource/actions/1" ,
157+ url = f"/ { resource } /actions/1" ,
110158 )
111159
112- assert_bound_action1 (action , actions_client ._parent .actions )
160+ assert_bound_action1 (action , resource_client ._parent .actions )
113161
114162 @pytest .mark .parametrize (
115163 "params" ,
116164 [
117165 {},
118- {"status" : ["active " ], "sort" : ["status" ], "page" : 2 , "per_page" : 10 },
166+ {"status" : ["running " ], "sort" : ["status" ], "page" : 2 , "per_page" : 10 },
119167 ],
120168 )
121169 def test_get_list (
122170 self ,
123171 request_mock : mock .MagicMock ,
124- actions_client : ActionsClient ,
172+ resource_client : ResourceActionsClient ,
173+ resource : str ,
125174 action_list_response ,
126175 params ,
127176 ):
128177 request_mock .return_value = action_list_response
129178
130- result = actions_client .get_list (** params )
179+ result = resource_client .get_list (** params )
131180
132181 request_mock .assert_called_with (
133182 method = "GET" ,
134- url = "/ resource/actions" ,
183+ url = f"/ { resource } /actions" ,
135184 params = params ,
136185 )
137186
138187 assert result .meta is not None
139188
140189 actions = result .actions
141190 assert len (actions ) == 2
142- assert_bound_action1 (actions [0 ], actions_client ._parent .actions )
143- assert_bound_action2 (actions [1 ], actions_client ._parent .actions )
191+ assert_bound_action1 (actions [0 ], resource_client ._parent .actions )
192+ assert_bound_action2 (actions [1 ], resource_client ._parent .actions )
144193
145- @pytest .mark .parametrize ("params" , [{}, {"status" : ["active" ], "sort" : ["status" ]}])
194+ @pytest .mark .parametrize (
195+ "params" ,
196+ [
197+ {},
198+ {"status" : ["running" ], "sort" : ["status" ]},
199+ ],
200+ )
146201 def test_get_all (
147202 self ,
148203 request_mock : mock .MagicMock ,
149- actions_client : ActionsClient ,
204+ resource_client : ResourceActionsClient ,
205+ resource : str ,
150206 action_list_response ,
151207 params ,
152208 ):
153209 request_mock .return_value = action_list_response
154210
155- actions = actions_client .get_all (** params )
211+ actions = resource_client .get_all (** params )
156212
157213 request_mock .assert_called_with (
158214 method = "GET" ,
159- url = "/ resource/actions" ,
215+ url = f"/ { resource } /actions" ,
160216 params = {** params , "page" : 1 , "per_page" : 50 },
161217 )
162218
163219 assert len (actions ) == 2
164- assert_bound_action1 (actions [0 ], actions_client ._parent .actions )
165- assert_bound_action2 (actions [1 ], actions_client ._parent .actions )
220+ assert_bound_action1 (actions [0 ], resource_client ._parent .actions )
221+ assert_bound_action2 (actions [1 ], resource_client ._parent .actions )
222+
223+
224+ class TestResourceObjectActionsClient :
225+ """
226+ /<resource>/<id>/actions
227+ """
228+
229+ @pytest .fixture (params = resource_clients_with_actions .keys ())
230+ def resource (self , request ):
231+ if request .param == "primary_ips" :
232+ pytest .skip ("not implemented yet" )
233+ return request .param
234+
235+ @pytest .fixture ()
236+ def resource_client (self , client : Client , resource : str ) -> ResourceClientBase :
237+ return getattr (client , resource )
238+
239+ @pytest .mark .parametrize (
240+ "params" ,
241+ [
242+ {},
243+ {"status" : ["running" ], "sort" : ["status" ], "page" : 2 , "per_page" : 10 },
244+ ],
245+ )
246+ def test_get_actions_list (
247+ self ,
248+ request_mock : mock .MagicMock ,
249+ resource_client : ResourceClientBase ,
250+ resource : str ,
251+ action_list_response ,
252+ params ,
253+ ):
254+ request_mock .return_value = action_list_response
255+
256+ result = resource_client .get_actions_list (mock .MagicMock (id = 1 ), ** params )
257+
258+ request_mock .assert_called_with (
259+ method = "GET" ,
260+ url = f"/{ resource } /1/actions" ,
261+ params = params ,
262+ )
263+
264+ assert result .meta is not None
265+
266+ actions = result .actions
267+ assert len (actions ) == 2
268+ assert_bound_action1 (actions [0 ], resource_client ._parent .actions )
269+ assert_bound_action2 (actions [1 ], resource_client ._parent .actions )
270+
271+ @pytest .mark .parametrize (
272+ "params" ,
273+ [
274+ {},
275+ {"status" : ["running" ], "sort" : ["status" ]},
276+ ],
277+ )
278+ def test_get_actions (
279+ self ,
280+ request_mock : mock .MagicMock ,
281+ resource_client : ResourceClientBase ,
282+ resource : str ,
283+ action_list_response ,
284+ params ,
285+ ):
286+ request_mock .return_value = action_list_response
287+
288+ actions = resource_client .get_actions (mock .MagicMock (id = 1 ), ** params )
289+
290+ request_mock .assert_called_with (
291+ method = "GET" ,
292+ url = f"/{ resource } /1/actions" ,
293+ params = {** params , "page" : 1 , "per_page" : 50 },
294+ )
295+
296+ assert len (actions ) == 2
297+ assert_bound_action1 (actions [0 ], resource_client ._parent .actions )
298+ assert_bound_action2 (actions [1 ], resource_client ._parent .actions )
166299
167300
168301class TestActionsClient :
169302 @pytest .fixture ()
170- def actions_client (self , client : Client ):
171- return ActionsClient ( client )
303+ def actions_client (self , client : Client ) -> ActionsClient :
304+ return client . actions
172305
173306 def test_get_by_id (
174307 self ,
@@ -184,13 +317,13 @@ def test_get_by_id(
184317 method = "GET" ,
185318 url = "/actions/1" ,
186319 )
187- assert_bound_action1 (action , actions_client . _parent . actions )
320+ assert_bound_action1 (action , actions_client )
188321
189322 @pytest .mark .parametrize (
190323 "params" ,
191324 [
192325 {},
193- {"status" : ["active " ], "sort" : ["status" ], "page" : 2 , "per_page" : 10 },
326+ {"status" : ["running " ], "sort" : ["status" ], "page" : 2 , "per_page" : 10 },
194327 ],
195328 )
196329 def test_get_list (
@@ -215,10 +348,16 @@ def test_get_list(
215348
216349 actions = result .actions
217350 assert len (actions ) == 2
218- assert_bound_action1 (actions [0 ], actions_client . _parent . actions )
219- assert_bound_action2 (actions [1 ], actions_client . _parent . actions )
351+ assert_bound_action1 (actions [0 ], actions_client )
352+ assert_bound_action2 (actions [1 ], actions_client )
220353
221- @pytest .mark .parametrize ("params" , [{}, {"status" : ["active" ], "sort" : ["status" ]}])
354+ @pytest .mark .parametrize (
355+ "params" ,
356+ [
357+ {},
358+ {"status" : ["running" ], "sort" : ["status" ]},
359+ ],
360+ )
222361 def test_get_all (
223362 self ,
224363 request_mock : mock .MagicMock ,
@@ -238,5 +377,5 @@ def test_get_all(
238377 )
239378
240379 assert len (actions ) == 2
241- assert_bound_action1 (actions [0 ], actions_client . _parent . actions )
242- assert_bound_action2 (actions [1 ], actions_client . _parent . actions )
380+ assert_bound_action1 (actions [0 ], actions_client )
381+ assert_bound_action2 (actions [1 ], actions_client )
0 commit comments