NavisworksTransport/UnitTests/Integration/PathEditingAutomationTests.cs
tian 8e5d9e845f feat: 集成测试补 T11-T15(P0+P1+P2 全部完成,24/24 通过)
- T11 路径编辑(PathEditingAutomationTests):删除点/更新位置/正交化/去环
- T12 路径导出(ExportImportRoundTripAutomationTests):XML/JSON 导出→导入回环
- T13 播放控制(AnimationPlaybackControlAutomationTests):pause 验证帧停止/resume 前进
- T14 批量队列(BatchQueueAutomationTests):队列添加/计数递增
- T15 路径分析(PathAnalysisAutomationTests):评分结构验证
- 服务端新增 5 端点:export-route-file/edit-route/animation-playback-control/batch-queue-add/analyze-path
- 产品 bug 修复:PathDatabase.CollisionResults 表已废弃→GetCollisionCount 改查 CollisionReports、
  SaveCollisions 异常保护;路径编辑真删点走 PathRoute.RemovePoint(RemovePathPoint 仅 3D 标记)

验证:集成测试 24/24 通过,完整集 74.6s(15fps/5s 动画)
2026-08-04 18:39:16 +08:00

102 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 路径编辑集成测试(覆盖计划 T11
///
/// 验证 PathPlanningManager 编辑链路:
/// - 删除路径点remove-point点数递减
/// - 更新路径点位置update-point坐标更新
/// - 正交化orthogonalize
/// - 去除矩形环remove-loops
///
/// 使用独立导入的临时路径,避免影响标准测试路径。
/// </summary>
[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<bool>("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<bool>("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<bool>("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<bool>("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<bool>("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
{
}
}
}
}