using System.Text; using NATS.Server.Gateways; using Shouldly; namespace NATS.Server.Tests.Gateways; // Go reference: gateway.go:90-120 — gateway protocol constants and command formatting. public class GatewayCommandTests { [Fact] public void FormatSub_produces_correct_wire_format() { // Go reference: gateway.go — RS+ propagation, sendGatewaySubsToGateway var bytes = GatewayCommands.FormatSub("$G", "orders.>"); var line = Encoding.UTF8.GetString(bytes); line.ShouldBe("GS+ $G orders.>\r\n"); } [Fact] public void FormatUnsub_produces_correct_wire_format() { // Go reference: gateway.go — RS- propagation, sendGatewayUnsubToGateway var bytes = GatewayCommands.FormatUnsub("$G", "orders.>"); var line = Encoding.UTF8.GetString(bytes); line.ShouldBe("GS- $G orders.>\r\n"); } [Fact] public void FormatMode_optimistic_produces_O() { // Go reference: gateway.go — GMODE command, "O" = Optimistic mode var bytes = GatewayCommands.FormatMode("$G", GatewayInterestMode.Optimistic); var line = Encoding.UTF8.GetString(bytes); line.ShouldBe("GMODE $G O\r\n"); } [Fact] public void FormatMode_interest_only_produces_I() { // Go reference: gateway.go — GMODE command, "I" = InterestOnly mode var bytes = GatewayCommands.FormatMode("$G", GatewayInterestMode.InterestOnly); var line = Encoding.UTF8.GetString(bytes); line.ShouldBe("GMODE $G I\r\n"); } [Fact] public void ParseCommandType_identifies_sub() { // Go reference: gateway.go — processGatewayMsg dispatch on GS+ var line = Encoding.UTF8.GetBytes("GS+ ACC foo.bar\r\n"); var result = GatewayCommands.ParseCommandType(line); result.ShouldBe(GatewayCommandType.Sub); } [Fact] public void ParseCommandType_identifies_unsub() { // Go reference: gateway.go — processGatewayMsg dispatch on GS- var line = Encoding.UTF8.GetBytes("GS- ACC foo.bar\r\n"); var result = GatewayCommands.ParseCommandType(line); result.ShouldBe(GatewayCommandType.Unsub); } [Fact] public void ParseCommandType_identifies_ping() { // Go reference: gateway.go — keepalive GPING command var result = GatewayCommands.ParseCommandType(GatewayCommands.Ping); result.ShouldBe(GatewayCommandType.Ping); } [Fact] public void ParseCommandType_identifies_pong() { // Go reference: gateway.go — keepalive GPONG response var result = GatewayCommands.ParseCommandType(GatewayCommands.Pong); result.ShouldBe(GatewayCommandType.Pong); } [Fact] public void ParseCommandType_returns_null_for_unknown() { // Unrecognized commands should return null for graceful handling var line = Encoding.UTF8.GetBytes("UNKNOWN something\r\n"); var result = GatewayCommands.ParseCommandType(line); result.ShouldBeNull(); } [Fact] public void Wire_format_constants_end_correctly() { // Go reference: gateway.go — all gateway commands use CRLF line endings var crlf = new byte[] { (byte)'\r', (byte)'\n' }; GatewayCommands.Ping.TakeLast(2).ShouldBe(crlf); GatewayCommands.Pong.TakeLast(2).ShouldBe(crlf); GatewayCommands.Crlf.ShouldBe(crlf); } }