1- """Tests for manage_prefabs tool - component_properties parameter ."""
1+ """Tests for manage_prefabs tool."""
22
3+ import asyncio
34import inspect
5+ from types import SimpleNamespace
6+ from unittest .mock import AsyncMock
7+
8+ import pytest
49
510from services .tools .manage_prefabs import manage_prefabs
11+ from services .registry import get_registered_tools
12+
13+
14+ # ── Fixture ──────────────────────────────────────────────────────────
15+
16+
17+ @pytest .fixture
18+ def mock_unity (monkeypatch ):
19+ captured : dict [str , object ] = {}
20+
21+ async def fake_send (send_fn , unity_instance , tool_name , params ):
22+ captured ["unity_instance" ] = unity_instance
23+ captured ["tool_name" ] = tool_name
24+ captured ["params" ] = params
25+ return {"success" : True , "message" : "ok" }
26+
27+ monkeypatch .setattr (
28+ "services.tools.manage_prefabs.get_unity_instance_from_context" ,
29+ AsyncMock (return_value = "unity-instance-1" ),
30+ )
31+ monkeypatch .setattr (
32+ "services.tools.manage_prefabs.send_with_unity_instance" ,
33+ fake_send ,
34+ )
35+ monkeypatch .setattr (
36+ "services.tools.manage_prefabs.preflight" ,
37+ AsyncMock (return_value = None ),
38+ )
39+ return captured
40+
41+
42+ # ── component_properties ─────────────────────────────────────────────
643
744
845class TestManagePrefabsComponentProperties :
@@ -21,13 +58,10 @@ def test_component_properties_parameter_is_optional(self):
2158
2259 def test_tool_description_mentions_component_properties (self ):
2360 """The tool description should mention component_properties."""
24- from services .registry import get_registered_tools
25- tools = get_registered_tools ()
2661 prefab_tool = next (
27- (t for t in tools if t ["name" ] == "manage_prefabs" ), None
62+ (t for t in get_registered_tools () if t ["name" ] == "manage_prefabs" ), None
2863 )
2964 assert prefab_tool is not None
30- # Description is stored at top level or in kwargs depending on how the decorator stores it
3165 desc = prefab_tool .get ("description" ) or prefab_tool .get ("kwargs" , {}).get ("description" , "" )
3266 assert "component_properties" in desc
3367
@@ -36,3 +70,68 @@ def test_required_params_include_modify_contents(self):
3670 from services .tools .manage_prefabs import REQUIRED_PARAMS
3771 assert "modify_contents" in REQUIRED_PARAMS
3872 assert "prefab_path" in REQUIRED_PARAMS ["modify_contents" ]
73+
74+
75+ # ── delete_child ─────────────────────────────────────────────────────
76+
77+
78+ class TestManagePrefabsDeleteChild :
79+ """Tests for the delete_child parameter on manage_prefabs."""
80+
81+ def test_delete_child_parameter_exists (self ):
82+ """The manage_prefabs tool should have a delete_child parameter."""
83+ sig = inspect .signature (manage_prefabs )
84+ assert "delete_child" in sig .parameters
85+
86+ def test_delete_child_parameter_is_optional (self ):
87+ """delete_child should default to None."""
88+ sig = inspect .signature (manage_prefabs )
89+ param = sig .parameters ["delete_child" ]
90+ assert param .default is None
91+
92+ def test_tool_description_mentions_delete_child (self ):
93+ """The tool description should mention delete_child."""
94+ prefab_tool = next (
95+ (t for t in get_registered_tools () if t ["name" ] == "manage_prefabs" ), None
96+ )
97+ assert prefab_tool is not None
98+ desc = prefab_tool .get ("description" ) or prefab_tool .get ("kwargs" , {}).get ("description" , "" )
99+ assert "delete_child" in desc
100+
101+ def test_delete_child_string_forwards_to_unity (self , mock_unity ):
102+ """A single string delete_child should be forwarded as-is."""
103+ result = asyncio .run (
104+ manage_prefabs (
105+ SimpleNamespace (),
106+ action = "modify_contents" ,
107+ prefab_path = "Assets/Prefabs/Test.prefab" ,
108+ delete_child = "Child1" ,
109+ )
110+ )
111+ assert result ["success" ] is True
112+ assert mock_unity ["tool_name" ] == "manage_prefabs"
113+ assert mock_unity ["params" ]["deleteChild" ] == "Child1"
114+
115+ def test_delete_child_list_forwards_to_unity (self , mock_unity ):
116+ """A list of delete_child paths should be forwarded as-is."""
117+ result = asyncio .run (
118+ manage_prefabs (
119+ SimpleNamespace (),
120+ action = "modify_contents" ,
121+ prefab_path = "Assets/Prefabs/Test.prefab" ,
122+ delete_child = ["Child1" , "Child2/Grandchild" ],
123+ )
124+ )
125+ assert result ["success" ] is True
126+ assert mock_unity ["params" ]["deleteChild" ] == ["Child1" , "Child2/Grandchild" ]
127+
128+ def test_delete_child_none_omitted_from_params (self , mock_unity ):
129+ """When delete_child is None, deleteChild should not appear in params."""
130+ asyncio .run (
131+ manage_prefabs (
132+ SimpleNamespace (),
133+ action = "modify_contents" ,
134+ prefab_path = "Assets/Prefabs/Test.prefab" ,
135+ )
136+ )
137+ assert "deleteChild" not in mock_unity ["params" ]
0 commit comments