using System; using System.Globalization; using System.Net.Http; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; namespace NavisworksTransport.UnitTests.Integration { internal sealed class NavisworksTestAutomationClient : IDisposable { private readonly HttpClient _httpClient; public NavisworksTestAutomationClient() { _httpClient = new HttpClient { BaseAddress = new Uri("http://127.0.0.1:18777"), Timeout = TimeSpan.FromSeconds(20) }; } public async Task EnsureServiceReadyAsync(TimeSpan timeout) { DateTime deadlineUtc = DateTime.UtcNow.Add(timeout); Exception lastError = null; while (DateTime.UtcNow < deadlineUtc) { try { JObject pingResponse = await GetJsonAsync("/api/test/ping").ConfigureAwait(false); if (pingResponse.Value("ok") == true) { return; } } catch (Exception ex) { lastError = ex; } await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); } Assert.Fail( "Navisworks 测试服务未就绪。请先用 start-navisworks.bat 启动 Navisworks,并确保插件面板已加载。最后错误: {0}", lastError?.Message ?? "unknown"); } public async Task RunVirtualCollisionTestAsync(string pathType, int timeoutSeconds) { string requestUri = string.Format( "/api/test/run-virtual-collision-test?pathType={0}&timeoutSeconds={1}", Uri.EscapeDataString(pathType), timeoutSeconds); return await PostJsonAsync(requestUri).ConfigureAwait(false); } public async Task AnalyzeAutoPathGridAsync(string pathType) { string requestUri = string.Format( "/api/test/analyze-auto-path-grid?pathType={0}", Uri.EscapeDataString(pathType)); return await PostJsonAsync(requestUri).ConfigureAwait(false); } public async Task RunAutoPathAsync( string pathType, string routeName, double objectLengthInMeters, double objectWidthInMeters, double safetyMarginInMeters, double gridSizeInMeters) { string requestUri = string.Format( CultureInfo.InvariantCulture, "/api/test/run-auto-path?pathType={0}&routeName={1}&objectLengthInMeters={2}&objectWidthInMeters={3}&safetyMarginInMeters={4}&gridSizeInMeters={5}", Uri.EscapeDataString(pathType), Uri.EscapeDataString(routeName), objectLengthInMeters, objectWidthInMeters, safetyMarginInMeters, gridSizeInMeters); return await PostJsonAsync(requestUri).ConfigureAwait(false); } private async Task GetJsonAsync(string requestUri) { using (HttpResponseMessage response = await _httpClient.GetAsync(requestUri).ConfigureAwait(false)) { string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); response.EnsureSuccessStatusCode(); return JObject.Parse(content); } } private async Task PostJsonAsync(string requestUri) { using (HttpResponseMessage response = await _httpClient.PostAsync(requestUri, new StringContent(string.Empty)).ConfigureAwait(false)) { string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); response.EnsureSuccessStatusCode(); return JObject.Parse(content); } } public void Dispose() { _httpClient.Dispose(); } } }