using System.Text; using NATS.Server.Mqtt; namespace NATS.Server.Mqtt.Tests.Mqtt; public class MqttProtocolConstantsParityBatch2Tests { [Fact] public void Extended_constants_match_go_reference_values() { MqttProtocolConstants.MultiLevelSidSuffix.ShouldBe(" fwc"); MqttProtocolConstants.Prefix.ShouldBe("$MQTT."); MqttProtocolConstants.SubPrefix.ShouldBe("$MQTT.sub."); MqttProtocolConstants.StreamName.ShouldBe("$MQTT_msgs"); MqttProtocolConstants.StreamSubjectPrefix.ShouldBe("$MQTT.msgs."); MqttProtocolConstants.RetainedMsgsStreamName.ShouldBe("$MQTT_rmsgs"); MqttProtocolConstants.RetainedMsgsStreamSubject.ShouldBe("$MQTT.rmsgs."); MqttProtocolConstants.SessStreamName.ShouldBe("$MQTT_sess"); MqttProtocolConstants.SessStreamSubjectPrefix.ShouldBe("$MQTT.sess."); MqttProtocolConstants.SessionsStreamNamePrefix.ShouldBe("$MQTT_sess_"); MqttProtocolConstants.QoS2IncomingMsgsStreamName.ShouldBe("$MQTT_qos2in"); MqttProtocolConstants.QoS2IncomingMsgsStreamSubjectPrefix.ShouldBe("$MQTT.qos2.in."); MqttProtocolConstants.OutStreamName.ShouldBe("$MQTT_out"); MqttProtocolConstants.OutSubjectPrefix.ShouldBe("$MQTT.out."); MqttProtocolConstants.PubRelSubjectPrefix.ShouldBe("$MQTT.out.pubrel."); MqttProtocolConstants.PubRelDeliverySubjectPrefix.ShouldBe("$MQTT.deliver.pubrel."); MqttProtocolConstants.PubRelConsumerDurablePrefix.ShouldBe("$MQTT_PUBREL_"); MqttProtocolConstants.JSARepliesPrefix.ShouldBe("$MQTT.JSA."); MqttProtocolConstants.JSAIdTokenPos.ShouldBe(3); MqttProtocolConstants.JSATokenPos.ShouldBe(4); MqttProtocolConstants.JSAClientIDPos.ShouldBe(5); MqttProtocolConstants.JSAStreamCreate.ShouldBe("SC"); MqttProtocolConstants.JSAStreamUpdate.ShouldBe("SU"); MqttProtocolConstants.JSAStreamLookup.ShouldBe("SL"); MqttProtocolConstants.JSAStreamDel.ShouldBe("SD"); MqttProtocolConstants.JSAConsumerCreate.ShouldBe("CC"); MqttProtocolConstants.JSAConsumerLookup.ShouldBe("CL"); MqttProtocolConstants.JSAConsumerDel.ShouldBe("CD"); MqttProtocolConstants.JSAMsgStore.ShouldBe("MS"); MqttProtocolConstants.JSAMsgLoad.ShouldBe("ML"); MqttProtocolConstants.JSAMsgDelete.ShouldBe("MD"); MqttProtocolConstants.JSASessPersist.ShouldBe("SP"); MqttProtocolConstants.JSARetainedMsgDel.ShouldBe("RD"); MqttProtocolConstants.JSAStreamNames.ShouldBe("SN"); MqttProtocolConstants.SparkbNBirth.ShouldBe("NBIRTH"); MqttProtocolConstants.SparkbDBirth.ShouldBe("DBIRTH"); MqttProtocolConstants.SparkbNDeath.ShouldBe("NDEATH"); MqttProtocolConstants.SparkbDDeath.ShouldBe("DDEATH"); Encoding.ASCII.GetString(MqttProtocolConstants.SparkbNamespaceTopicPrefix).ShouldBe("spBv1.0/"); Encoding.ASCII.GetString(MqttProtocolConstants.SparkbCertificatesTopicPrefix).ShouldBe("$sparkplug/certificates/"); MqttProtocolConstants.NatsHeaderPublish.ShouldBe("Nmqtt-Pub"); MqttProtocolConstants.NatsRetainedMessageTopic.ShouldBe("Nmqtt-RTopic"); MqttProtocolConstants.NatsRetainedMessageOrigin.ShouldBe("Nmqtt-ROrigin"); MqttProtocolConstants.NatsRetainedMessageFlags.ShouldBe("Nmqtt-RFlags"); MqttProtocolConstants.NatsRetainedMessageSource.ShouldBe("Nmqtt-RSource"); MqttProtocolConstants.NatsPubRelHeader.ShouldBe("Nmqtt-PubRel"); MqttProtocolConstants.NatsHeaderSubject.ShouldBe("Nmqtt-Subject"); MqttProtocolConstants.NatsHeaderMapped.ShouldBe("Nmqtt-Mapped"); } [Fact] public void WriteString_writes_length_prefixed_utf8() { var encoded = MqttPacketWriter.WriteString("MQTT"); encoded.Length.ShouldBe(6); encoded[0].ShouldBe((byte)0x00); encoded[1].ShouldBe((byte)0x04); Encoding.UTF8.GetString(encoded.AsSpan(2)).ShouldBe("MQTT"); } [Fact] public void WriteBytes_writes_length_prefixed_binary_payload() { var encoded = MqttPacketWriter.WriteBytes(new byte[] { 0xAA, 0xBB, 0xCC }); encoded.ShouldBe(new byte[] { 0x00, 0x03, 0xAA, 0xBB, 0xCC }); } [Fact] public void WriteBytes_rejects_payload_larger_than_uint16() { var payload = new byte[ushort.MaxValue + 1]; Should.Throw(() => MqttPacketWriter.WriteBytes(payload)); } }