using System.Net; using System.Text; using Omika.Core.Observability.Forwarding; using Omika.Core.Observability.Outbox; namespace Omika.Tests.Observability.Forwarding; /// Tests du client HTTP du forwarder (mapping de statuts, headers, jamais de levée). public class DiagnosticsForwarderClientTests { private static DiagnosticsForwarderClient NewClient(FakeHandler handler) => new(new HttpClient(handler), "https://diagnostics.example/api/v1/diagnostics/batches", TimeSpan.FromSeconds(5)); [Fact] public async Task SendAsync_2xx_ReturnsSuccess_WithAcceptedCount() { var handler = new FakeHandler(HttpStatusCode.OK, "{\"batchId\":\"00000000-0000-0000-0000-000000000000\",\"acceptedCount\":7}"); var client = NewClient(handler); DiagnosticsForwardResult result = await client.SendAsync(Batch(), "BATIK.01", "omkdiag_x"); Assert.Equal(DiagnosticsForwardOutcome.Success, result.Outcome); Assert.Equal(7, result.AcceptedCount); } [Fact] public async Task SendAsync_401_ReturnsUnauthorized() => await AssertOutcomeAsync(HttpStatusCode.Unauthorized, DiagnosticsForwardOutcome.Unauthorized); [Fact] public async Task SendAsync_403_ReturnsForbidden() => await AssertOutcomeAsync(HttpStatusCode.Forbidden, DiagnosticsForwardOutcome.Forbidden); [Fact] public async Task SendAsync_400_ReturnsRejected() => await AssertOutcomeAsync(HttpStatusCode.BadRequest, DiagnosticsForwardOutcome.Rejected); [Fact] public async Task SendAsync_503_ReturnsTransient() => await AssertOutcomeAsync(HttpStatusCode.ServiceUnavailable, DiagnosticsForwardOutcome.Transient); [Fact] public async Task SendAsync_SetsClientCodeAndKeyHeaders() { var handler = new FakeHandler(HttpStatusCode.OK, "{}"); var client = NewClient(handler); await client.SendAsync(Batch(), "BATIK.01", "omkdiag_secret_key"); Assert.Equal("BATIK.01", handler.LastRequest?.Headers.GetValues("X-Omika-Client-Code").FirstOrDefault()); Assert.Equal("omkdiag_secret_key", handler.LastRequest?.Headers.GetValues("X-Omika-Diagnostics-Key").FirstOrDefault()); } private static async Task AssertOutcomeAsync(HttpStatusCode status, DiagnosticsForwardOutcome expected) { var handler = new FakeHandler(status, "{}"); var client = NewClient(handler); DiagnosticsForwardResult result = await client.SendAsync(Batch(), "BATIK.01", "omkdiag_x"); Assert.Equal(expected, result.Outcome); } private static CentralDiagnosticBatchDto Batch() => new() { Events = [ForwardingTestHarness.NewRecord()] }; private sealed class FakeHandler : HttpMessageHandler { private readonly HttpStatusCode _status; private readonly string _body; public FakeHandler(HttpStatusCode status, string body) { _status = status; _body = body; } public HttpRequestMessage? LastRequest { get; private set; } protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { LastRequest = request; return Task.FromResult(new HttpResponseMessage(_status) { Content = new StringContent(_body, Encoding.UTF8, "application/json") }); } } }