using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using System.Collections; using UnityEditor; using Newtonsoft.Json.Linq; using MCPForUnity.Editor.Tools; using System; namespace Tests.EditMode { /// /// Tests specifically for MCP tool parameter handling issues. /// These tests focus on the actual problems we encountered: /// 1. JSON parameter parsing in manage_asset and manage_gameobject tools /// 2. Material creation with properties through MCP tools /// 3. Material assignment through MCP tools /// public class MCPToolParameterTests { private const string TempDir = "Assets/Temp/MCPToolParameterTests"; [SetUp] public void SetUp() { if (!AssetDatabase.IsValidFolder("Assets/Temp")) { AssetDatabase.CreateFolder("Assets", "Temp"); } if (!AssetDatabase.IsValidFolder(TempDir)) { AssetDatabase.CreateFolder("Assets/Temp", "MCPToolParameterTests"); } } [Test] public void Test_ManageAsset_ShouldAcceptJSONProperties() { var matPath = $"{TempDir}/JsonMat_{Guid.NewGuid().ToString("N")}.mat"; // Build params with properties as a JSON string (to be coerced) var p = new JObject { ["action"] = "create", ["path"] = matPath, ["assetType"] = "Material", ["properties"] = "{\"shader\": \"Universal Render Pipeline/Lit\", \"color\": [0,0,1,1]}" }; try { var raw = ManageAsset.HandleCommand(p); var result = raw as JObject ?? JObject.FromObject(raw); Assert.IsNotNull(result, "Handler should return a JObject result"); Assert.IsTrue(result!.Value("success"), result.ToString()); var mat = AssetDatabase.LoadAssetAtPath(matPath); Assert.IsNotNull(mat, "Material should be created at path"); if (mat.HasProperty("_Color")) { Assert.AreEqual(Color.blue, mat.GetColor("_Color")); } } finally { if (AssetDatabase.LoadAssetAtPath(matPath) != null) { AssetDatabase.DeleteAsset(matPath); } AssetDatabase.Refresh(); } } [Test] public void Test_ManageGameObject_ShouldAcceptJSONComponentProperties() { var matPath = $"{TempDir}/JsonMat_{Guid.NewGuid().ToString("N")}.mat"; // Create a material first (object-typed properties) var createMat = new JObject { ["action"] = "create", ["path"] = matPath, ["assetType"] = "Material", ["properties"] = new JObject { ["shader"] = "Universal Render Pipeline/Lit", ["color"] = new JArray(0,0,1,1) } }; var createMatRes = ManageAsset.HandleCommand(createMat); var createMatObj = createMatRes as JObject ?? JObject.FromObject(createMatRes); Assert.IsTrue(createMatObj.Value("success"), createMatObj.ToString()); // Create a sphere var createGo = new JObject { ["action"] = "create", ["name"] = "MCPParamTestSphere", ["primitiveType"] = "Sphere" }; var createGoRes = ManageGameObject.HandleCommand(createGo); var createGoObj = createGoRes as JObject ?? JObject.FromObject(createGoRes); Assert.IsTrue(createGoObj.Value("success"), createGoObj.ToString()); try { // Assign material via JSON string componentProperties (coercion path) var compJsonObj = new JObject { ["MeshRenderer"] = new JObject { ["sharedMaterial"] = matPath } }; var compJson = compJsonObj.ToString(Newtonsoft.Json.Formatting.None); var modify = new JObject { ["action"] = "modify", ["target"] = "MCPParamTestSphere", ["searchMethod"] = "by_name", ["componentProperties"] = compJson }; var raw = ManageGameObject.HandleCommand(modify); var result = raw as JObject ?? JObject.FromObject(raw); Assert.IsTrue(result.Value("success"), result.ToString()); } finally { var go = GameObject.Find("MCPParamTestSphere"); if (go != null) UnityEngine.Object.DestroyImmediate(go); if (AssetDatabase.LoadAssetAtPath(matPath) != null) AssetDatabase.DeleteAsset(matPath); AssetDatabase.Refresh(); } } [Test] public void Test_JSONParsing_ShouldWorkInMCPTools() { var matPath = $"{TempDir}/JsonMat_{Guid.NewGuid().ToString("N")}.mat"; // manage_asset with JSON string properties (coercion path) var createMat = new JObject { ["action"] = "create", ["path"] = matPath, ["assetType"] = "Material", ["properties"] = "{\"shader\": \"Universal Render Pipeline/Lit\", \"color\": [0,0,1,1]}" }; var createResRaw = ManageAsset.HandleCommand(createMat); var createRes = createResRaw as JObject ?? JObject.FromObject(createResRaw); Assert.IsTrue(createRes.Value("success"), createRes.ToString()); // Create sphere and assign material (object-typed componentProperties) var go = new JObject { ["action"] = "create", ["name"] = "MCPParamJSONSphere", ["primitiveType"] = "Sphere" }; var goRes = ManageGameObject.HandleCommand(go); var goObj = goRes as JObject ?? JObject.FromObject(goRes); Assert.IsTrue(goObj.Value("success"), goObj.ToString()); try { var compJsonObj = new JObject { ["MeshRenderer"] = new JObject { ["sharedMaterial"] = matPath } }; var compJson = compJsonObj.ToString(Newtonsoft.Json.Formatting.None); var modify = new JObject { ["action"] = "modify", ["target"] = "MCPParamJSONSphere", ["searchMethod"] = "by_name", ["componentProperties"] = compJson }; var modResRaw = ManageGameObject.HandleCommand(modify); var modRes = modResRaw as JObject ?? JObject.FromObject(modResRaw); Assert.IsTrue(modRes.Value("success"), modRes.ToString()); } finally { var goObj2 = GameObject.Find("MCPParamJSONSphere"); if (goObj2 != null) UnityEngine.Object.DestroyImmediate(goObj2); if (AssetDatabase.LoadAssetAtPath(matPath) != null) AssetDatabase.DeleteAsset(matPath); AssetDatabase.Refresh(); } } } }