refactor(battle-node): switch MsgEnvelope.Body to IMsgBody, migrate all sites
This commit is contained in:
@@ -66,7 +66,7 @@ public class BattleNodeFlowTests
|
||||
Cat: uri == NetworkBattleUri.InitNetwork ? EmitCategory.General
|
||||
: uri == NetworkBattleUri.InitBattle ? EmitCategory.Matching
|
||||
: EmitCategory.Battle,
|
||||
PubSeq: pubSeq, PlaySeq: null, Body: body ?? new Dictionary<string, object?>());
|
||||
PubSeq: pubSeq, PlaySeq: null, Body: new RawBody(body ?? new Dictionary<string, object?>()));
|
||||
|
||||
private static string MakeKey()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using NUnit.Framework;
|
||||
using SVSim.BattleNode.Lifecycle;
|
||||
using SVSim.BattleNode.Protocol;
|
||||
using SVSim.BattleNode.Protocol.Bodies;
|
||||
|
||||
namespace SVSim.UnitTests.BattleNode.Lifecycle;
|
||||
|
||||
@@ -13,40 +14,39 @@ public class ScriptedLifecycleTests
|
||||
var env = ScriptedLifecycle.BuildMatched(playerViewerId: 906243102, opponentViewerId: 847666884, battleId: "b");
|
||||
|
||||
Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.Matched));
|
||||
var selfInfo = (Dictionary<string, object?>)env.Body["selfInfo"]!;
|
||||
Assert.That(selfInfo["oppoId"], Is.EqualTo(847666884L));
|
||||
var oppoInfo = (Dictionary<string, object?>)env.Body["oppoInfo"]!;
|
||||
Assert.That(oppoInfo["oppoId"], Is.EqualTo(906243102L));
|
||||
var body = (MatchedBody)env.Body;
|
||||
Assert.That(body.SelfInfo.OppoId, Is.EqualTo(847666884L));
|
||||
Assert.That(body.OppoInfo.OppoId, Is.EqualTo(906243102L));
|
||||
|
||||
// Bid travels in the envelope, not the Body — protect against the Task 5 reserved-keys regression.
|
||||
// Bid travels in the envelope, not the Body — protect against the reserved-keys regression.
|
||||
Assert.That(env.Bid, Is.EqualTo("b"));
|
||||
Assert.That(env.Body.ContainsKey("bid"), Is.False);
|
||||
// Typed bodies can't carry an envelope-level "bid" key by construction (no such property).
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildMatched_ContainsThirtyCardSelfDeck()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildMatched(1, 2, "b");
|
||||
var deck = (List<object?>)env.Body["selfDeck"]!;
|
||||
Assert.That(deck.Count, Is.EqualTo(30));
|
||||
var body = (MatchedBody)env.Body;
|
||||
Assert.That(body.SelfDeck.Count, Is.EqualTo(30));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildBattleStart_HasTurnStateZeroAndBattleTypeEleven()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildBattleStart(playerViewerId: 1);
|
||||
Assert.That(env.Body["turnState"], Is.EqualTo(0));
|
||||
Assert.That(env.Body["battleType"], Is.EqualTo(11));
|
||||
var body = (BattleStartBody)env.Body;
|
||||
Assert.That(body.TurnState, Is.EqualTo(0));
|
||||
Assert.That(body.BattleType, Is.EqualTo(11));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildDeal_HasThreeSelfAndThreeOppoEntries()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildDeal();
|
||||
var self = (List<object?>)env.Body["self"]!;
|
||||
var oppo = (List<object?>)env.Body["oppo"]!;
|
||||
Assert.That(self.Count, Is.EqualTo(3));
|
||||
Assert.That(oppo.Count, Is.EqualTo(3));
|
||||
var body = (DealBody)env.Body;
|
||||
Assert.That(body.Self.Count, Is.EqualTo(3));
|
||||
Assert.That(body.Oppo.Count, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -75,19 +75,19 @@ public class ScriptedLifecycleTests
|
||||
public void BuildSwapResponse_RendersGivenHandAsPositions()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildSwapResponse(new long[] { 1, 4, 3 });
|
||||
var self = (List<object?>)env.Body["self"]!;
|
||||
Assert.That(self.Count, Is.EqualTo(3));
|
||||
Assert.That(((Dictionary<string, object?>)self[1]!)["idx"], Is.EqualTo(4));
|
||||
var body = (SwapResponseBody)env.Body;
|
||||
Assert.That(body.Self.Count, Is.EqualTo(3));
|
||||
Assert.That(body.Self[1].Idx, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildReady_IncludesIdxChangeSeedAndSpin_AndUsesGivenHand()
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildReady(new long[] { 1, 4, 3 });
|
||||
Assert.That(env.Body.ContainsKey("idxChangeSeed"), Is.True);
|
||||
Assert.That(env.Body.ContainsKey("spin"), Is.True);
|
||||
var self = (List<object?>)env.Body["self"]!;
|
||||
Assert.That(((Dictionary<string, object?>)self[1]!)["idx"], Is.EqualTo(4));
|
||||
var body = (ReadyBody)env.Body;
|
||||
Assert.That(body.IdxChangeSeed, Is.EqualTo(771_335_280));
|
||||
Assert.That(body.Spin, Is.EqualTo(243));
|
||||
Assert.That(body.Self[1].Idx, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -95,6 +95,7 @@ public class ScriptedLifecycleTests
|
||||
{
|
||||
var env = ScriptedLifecycle.BuildOpponentTurnStart();
|
||||
Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.TurnStart));
|
||||
Assert.That(env.Body.ContainsKey("spin"), Is.True);
|
||||
var body = (OpponentTurnStartBody)env.Body;
|
||||
Assert.That(body.Spin, Is.EqualTo(100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Text.Json;
|
||||
using NUnit.Framework;
|
||||
using SVSim.BattleNode.Protocol;
|
||||
|
||||
@@ -19,7 +18,8 @@ public class MsgEnvelopeTests
|
||||
|
||||
var env = MsgEnvelope.FromJson(json);
|
||||
|
||||
var idxList = (List<object?>)env.Body["idxList"]!;
|
||||
var raw = (RawBody)env.Body;
|
||||
var idxList = (List<object?>)raw.Entries["idxList"]!;
|
||||
Assert.That(idxList.Count, Is.EqualTo(2));
|
||||
Assert.That(idxList[0], Is.TypeOf<long>(), "idxList[0] must be boxed long, not double.");
|
||||
Assert.That(idxList[0], Is.EqualTo(2L));
|
||||
@@ -39,7 +39,7 @@ public class MsgEnvelopeTests
|
||||
Cat: EmitCategory.General,
|
||||
PubSeq: null,
|
||||
PlaySeq: null,
|
||||
Body: new Dictionary<string, object?> { ["foo"] = 42 });
|
||||
Body: new RawBody(new Dictionary<string, object?> { ["foo"] = 42 }));
|
||||
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
var back = MsgEnvelope.FromJson(json);
|
||||
@@ -49,7 +49,7 @@ public class MsgEnvelopeTests
|
||||
Assert.That(back.Uuid, Is.EqualTo("udid-1234"));
|
||||
Assert.That(back.Bid, Is.EqualTo("597830888107"));
|
||||
Assert.That(back.Cat, Is.EqualTo(EmitCategory.General));
|
||||
Assert.That(back.Body["foo"], Is.EqualTo(42L)); // JsonElement → int64
|
||||
Assert.That(((RawBody)back.Body).Entries["foo"], Is.EqualTo(42L));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -64,7 +64,7 @@ public class MsgEnvelopeTests
|
||||
Cat: EmitCategory.Battle,
|
||||
PubSeq: null,
|
||||
PlaySeq: 5,
|
||||
Body: new Dictionary<string, object?>());
|
||||
Body: new RawBody(new Dictionary<string, object?>()));
|
||||
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
|
||||
@@ -85,7 +85,7 @@ public class MsgEnvelopeTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToJson_BodyContainingReservedKey_Throws()
|
||||
public void ToJson_RawBodyContainingReservedKey_Throws()
|
||||
{
|
||||
var env = new MsgEnvelope(
|
||||
Uri: NetworkBattleUri.Loaded,
|
||||
@@ -96,7 +96,7 @@ public class MsgEnvelopeTests
|
||||
Cat: EmitCategory.Battle,
|
||||
PubSeq: null,
|
||||
PlaySeq: null,
|
||||
Body: new Dictionary<string, object?> { ["uri"] = "Injected" });
|
||||
Body: new RawBody(new Dictionary<string, object?> { ["uri"] = "Injected" }));
|
||||
|
||||
var ex = Assert.Throws<ArgumentException>(() => MsgEnvelope.ToJson(env));
|
||||
Assert.That(ex!.Message, Does.Contain("uri"));
|
||||
@@ -114,7 +114,7 @@ public class MsgEnvelopeTests
|
||||
Cat: EmitCategory.Battle,
|
||||
PubSeq: null,
|
||||
PlaySeq: null,
|
||||
Body: new Dictionary<string, object?>());
|
||||
Body: new RawBody(new Dictionary<string, object?>()));
|
||||
|
||||
var json = MsgEnvelope.ToJson(env);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public class MsgPayloadCodecTests
|
||||
Cat: EmitCategory.Battle,
|
||||
PubSeq: 3,
|
||||
PlaySeq: null,
|
||||
Body: new Dictionary<string, object?>());
|
||||
Body: new RawBody(new Dictionary<string, object?>()));
|
||||
|
||||
var bytes = MsgPayloadCodec.Encode(env, key: FreshKey());
|
||||
var back = MsgPayloadCodec.Decode(bytes);
|
||||
@@ -48,6 +48,6 @@ public class MsgPayloadCodecTests
|
||||
|
||||
Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.InitNetwork));
|
||||
Assert.That(env.Cat, Is.EqualTo(EmitCategory.General));
|
||||
Assert.That(env.Body["resultCode"], Is.EqualTo(1L));
|
||||
Assert.That(((RawBody)env.Body).Entries["resultCode"], Is.EqualTo(1L));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,6 @@ namespace SVSim.UnitTests.BattleNode.Reliability;
|
||||
[TestFixture]
|
||||
public class GungnirTests
|
||||
{
|
||||
[Test]
|
||||
public void BuildAlivePush_AlwaysReturnsScsOnlineOcsOnline()
|
||||
{
|
||||
var body = Gungnir.BuildAlivePushBody();
|
||||
Assert.That(body["scs"], Is.EqualTo("ONLINE"));
|
||||
Assert.That(body["ocs"], Is.EqualTo("ONLINE"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildAliveEmit_CarriesCurrentSeqFromTracker()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ public class OutboundSequencerTests
|
||||
{
|
||||
private static MsgEnvelope MakeEnvelope(NetworkBattleUri uri) =>
|
||||
new(uri, ViewerId: 1, Uuid: "u", Bid: null, Try: 0, Cat: EmitCategory.Battle,
|
||||
PubSeq: null, PlaySeq: null, Body: new Dictionary<string, object?>());
|
||||
PubSeq: null, PlaySeq: null, Body: new RawBody(new Dictionary<string, object?>()));
|
||||
|
||||
[Test]
|
||||
public void AssignAndArchive_FirstCall_ReturnsEnvelopeWithPlaySeq1()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NUnit.Framework;
|
||||
using SVSim.BattleNode.Protocol;
|
||||
using SVSim.BattleNode.Protocol.Bodies;
|
||||
using SVSim.BattleNode.Sessions;
|
||||
|
||||
namespace SVSim.UnitTests.BattleNode.Sessions;
|
||||
@@ -17,7 +18,7 @@ public class BattleSessionDispatchTests
|
||||
|
||||
private static MsgEnvelope NewEnvelope(NetworkBattleUri uri) =>
|
||||
new(uri, ViewerId: 1, Uuid: "u", Bid: null, Try: 0, Cat: EmitCategory.Battle,
|
||||
PubSeq: null, PlaySeq: null, Body: new Dictionary<string, object?>());
|
||||
PubSeq: null, PlaySeq: null, Body: new RawBody(new Dictionary<string, object?>()));
|
||||
|
||||
[Test]
|
||||
public void InitNetwork_PushesAckOnly_TransitionsToAwaitingInitBattle()
|
||||
@@ -58,18 +59,22 @@ public class BattleSessionDispatchTests
|
||||
s.ComputeResponses(NewEnvelope(NetworkBattleUri.InitNetwork));
|
||||
s.ComputeResponses(NewEnvelope(NetworkBattleUri.InitBattle));
|
||||
s.ComputeResponses(NewEnvelope(NetworkBattleUri.Loaded));
|
||||
var swapEnv = NewEnvelope(NetworkBattleUri.Swap);
|
||||
// Simulate the client's Swap{idxList:[2]}: the dict shape produced by MsgEnvelope.FromJson
|
||||
// (a List<object?> of boxed long values).
|
||||
swapEnv.Body["idxList"] = new List<object?> { 2L };
|
||||
// (a List<object?> of boxed long values), wrapped in a RawBody as the inbound type.
|
||||
var swapEnv = new MsgEnvelope(
|
||||
NetworkBattleUri.Swap, ViewerId: 1, Uuid: "u", Bid: null, Try: 0,
|
||||
Cat: EmitCategory.Battle, PubSeq: null, PlaySeq: null,
|
||||
Body: new RawBody(new Dictionary<string, object?>
|
||||
{
|
||||
["idxList"] = new List<object?> { 2L },
|
||||
}));
|
||||
|
||||
var responses = s.ComputeResponses(swapEnv);
|
||||
|
||||
var swapBody = responses[0].Envelope.Body;
|
||||
var self = (List<object?>)swapBody["self"]!;
|
||||
Assert.That(((Dictionary<string, object?>)self[0]!)["idx"], Is.EqualTo(1));
|
||||
Assert.That(((Dictionary<string, object?>)self[1]!)["idx"], Is.EqualTo(4)); // swapped — fresh deck idx
|
||||
Assert.That(((Dictionary<string, object?>)self[2]!)["idx"], Is.EqualTo(3));
|
||||
var swapBody = (SwapResponseBody)responses[0].Envelope.Body;
|
||||
Assert.That(swapBody.Self[0].Idx, Is.EqualTo(1));
|
||||
Assert.That(swapBody.Self[1].Idx, Is.EqualTo(4)); // swapped — fresh deck idx
|
||||
Assert.That(swapBody.Self[2].Idx, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
Reference in New Issue
Block a user