using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
namespace NavisworksTransport.UnitTests.Integration
{
///
/// 路径编辑集成测试(覆盖计划 T11)。
///
/// 验证 PathPlanningManager 编辑链路:
/// - 删除路径点(remove-point:点数递减)
/// - 更新路径点位置(update-point:坐标更新)
/// - 正交化(orthogonalize)
/// - 去除矩形环(remove-loops)
///
/// 使用独立导入的临时路径,避免影响标准测试路径。
///
[TestClass]
[TestCategory("NavisworksIntegration")]
public class PathEditingAutomationTests
{
private const string RouteName = "路径编辑_测试";
[TestMethod]
[Timeout(120000)]
public async Task EditRoute_RemoveUpdateOrthogonalize_Work()
{
using (var client = new NavisworksTestAutomationClient())
{
await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);
string tempDir = Path.Combine(Path.GetTempPath(), "NavisworksTransportIntegrationTests", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);
try
{
// 1. 导入 3 点测试路径
string filePath = Path.Combine(tempDir, "edit-route.json");
File.WriteAllText(filePath, BuildEditRouteJson(), new UTF8Encoding(false));
JObject importResponse = await client.ImportRouteFileAsync(filePath, overwrite: true).ConfigureAwait(false);
Assert.IsTrue(importResponse.Value("ok"), "导入编辑路径失败: " + (string)importResponse["error"]);
Assert.AreEqual(3, (int)((JArray)importResponse["data"]["routes"])[0]["pointCount"], "初始点数应为 3");
// 2. 删除中间点(index=1)
JObject removeResponse = await client.EditRouteAsync("remove-point", RouteName, pointIndex: 1).ConfigureAwait(false);
Assert.IsTrue(removeResponse.Value("ok"), "删除路径点失败: " + (string)removeResponse["error"]);
Assert.AreEqual(2, (int)removeResponse["data"]["pointCount"], "删除后点数应为 2");
// 3. 更新起点位置
JObject updateResponse = await client.EditRouteAsync(
"update-point", RouteName,
pointIndex: 0, x: -204.608, y: 14.833, z: 20.0).ConfigureAwait(false);
Assert.IsTrue(updateResponse.Value("ok"), "更新路径点失败: " + (string)updateResponse["error"]);
JArray updatedPoints = (JArray)updateResponse["data"]["points"];
JObject updatedStart = (JObject)updatedPoints[0]["position"];
Assert.AreEqual(20.0, (double)updatedStart["z"], 1e-2, "更新后的 Z 坐标不匹配");
// 4. 正交化
JObject orthogonalizeResponse = await client.EditRouteAsync("orthogonalize", RouteName).ConfigureAwait(false);
Assert.IsTrue(orthogonalizeResponse.Value("ok"), "正交化失败: " + (string)orthogonalizeResponse["error"]);
Assert.IsTrue((int)orthogonalizeResponse["data"]["pointCount"] >= 2, "正交化后点数应 >= 2");
// 5. 去除矩形环
JObject removeLoopsResponse = await client.EditRouteAsync("remove-loops", RouteName).ConfigureAwait(false);
Assert.IsTrue(removeLoopsResponse.Value("ok"), "去除矩形环失败: " + (string)removeLoopsResponse["error"]);
}
finally
{
SafeDelete(tempDir);
}
}
}
private static string BuildEditRouteJson()
{
return string.Format(
System.Globalization.CultureInfo.InvariantCulture,
@"{{""PathPlanningData"":{{""version"":""1.0"",""generator"":""integration-test"",""timestamp"":""2026-08-04T21:30:00"",""ProjectInfo"":{{""name"":""test"",""description"":""test"",""units"":""meters"",""coordinateSystem"":""Global""}},""Routes"":[{{""id"":""edit-route-{0}"",""name"":""{1}"",""description"":"""",""pathType"":""Ground"",""totalLength"":20.0,""objectLimits"":{{""maxLength"":0,""maxWidth"":0,""maxHeight"":0,""safetyMargin"":0}},""gridSize"":1.0,""liftHeight"":0.0,""created"":""2026-08-04T21:30:00"",""points"":[{{""id"":""er-p1"",""name"":""start"",""type"":""StartPoint"",""index"":0,""x"":-204.608,""y"":14.833,""z"":19.250,""created"":""2026-08-04T21:30:00""}},{{""id"":""er-p2"",""name"":""mid"",""type"":""WayPoint"",""index"":1,""x"":-206.608,""y"":14.833,""z"":18.250,""created"":""2026-08-04T21:30:00""}},{{""id"":""er-p3"",""name"":""end"",""type"":""EndPoint"",""index"":2,""x"":-208.608,""y"":14.833,""z"":17.250,""created"":""2026-08-04T21:30:00""}}]}}]}}}}",
Guid.NewGuid().ToString("N"),
RouteName);
}
private static void SafeDelete(string directory)
{
if (!Directory.Exists(directory))
{
return;
}
try
{
Directory.Delete(directory, true);
}
catch
{
}
}
}
}