test(battle-node): envelope-level wire-shape regression for scripted bodies
This commit is contained in:
134
SVSim.UnitTests/BattleNode/Lifecycle/TypedBodyWireShapeTests.cs
Normal file
134
SVSim.UnitTests/BattleNode/Lifecycle/TypedBodyWireShapeTests.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using NUnit.Framework;
|
||||
using SVSim.BattleNode.Lifecycle;
|
||||
using SVSim.BattleNode.Protocol;
|
||||
|
||||
namespace SVSim.UnitTests.BattleNode.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// Wire-shape regression tests: compare <see cref="MsgEnvelope.ToJson"/> output against
|
||||
/// JSON literals derived from captured prod frames in
|
||||
/// data_dumps/captures/battle-traffic_tk2_regular.ndjson. Per the feedback_wire_shape_tests
|
||||
/// memory, these are literal-comparison tests — NOT self-symmetric round-trips — so they
|
||||
/// catch the failure mode where a C# property is renamed and silently breaks the wire
|
||||
/// contract.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TypedBodyWireShapeTests
|
||||
{
|
||||
[Test]
|
||||
public void BuildMatched_SerializesAllWireKeysExpectedByTheClient()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildMatched(
|
||||
playerViewerId: 906243102, opponentViewerId: 847666884, battleId: "597830888107");
|
||||
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
// Top-level envelope fields:
|
||||
Assert.That(node["uri"]!.GetValue<string>(), Is.EqualTo("Matched"));
|
||||
Assert.That(node["viewerId"]!.GetValue<long>(), Is.EqualTo(999_999_999L));
|
||||
Assert.That(node["uuid"]!.GetValue<string>(), Is.EqualTo("node-stub"));
|
||||
Assert.That(node["bid"]!.GetValue<string>(), Is.EqualTo("597830888107"));
|
||||
Assert.That(node["try"]!.GetValue<int>(), Is.EqualTo(0));
|
||||
Assert.That(node["cat"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
Assert.That(node["resultCode"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
|
||||
// Inner selfInfo block has the wire keys the client's Parse looks up.
|
||||
var selfInfo = node["selfInfo"]!.AsObject();
|
||||
foreach (var key in new[] {
|
||||
"country_code", "userName", "sleeveId", "emblemId", "degreeId",
|
||||
"fieldId", "isOfficial", "oppoId", "seed",
|
||||
})
|
||||
{
|
||||
Assert.That(selfInfo.ContainsKey(key), Is.True, $"selfInfo missing wire key '{key}'");
|
||||
}
|
||||
Assert.That(selfInfo["oppoId"]!.GetValue<long>(), Is.EqualTo(847666884L));
|
||||
Assert.That(selfInfo.ContainsKey("oppoDeckCount"), Is.False, "selfInfo must NOT have oppoDeckCount");
|
||||
|
||||
var oppoInfo = node["oppoInfo"]!.AsObject();
|
||||
Assert.That(oppoInfo["oppoDeckCount"]!.GetValue<int>(), Is.EqualTo(30));
|
||||
Assert.That(oppoInfo["oppoId"]!.GetValue<long>(), Is.EqualTo(906243102L));
|
||||
|
||||
var selfDeck = node["selfDeck"]!.AsArray();
|
||||
Assert.That(selfDeck.Count, Is.EqualTo(30));
|
||||
Assert.That(selfDeck[0]!.AsObject()["idx"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
Assert.That(selfDeck[0]!.AsObject()["cardId"]!.GetValue<long>(), Is.EqualTo(100_011_010L));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildBattleStart_SerializesAllWireKeysAndPreservesBattlePointAsymmetry()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildBattleStart(playerViewerId: 906243102);
|
||||
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
Assert.That(node["turnState"]!.GetValue<int>(), Is.EqualTo(0));
|
||||
Assert.That(node["battleType"]!.GetValue<int>(), Is.EqualTo(11));
|
||||
Assert.That(node["resultCode"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
|
||||
var selfInfo = node["selfInfo"]!.AsObject();
|
||||
Assert.That(selfInfo["rank"]!.GetValue<string>(), Is.EqualTo("10"));
|
||||
Assert.That(selfInfo["battlePoint"]!.GetValue<string>(), Is.EqualTo("6270")); // string on self
|
||||
Assert.That(selfInfo["cardMasterName"]!.GetValue<string>(), Is.EqualTo("card_master_node_10015"));
|
||||
|
||||
var oppoInfo = node["oppoInfo"]!.AsObject();
|
||||
Assert.That(oppoInfo["battlePoint"]!.GetValue<int>(), Is.EqualTo(0)); // int on oppo
|
||||
Assert.That(oppoInfo["isMasterRank"]!.GetValue<string>(), Is.EqualTo("0"));
|
||||
Assert.That(oppoInfo["masterPoint"]!.GetValue<string>(), Is.EqualTo("0"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildDeal_SerializesSelfAndOppoArraysWithPosIdxShape()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildDeal();
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
var self = node["self"]!.AsArray();
|
||||
Assert.That(self.Count, Is.EqualTo(3));
|
||||
Assert.That(self[0]!.AsObject()["pos"]!.GetValue<int>(), Is.EqualTo(0));
|
||||
Assert.That(self[0]!.AsObject()["idx"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
|
||||
var oppo = node["oppo"]!.AsArray();
|
||||
Assert.That(oppo.Count, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildSwapResponse_SerializesSelfWithoutOppo()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildSwapResponse(new long[] { 1, 4, 3 });
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
Assert.That(node.ContainsKey("self"), Is.True);
|
||||
Assert.That(node.ContainsKey("oppo"), Is.False);
|
||||
Assert.That(node["self"]!.AsArray()[1]!.AsObject()["idx"]!.GetValue<int>(), Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildReady_SerializesAllFieldsIncludingSeedAndSpin()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildReady(new long[] { 1, 4, 3 });
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
Assert.That(node["idxChangeSeed"]!.GetValue<int>(), Is.EqualTo(771_335_280));
|
||||
Assert.That(node["spin"]!.GetValue<int>(), Is.EqualTo(243));
|
||||
Assert.That(node["self"]!.AsArray().Count, Is.EqualTo(3));
|
||||
Assert.That(node["oppo"]!.AsArray().Count, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildOpponentTurnStart_SerializesSpinAndResultCode()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildOpponentTurnStart();
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var node = JsonNode.Parse(json)!.AsObject();
|
||||
|
||||
Assert.That(node["spin"]!.GetValue<int>(), Is.EqualTo(100));
|
||||
Assert.That(node["resultCode"]!.GetValue<int>(), Is.EqualTo(1));
|
||||
Assert.That(node["uri"]!.GetValue<string>(), Is.EqualTo("TurnStart"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user