using System.Text; using SuiteLink.Client.Protocol; namespace SuiteLink.Client.Tests.Protocol; public sealed class SuiteLinkUpdateCodecTests { [Fact] public void DecodeUpdate_DecodesBinaryValue() { byte[] frame = [ 0x0D, 0x00, 0x09, 0x00, 0x34, 0x12, 0x00, 0x00, 0x0A, 0x00, 0xC0, 0x00, 0x01, 0x01, 0xA5 ]; Assert.Equal(0x09, frame[2]); Assert.Equal(0x00, frame[3]); var update = SuiteLinkUpdateCodec.Decode(frame); Assert.Equal(0x1234u, update.TagId); Assert.Equal(0x00C0, update.Quality); Assert.Equal(10, update.ElapsedMilliseconds); Assert.True(update.Value.TryGetBoolean(out var value)); Assert.True(value); } [Fact] public void DecodeUpdate_DecodesIntegerValue() { byte[] frame = [ 0x10, 0x00, 0x09, 0x00, 0x78, 0x56, 0x34, 0x12, 0x01, 0x00, 0xC0, 0x00, 0x02, 0x2A, 0x00, 0x00, 0x00, 0xA5 ]; var update = SuiteLinkUpdateCodec.Decode(frame); Assert.Equal(0x12345678u, update.TagId); Assert.True(update.Value.TryGetInt32(out var value)); Assert.Equal(42, value); } [Fact] public void DecodeUpdate_DecodesRealValue() { byte[] frame = [ 0x10, 0x00, 0x09, 0x00, 0x34, 0x12, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x48, 0x41, 0xA5 ]; var update = SuiteLinkUpdateCodec.Decode(frame); Assert.True(update.Value.TryGetFloat32(out var value)); Assert.Equal(12.5f, value); } [Fact] public void DecodeUpdate_DecodesMessageValue() { byte[] frame = [ 0x10, 0x00, 0x09, 0x00, 0x22, 0x22, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x00, 0x04, 0x02, 0x00, 0x4F, 0x4B, 0xA5 ]; var update = SuiteLinkUpdateCodec.Decode(frame); Assert.True(update.Value.TryGetString(out var value)); Assert.Equal("OK", value); } [Fact] public void DecodeUpdateMany_ParsesTwoItemsFromSingleFrame() { byte[] frame = [ 0x1A, 0x00, 0x09, 0x00, 0x11, 0x11, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x01, 0x01, 0x22, 0x22, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x00, 0x02, 0x2A, 0x00, 0x00, 0x00, 0xA5 ]; var updates = SuiteLinkUpdateCodec.DecodeMany(frame); Assert.Equal(2, updates.Count); Assert.Equal(0x1111u, updates[0].TagId); Assert.True(updates[0].Value.TryGetBoolean(out var boolValue)); Assert.True(boolValue); Assert.Equal(0x2222u, updates[1].TagId); Assert.True(updates[1].Value.TryGetInt32(out var intValue)); Assert.Equal(42, intValue); } [Fact] public void DecodeUpdate_WithDefaultMessageEncoding_UsesLatin1LosslessMapping() { byte[] frame = [ 0x0F, 0x00, 0x09, 0x00, 0x33, 0x33, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x04, 0x01, 0x00, 0xE9, 0xA5 ]; var update = SuiteLinkUpdateCodec.Decode(frame); Assert.True(update.Value.TryGetString(out var value)); Assert.Equal("\u00E9", value); } [Fact] public void DecodeUpdate_WithExplicitUtf8MessageEncoding_UsesProvidedEncoding() { byte[] frame = [ 0x10, 0x00, 0x09, 0x00, 0x44, 0x44, 0x00, 0x00, 0x01, 0x00, 0xC0, 0x00, 0x04, 0x02, 0x00, 0xC3, 0xA9, 0xA5 ]; var update = SuiteLinkUpdateCodec.Decode(frame, Encoding.UTF8); Assert.True(update.Value.TryGetString(out var value)); Assert.Equal("\u00E9", value); } }