using SuiteLink.Client.Protocol; namespace SuiteLink.Client.Tests.Protocol; public sealed class SuiteLinkFrameReaderTests { [Fact] public void ParseFrame_WithValidFrame_ParsesMessageTypeAndPayload() { var bytes = new byte[] { 0x05, 0x00, 0x00, 0x09, 0x01, 0x02, 0xA5 }; var frame = SuiteLinkFrameReader.ParseFrame(bytes); Assert.Equal((ushort)0x0900, frame.MessageType); Assert.Equal(new byte[] { 0x01, 0x02 }, frame.Payload.ToArray()); Assert.Equal((ushort)5, frame.RemainingLength); } [Fact] public void ParseFrame_WithInvalidMarker_ThrowsFormatException() { var bytes = new byte[] { 0x03, 0x00, 0x40, 0x24, 0x00 }; var exception = Assert.Throws(() => SuiteLinkFrameReader.ParseFrame(bytes)); Assert.Contains("marker", exception.Message, StringComparison.OrdinalIgnoreCase); } [Fact] public void ParseFrame_WithTooShortInput_ThrowsFormatException() { var bytes = new byte[] { 0x03, 0x00, 0x40, 0x24 }; Assert.Throws(() => SuiteLinkFrameReader.ParseFrame(bytes)); } [Fact] public void ParseFrame_WithRemainingLengthBelowMinimum_ThrowsFormatException() { var bytes = new byte[] { 0x02, 0x00, 0x40, 0x24 }; Assert.Throws(() => SuiteLinkFrameReader.ParseFrame(bytes)); } [Fact] public void ParseFrame_WithTruncatedInput_ThrowsFormatException() { var bytes = new byte[] { 0x05, 0x00, 0x40, 0x24, 0x01, 0xA5 }; Assert.Throws(() => SuiteLinkFrameReader.ParseFrame(bytes)); } [Fact] public void TryParseFrame_WithExtraBytes_ReturnsFrameAndConsumedLength() { var bytes = new byte[] { 0x03, 0x00, 0x40, 0x24, 0xA5, 0xFF, 0xEE }; var parsed = SuiteLinkFrameReader.TryParseFrame(bytes, out var frame, out var consumed); Assert.True(parsed); Assert.Equal(5, consumed); Assert.Equal((ushort)0x2440, frame.MessageType); Assert.True(frame.Payload.IsEmpty); } [Fact] public void ParseFrame_WithExtraBytes_ThrowsFormatException() { var bytes = new byte[] { 0x03, 0x00, 0x40, 0x24, 0xA5, 0xFF }; Assert.Throws(() => SuiteLinkFrameReader.ParseFrame(bytes)); } [Fact] public void TryParseFrame_WithIncompleteBuffer_ReturnsFalse() { var bytes = new byte[] { 0x05, 0x00, 0x00, 0x09, 0x01 }; var parsed = SuiteLinkFrameReader.TryParseFrame(bytes, out _, out var consumed); Assert.False(parsed); Assert.Equal(0, consumed); } }