using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; using NUnit.Framework; using UnityEditor; using UnityEngine; using MCPForUnity.Editor.Tools.Graphics; using static MCPForUnityTests.Editor.TestUtilities; namespace MCPForUnityTests.Editor.Tools { public class ManageGraphicsTests { private const string TempRoot = "Assets/Temp/ManageGraphicsTests"; private bool _hasVolumeSystem; private bool _hasURP; private bool _hasHDRP; private bool _hasSceneView; [SetUp] public void SetUp() { EnsureFolder(TempRoot); var pingResult = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "ping" })); if (pingResult.Value("success")) { var data = pingResult["data"]; _hasVolumeSystem = data?.Value("hasVolumeSystem") ?? false; _hasURP = data?.Value("hasURP") ?? false; _hasHDRP = data?.Value("hasHDRP") ?? false; } _hasSceneView = UnityEditor.SceneView.lastActiveSceneView != null; } [TearDown] public void TearDown() { #if UNITY_2022_2_OR_NEWER foreach (var go in UnityEngine.Object.FindObjectsByType(FindObjectsSortMode.None)) #else foreach (var go in UnityEngine.Object.FindObjectsOfType()) #endif { if (go.name.StartsWith("GfxTest_")) UnityEngine.Object.DestroyImmediate(go); } if (AssetDatabase.IsValidFolder(TempRoot)) AssetDatabase.DeleteAsset(TempRoot); CleanupEmptyParentFolders(TempRoot); // Reset scene debug mode ManageGraphics.HandleCommand(new JObject { ["action"] = "stats_set_scene_debug", ["mode"] = "Textured" }); } // ===================================================================== // Dispatch / Error Handling // ===================================================================== [Test] public void HandleCommand_NullParams_ReturnsError() { var result = ToJObject(ManageGraphics.HandleCommand(null)); Assert.IsFalse(result.Value("success")); } [Test] public void HandleCommand_MissingAction_ReturnsError() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject())); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("action")); } [Test] public void HandleCommand_UnknownAction_ReturnsError() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bogus_action" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("Unknown action")); } [Test] public void Ping_ReturnsPipelineInfo() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "ping" })); Assert.IsTrue(result.Value("success")); Assert.That(result["message"].ToString(), Does.Contain("Pipeline")); var data = result["data"]; Assert.IsNotNull(data); Assert.IsNotNull(data["pipeline"]); Assert.IsNotNull(data["pipelineName"]); } // ===================================================================== // Volume Actions // ===================================================================== private void AssumeVolumeSystem() { Assume.That(_hasVolumeSystem, "Volume system not available — skipping."); } [Test] public void VolumeCreate_Global_CreatesVolume() { AssumeVolumeSystem(); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_create", ["name"] = "GfxTest_Volume", ["is_global"] = true, ["priority"] = 10 })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsTrue(result["data"]["isGlobal"].Value()); Assert.AreEqual(10, result["data"]["priority"].Value()); } [Test] public void VolumeCreate_WithEffects_AddsEffects() { AssumeVolumeSystem(); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_create", ["name"] = "GfxTest_VolumeEffects", ["effects"] = new JArray { new JObject { ["type"] = "Bloom", ["intensity"] = 2 }, new JObject { ["type"] = "Vignette", ["intensity"] = 0.5 } } })); Assert.IsTrue(result.Value("success"), result.ToString()); var effects = result["data"]["effects"] as JArray; Assert.IsNotNull(effects); Assert.AreEqual(2, effects.Count); } [Test] public void VolumeCreate_Local_CreatesNonGlobal() { AssumeVolumeSystem(); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_create", ["name"] = "GfxTest_LocalVol", ["is_global"] = false })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsFalse(result["data"]["isGlobal"].Value()); } [Test] public void VolumeAddEffect_AddsEffect() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_AddFx"); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_AddFx", ["effect"] = "Bloom", ["parameters"] = new JObject { ["intensity"] = 3 } })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.AreEqual("Bloom", result["data"]["effect"].ToString()); } [Test] public void VolumeAddEffect_Duplicate_ReturnsError() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_DupFx"); ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_DupFx", ["effect"] = "Bloom" }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_DupFx", ["effect"] = "Bloom" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("already exists")); } [Test] public void VolumeAddEffect_InvalidEffect_ReturnsError() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_BadFx"); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_BadFx", ["effect"] = "FakeEffect" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("not found")); } [Test] public void VolumeSetEffect_SetsParameters() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_SetFx"); ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_SetFx", ["effect"] = "Bloom" }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_set_effect", ["target"] = "GfxTest_SetFx", ["effect"] = "Bloom", ["parameters"] = new JObject { ["intensity"] = 5, ["scatter"] = 0.8 } })); Assert.IsTrue(result.Value("success"), result.ToString()); var setParams = result["data"]["set"] as JArray; Assert.IsNotNull(setParams); Assert.That(setParams.Select(t => t.ToString()), Contains.Item("intensity")); Assert.That(setParams.Select(t => t.ToString()), Contains.Item("scatter")); } [Test] public void VolumeSetEffect_InvalidParam_ReportsFailed() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_BadParam"); ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_BadParam", ["effect"] = "Bloom" }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_set_effect", ["target"] = "GfxTest_BadParam", ["effect"] = "Bloom", ["parameters"] = new JObject { ["nonExistent"] = 42 } })); Assert.IsTrue(result.Value("success")); var failed = result["data"]["failed"] as JArray; Assert.IsNotNull(failed); Assert.That(failed.Select(t => t.ToString()), Contains.Item("nonExistent")); } [Test] public void VolumeRemoveEffect_RemovesEffect() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_RmFx"); ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_RmFx", ["effect"] = "Vignette" }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_remove_effect", ["target"] = "GfxTest_RmFx", ["effect"] = "Vignette" })); Assert.IsTrue(result.Value("success"), result.ToString()); // Verify it's gone var info = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_get_info", ["target"] = "GfxTest_RmFx" })); var effects = info["data"]["effects"] as JArray; Assert.IsNotNull(effects); Assert.AreEqual(0, effects.Count); } [Test] public void VolumeRemoveEffect_NonExistent_ReturnsError() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_RmMissing"); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_remove_effect", ["target"] = "GfxTest_RmMissing", ["effect"] = "DepthOfField" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("not found")); } [Test] public void VolumeGetInfo_ReturnsEffectList() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_Info"); ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_add_effect", ["target"] = "GfxTest_Info", ["effect"] = "Bloom" }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_get_info", ["target"] = "GfxTest_Info" })); Assert.IsTrue(result.Value("success"), result.ToString()); var data = result["data"]; Assert.AreEqual("GfxTest_Info", data["name"].ToString()); var effects = data["effects"] as JArray; Assert.IsNotNull(effects); Assert.AreEqual(1, effects.Count); Assert.AreEqual("Bloom", effects[0]["type"].ToString()); } [Test] public void VolumeGetInfo_NonExistentTarget_ReturnsError() { AssumeVolumeSystem(); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_get_info", ["target"] = "NonExistentVolume" })); Assert.IsFalse(result.Value("success")); } [Test] public void VolumeSetProperties_UpdatesWeightAndPriority() { AssumeVolumeSystem(); CreateTestVolume("GfxTest_Props"); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_set_properties", ["target"] = "GfxTest_Props", ["properties"] = new JObject { ["weight"] = 0.5, ["priority"] = 20 } })); Assert.IsTrue(result.Value("success"), result.ToString()); var changed = result["data"]["changed"] as JArray; Assert.IsNotNull(changed); Assert.That(changed.Select(t => t.ToString()), Contains.Item("weight")); Assert.That(changed.Select(t => t.ToString()), Contains.Item("priority")); // Verify via get_info var info = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_get_info", ["target"] = "GfxTest_Props" })); Assert.AreEqual(0.5f, info["data"]["weight"].Value(), 0.01f); Assert.AreEqual(20f, info["data"]["priority"].Value(), 0.01f); } [Test] public void VolumeListEffects_ReturnsAvailableTypes() { AssumeVolumeSystem(); var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "volume_list_effects" })); Assert.IsTrue(result.Value("success"), result.ToString()); var effects = result["data"]["effects"] as JArray; Assert.IsNotNull(effects); Assert.Greater(effects.Count, 0); Assert.IsNotNull(effects[0]["name"]); } [Test] public void VolumeCreateProfile_CreatesAsset() { AssumeVolumeSystem(); string path = $"{TempRoot}/TestProfile"; var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_create_profile", ["path"] = path })); Assert.IsTrue(result.Value("success"), result.ToString()); string fullPath = result["data"]["path"].ToString(); Assert.IsTrue(fullPath.EndsWith(".asset")); Assert.IsNotNull(AssetDatabase.LoadAssetAtPath(fullPath)); } // ===================================================================== // Bake Actions // ===================================================================== [Test] public void BakeGetSettings_ReturnsLightmapperInfo() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bake_get_settings" })); Assert.IsTrue(result.Value("success"), result.ToString()); var data = result["data"]; Assert.IsNotNull(data["lightmapper"]); Assert.IsNotNull(data["lightmapResolution"]); } [Test] public void BakeSetSettings_ChangesAndRestores() { // Read original var original = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bake_get_settings" })); int origResolution = original["data"]["lightmapResolution"].Value(); // Change var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_set_settings", ["settings"] = new JObject { ["lightmapResolution"] = 20 } })); Assert.IsTrue(result.Value("success"), result.ToString()); var changed = result["data"]["changed"] as JArray; Assert.That(changed.Select(t => t.ToString()), Contains.Item("lightmapResolution")); // Verify var verify = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bake_get_settings" })); Assert.AreEqual(20, verify["data"]["lightmapResolution"].Value()); // Restore ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_set_settings", ["settings"] = new JObject { ["lightmapResolution"] = origResolution } }); } [Test] public void BakeStatus_ReportsNotRunning() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bake_status" })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsNotNull(result["data"]["isRunning"]); } [Test] public void BakeClear_Succeeds() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "bake_clear" })); Assert.IsTrue(result.Value("success"), result.ToString()); } [Test] public void BakeCreateReflectionProbe_CreatesProbe() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_create_reflection_probe", ["name"] = "GfxTest_ReflProbe", ["position"] = new JArray(0, 1, 0), ["size"] = new JArray(10, 10, 10), ["resolution"] = 128 })); Assert.IsTrue(result.Value("success"), result.ToString()); var go = GameObject.Find("GfxTest_ReflProbe"); Assert.IsNotNull(go); Assert.IsNotNull(go.GetComponent()); } [Test] public void BakeCreateLightProbeGroup_CreatesGrid() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_create_light_probe_group", ["name"] = "GfxTest_LPGroup", ["position"] = new JArray(0, 0, 0), ["grid_size"] = new JArray(2, 2, 2), ["spacing"] = 2 })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.AreEqual(8, result["data"]["probeCount"].Value()); var go = GameObject.Find("GfxTest_LPGroup"); Assert.IsNotNull(go); Assert.IsNotNull(go.GetComponent()); } [Test] public void BakeSetProbePositions_SetsPositions() { ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_create_light_probe_group", ["name"] = "GfxTest_LPPos", ["grid_size"] = new JArray(1, 1, 1) }); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_set_probe_positions", ["target"] = "GfxTest_LPPos", ["positions"] = new JArray { new JArray(0, 0, 0), new JArray(1, 0, 0), new JArray(0, 1, 0) } })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.AreEqual(3, result["data"]["probeCount"].Value()); } [Test] public void BakeSetProbePositions_WrongComponent_ReturnsError() { var go = new GameObject("GfxTest_NoProbe"); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "bake_set_probe_positions", ["target"] = "GfxTest_NoProbe", ["positions"] = new JArray { new JArray(0, 0, 0) } })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("LightProbeGroup")); } // ===================================================================== // Stats Actions // ===================================================================== [Test] public void StatsGet_ReturnsCounters() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "stats_get" })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsNotNull(result["data"]["draw_calls"]); Assert.IsNotNull(result["data"]["batches"]); Assert.IsNotNull(result["data"]["triangles"]); } [Test] public void StatsListCounters_ReturnsList() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "stats_list_counters" })); Assert.IsTrue(result.Value("success"), result.ToString()); var counters = result["data"]["counters"] as JArray; Assert.IsNotNull(counters); Assert.Greater(counters.Count, 0); } [Test] public void StatsGetMemory_ReturnsMemoryInfo() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "stats_get_memory" })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsNotNull(result["data"]["totalAllocatedMB"]); Assert.IsNotNull(result["data"]["graphicsDriverMB"]); } [Test] public void StatsSetSceneDebug_ValidMode_Succeeds() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "stats_set_scene_debug", ["mode"] = "Wireframe" })); if (_hasSceneView) Assert.IsTrue(result.Value("success"), result.ToString()); else Assert.IsFalse(result.Value("success")); } [Test] public void StatsSetSceneDebug_InvalidMode_ReturnsError() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "stats_set_scene_debug", ["mode"] = "InvalidMode" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("Valid:")); } // ===================================================================== // Pipeline Actions // ===================================================================== [Test] public void PipelineGetInfo_ReturnsPipelineName() { var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "pipeline_get_info" })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsNotNull(result["data"]["pipelineName"]); Assert.IsNotNull(result["data"]["qualityLevelName"]); } [Test] public void PipelineGetSettings_ReturnsSettings() { Assume.That(_hasURP || _hasHDRP, "Built-in pipeline has no settings asset — skipping."); var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "pipeline_get_settings" })); Assert.IsTrue(result.Value("success"), result.ToString()); var settings = result["data"]["settings"]; Assert.IsNotNull(settings); Assert.IsNotNull(settings["renderScale"]); } [Test] public void PipelineSetQuality_InvalidLevel_ReturnsError() { var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "pipeline_set_quality", ["level"] = "NonExistentLevel" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("Available:")); } // ===================================================================== // Renderer Feature Actions (URP only) // ===================================================================== private void AssumeURP() { Assume.That(_hasURP, "URP not available — skipping."); } [Test] public void FeatureList_ReturnsFeatures() { AssumeURP(); var result = ToJObject(ManageGraphics.HandleCommand( new JObject { ["action"] = "feature_list" })); Assert.IsTrue(result.Value("success"), result.ToString()); Assert.IsNotNull(result["data"]["features"]); Assert.IsNotNull(result["data"]["rendererDataName"]); } [Test] public void FeatureAdd_InvalidType_ReturnsError() { AssumeURP(); var result = ToJObject(ManageGraphics.HandleCommand(new JObject { ["action"] = "feature_add", ["type"] = "NonExistentFeature" })); Assert.IsFalse(result.Value("success")); Assert.That(result["error"].ToString(), Does.Contain("not found")); Assert.That(result["error"].ToString(), Does.Contain("Available:")); } // ===================================================================== // Helpers // ===================================================================== private void CreateTestVolume(string name) { ManageGraphics.HandleCommand(new JObject { ["action"] = "volume_create", ["name"] = name }); } } }