22from httpx import Response
33
44from mpt_api_client .models import Meta , Model
5+ from mpt_api_client .models .model import BaseModel , ModelList , to_snake_case # noqa: WPS347
56
67
78class AgreementDummy (Model ): # noqa: WPS431
@@ -20,6 +21,30 @@ class AgreementWithContactDummy(Model):
2021 contact : ContactDummy
2122
2223
24+ class TypedListItemDummy (BaseModel ):
25+ """Dummy item for typed list tests."""
26+
27+ name : str
28+
29+
30+ class TypedListContainerDummy (BaseModel ):
31+ """Dummy container with a typed list field."""
32+
33+ entries : list [TypedListItemDummy ]
34+
35+
36+ class DictTypedContainerDummy (BaseModel ):
37+ """Dummy container with a dict-typed field."""
38+
39+ metadata : dict [str , str ]
40+
41+
42+ class ScalarListContainerDummy (BaseModel ):
43+ """Dummy container with a list[str] field."""
44+
45+ tags : list [str ]
46+
47+
2348@pytest .fixture
2449def meta_data ():
2550 return {"pagination" : {"limit" : 10 , "offset" : 20 , "total" : 100 }, "ignored" : ["one" ]} # noqa: WPS226
@@ -200,3 +225,106 @@ def test_advanced_mapping():
200225 assert agreement .parameters .ordering [0 ].external_id == "contact"
201226 assert agreement .parameters .ordering [1 ].external_id == "address"
202227 assert agreement .to_dict () == agreement_data
228+
229+
230+ def test_to_snake_case_already_snake ():
231+ result = to_snake_case ("already_snake" ) # act
232+
233+ assert result == "already_snake"
234+
235+
236+ def test_model_list_extend ():
237+ ml = ModelList ([{"id" : "1" }])
238+
239+ ml .extend ([{"id" : "2" }, {"id" : "3" }]) # act
240+
241+ assert [ml_item .id for ml_item in ml ] == ["1" , "2" , "3" ]
242+
243+
244+ def test_model_list_insert ():
245+ ml = ModelList ([{"id" : "1" }, {"id" : "3" }])
246+
247+ ml .insert (1 , {"id" : "2" }) # act
248+
249+ assert len (ml ) == 3
250+ assert ml [0 ].id == "1"
251+ assert ml [1 ].id == "2"
252+ assert ml [2 ].id == "3"
253+
254+
255+ def test_model_list_process_item_nested_list ():
256+ nested = [{"id" : "a" }, {"id" : "b" }]
257+
258+ ml = ModelList ([nested ]) # act
259+
260+ assert isinstance (ml [0 ], ModelList )
261+ assert ml [0 ][0 ].id == "a"
262+
263+
264+ def test_model_list_process_item_scalar ():
265+ ml = ModelList (["a" , "b" , "c" ]) # act
266+
267+ assert ml [0 ] == "a"
268+ assert ml [1 ] == "b"
269+ assert ml [2 ] == "c"
270+
271+
272+ def test_base_model_getattr_from_dict ():
273+ model = BaseModel (foo = "bar" )
274+
275+ result = model .__getattr__ ("foo" ) # noqa: PLC2801
276+
277+ assert result == "bar"
278+
279+
280+ def test_base_model_setattr_private ():
281+ model = BaseModel (foo = "bar" )
282+
283+ model ._private = "secret" # noqa: SLF001 # act
284+
285+ assert model ._private == "secret" # noqa: SLF001
286+
287+
288+ def test_to_dict_excludes_private_attrs ():
289+ model = BaseModel (foo = "bar" )
290+ model ._private = "secret" # noqa: SLF001
291+
292+ result = model .to_dict ()
293+
294+ assert result == {"foo" : "bar" }
295+ assert "_private" not in result
296+
297+
298+ def test_process_value_typed_list ():
299+ container = TypedListContainerDummy (entries = [{"name" : "one" }, {"name" : "two" }]) # act
300+
301+ assert isinstance (container .entries [0 ], TypedListItemDummy )
302+ assert container .entries [0 ].name == "one"
303+ assert isinstance (container .entries [1 ], TypedListItemDummy )
304+ assert container .entries [1 ].name == "two"
305+
306+
307+ def test_process_value_existing_base_model ():
308+ nested = BaseModel (value = "test" )
309+ model = BaseModel ()
310+
311+ model .nested = nested # act
312+
313+ assert model .nested is nested
314+
315+
316+ def test_process_value_non_list_target ():
317+ container = DictTypedContainerDummy ()
318+
319+ container .metadata = [{"id" : "1" }] # act
320+
321+ assert isinstance (container .metadata , ModelList )
322+ assert container .metadata [0 ].id == "1"
323+
324+
325+ def test_process_value_scalar_list_elements ():
326+ container = ScalarListContainerDummy (tags = ["a" , "b" , "c" ]) # act
327+
328+ assert isinstance (container .tags , ModelList )
329+ assert container .tags [0 ] == "a"
330+ assert container .tags [1 ] == "b"
0 commit comments