using NATS.Client.Core; using NATS.E2E.Tests.Infrastructure; namespace NATS.E2E.Tests; [Collection("E2E")] public class HeaderTests(NatsServerFixture fixture) { [Fact] public async Task Headers_PublishWithHeaders_ReceivedIntact() { await using var pub = fixture.CreateClient(); await using var sub = fixture.CreateClient(); await pub.ConnectAsync(); await sub.ConnectAsync(); await using var subscription = await sub.SubscribeCoreAsync("e2e.hdr.basic"); await sub.PingAsync(); var headers = new NatsHeaders { { "X-Test-Key", "test-value" } }; await pub.PublishAsync("e2e.hdr.basic", "with-headers", headers: headers); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var msg = await subscription.Msgs.ReadAsync(cts.Token); msg.Data.ShouldBe("with-headers"); msg.Headers.ShouldNotBeNull(); msg.Headers!["X-Test-Key"].ToString().ShouldBe("test-value"); } [Fact] public async Task Headers_MultipleHeaders_AllPreserved() { await using var pub = fixture.CreateClient(); await using var sub = fixture.CreateClient(); await pub.ConnectAsync(); await sub.ConnectAsync(); await using var subscription = await sub.SubscribeCoreAsync("e2e.hdr.multi"); await sub.PingAsync(); var headers = new NatsHeaders { { "X-First", "one" }, { "X-Second", "two" }, { "X-Third", "three" }, }; await pub.PublishAsync("e2e.hdr.multi", "multi-hdr", headers: headers); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var msg = await subscription.Msgs.ReadAsync(cts.Token); msg.Headers.ShouldNotBeNull(); msg.Headers!["X-First"].ToString().ShouldBe("one"); msg.Headers!["X-Second"].ToString().ShouldBe("two"); msg.Headers!["X-Third"].ToString().ShouldBe("three"); } [Fact] public async Task Headers_EmptyValue_RoundTrips() { await using var pub = fixture.CreateClient(); await using var sub = fixture.CreateClient(); await pub.ConnectAsync(); await sub.ConnectAsync(); await using var subscription = await sub.SubscribeCoreAsync("e2e.hdr.empty"); await sub.PingAsync(); var headers = new NatsHeaders { { "X-Empty", "" } }; await pub.PublishAsync("e2e.hdr.empty", "empty-val", headers: headers); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var msg = await subscription.Msgs.ReadAsync(cts.Token); msg.Headers.ShouldNotBeNull(); msg.Headers!.ContainsKey("X-Empty").ShouldBeTrue(); msg.Headers!["X-Empty"].ToString().ShouldBe(""); } }