11from __future__ import annotations
22
3+ import inspect
34from unittest import mock
45
56import pytest
1213 BoundAction ,
1314 ResourceActionsClient ,
1415)
16+ from hcloud .core import ResourceClientBase
1517
1618from ..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+
92108class 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
168282class 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