using System.Net; using System.Net.Http; using System.Text; using Microsoft.Extensions.Caching.Memory; using Moq; using Xunit; using JobTrackerApi.Services; namespace JobTrackerApi.Tests; public sealed class SummarizerServiceTests { [Fact] public async Task Summarize_section_clamps_lengths_to_ai_service_limits() { var handler = new CapturingHandler(); var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost:8001") }; var httpFactory = new Mock(); httpFactory.Setup(x => x.CreateClient("ai-service")).Returns(httpClient); using var memoryCache = new MemoryCache(new MemoryCacheOptions()); var service = new SummarizerService(httpFactory.Object, memoryCache); var result = await service.SummarizeSectionAsync("Rewrite this CV", "Professional Summary\nBuilt backend systems.", 1800, 400); Assert.Equal("ok", result); Assert.NotNull(handler.LastBody); Assert.Contains("\"max_length\":256", handler.LastBody); Assert.Contains("\"min_length\":180", handler.LastBody); } private sealed class CapturingHandler : HttpMessageHandler { public string? LastBody { get; private set; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { LastBody = request.Content is null ? null : await request.Content.ReadAsStringAsync(cancellationToken); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{\"summary\":\"ok\"}", Encoding.UTF8, "application/json") }; } } }