diff --git a/tests/NATS.E2E.Tests/HeaderTests.cs b/tests/NATS.E2E.Tests/HeaderTests.cs new file mode 100644 index 0000000..7e29fd3 --- /dev/null +++ b/tests/NATS.E2E.Tests/HeaderTests.cs @@ -0,0 +1,80 @@ +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(""); + } +}