using System.Net; using Health.Infrastructure.AI; using Microsoft.Extensions.Configuration; namespace Health.Tests; public sealed class AiClientErrorTests { [Fact] public async Task DeepSeek_ErrorResponse_IncludesStatusAndBody() { var client = CreateClient(HttpStatusCode.TooManyRequests, "{\"error\":\"rate limit\"}"); var error = await Assert.ThrowsAsync(() => client.ChatAsync([])); Assert.Contains("429", error.Message); Assert.Contains("rate limit", error.Message); } [Fact] public async Task DeepSeek_NullJsonResponse_ThrowsClearDataError() { var client = CreateClient(HttpStatusCode.OK, "null"); var error = await Assert.ThrowsAsync(() => client.ChatAsync([])); Assert.Contains("响应内容为空", error.Message); } private static DeepSeekClient CreateClient(HttpStatusCode statusCode, string body) { var http = new HttpClient(new StubHandler(statusCode, body)) { BaseAddress = new Uri("https://example.test/"), }; var config = new ConfigurationBuilder().AddInMemoryCollection( new Dictionary { ["DEEPSEEK_MODEL"] = "test-model" }).Build(); return new DeepSeekClient(http, config); } private sealed class StubHandler(HttpStatusCode statusCode, string body) : HttpMessageHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => Task.FromResult(new HttpResponseMessage(statusCode) { Content = new StringContent(body), RequestMessage = request, }); } }