feat: bootstrap suitelink tag client codecs

This commit is contained in:
Joseph Doherty
2026-03-16 14:43:31 -04:00
commit 731bfe2237
30 changed files with 3429 additions and 0 deletions

View File

@@ -0,0 +1,159 @@
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);
}
}