diff --git a/SVSim.UnitTests/BattleNode/Integration/CaptureConformanceTests.cs b/SVSim.UnitTests/BattleNode/Integration/CaptureConformanceTests.cs index 92c3fe5..ad3d8c2 100644 --- a/SVSim.UnitTests/BattleNode/Integration/CaptureConformanceTests.cs +++ b/SVSim.UnitTests/BattleNode/Integration/CaptureConformanceTests.cs @@ -353,6 +353,48 @@ public class CaptureConformanceTests Assert.That(ourEntry.GetProperty("to").GetInt32(), Is.EqualTo(20)); } + [Test] + public void RelayedUList_matches_prod_recv_uList_shape() + { + // Prod recv PlayActions uList entry (battle-traffic_tk2_regular.ndjson:75) — a deck-fetch the + // official node relayed to the opponent. We forward it verbatim; assert the always-present keys + // round-trip with matching value-kinds (capture ⊆ ours). + const string prodEntry = """ + { "idxList": [16, 22], "from": 0, "to": 10, "isSelf": 1, "skill": "37|36|0" } + """; + + var uListRaw = new List + { + new Dictionary + { + ["idxList"] = new List { 16L, 22L }, + ["from"] = 0L, ["to"] = 10L, ["isSelf"] = 1L, ["skill"] = "37|36|0", + }, + }; + var relayed = SVSim.BattleNode.Sessions.Dispatch.KnownListBuilder.RelayUList(uListRaw); + Assert.That(relayed, Is.Not.Null); + + var body = new SVSim.BattleNode.Protocol.Bodies.PlayActionsBroadcastBody( + PlayIdx: 37, Type: 30, KnownList: null, OppoTargetList: null, UList: relayed); + var env = new MsgEnvelope(NetworkBattleUri.PlayActions, ViewerId: 1, Uuid: "u", Bid: null, Try: 0, + Cat: EmitCategory.Battle, PubSeq: null, PlaySeq: null, Body: body); + + using var ourDoc = JsonDocument.Parse(MsgEnvelope.ToJson(env)); + var ourEntry = ourDoc.RootElement.GetProperty("uList")[0]; + using var prodDoc = JsonDocument.Parse(prodEntry); + + foreach (var key in new[] { "idxList", "from", "to", "isSelf", "skill" }) + { + Assert.That(ourEntry.TryGetProperty(key, out var ours), Is.True, $"uList entry missing '{key}'"); + var prodVal = prodDoc.RootElement.GetProperty(key); + Assert.That(ours.ValueKind, Is.EqualTo(prodVal.ValueKind), $"'{key}' type category mismatch"); + } + Assert.That(ourEntry.GetProperty("idxList").GetArrayLength(), Is.EqualTo(2)); + Assert.That(ourEntry.GetProperty("skill").GetString(), Is.EqualTo("37|36|0")); + // No cardId on a hidden fetch — confirm we didn't invent one. + Assert.That(ourEntry.TryGetProperty("cardId", out _), Is.False, "hidden fetch carries no cardId"); + } + [Test] public void MineCopyTokens_extracts_the_prod_capture_copy_op_shape() {