diff --git a/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs b/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs index 35e01d5..197216b 100644 --- a/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs +++ b/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs @@ -99,16 +99,25 @@ public class BattleSessionDispatchTests } [Test] - public void TurnEnd_AfterReady_PushesOpponentTurnStart_TransitionsToOpponentTurn() + public void TurnEnd_AfterReady_PushesOpponentTurnStart_ThenTurnEnd_StaysInAfterReady() { var s = NewSession(); s.ComputeResponses(NewEnvelope(NetworkBattleUri.InitNetwork)); s.ComputeResponses(NewEnvelope(NetworkBattleUri.InitBattle)); s.ComputeResponses(NewEnvelope(NetworkBattleUri.Loaded)); s.ComputeResponses(NewEnvelope(NetworkBattleUri.Swap)); + var responses = s.ComputeResponses(NewEnvelope(NetworkBattleUri.TurnEnd)); - Assert.That(responses.Single().Envelope.Uri, Is.EqualTo(NetworkBattleUri.TurnStart)); - Assert.That(s.Phase, Is.EqualTo(BattleSessionPhase.OpponentTurn)); + + // Two-frame cycle: opponent opens its turn, immediately ends it, hands control back. + Assert.That(responses.Select(r => r.Envelope.Uri), + Is.EqualTo(new[] { NetworkBattleUri.TurnStart, NetworkBattleUri.TurnEnd })); + Assert.That(responses.Select(r => r.NoStock), + Is.EqualTo(new[] { false, false })); + // Phase returns to AfterReady within the same call; the next player TurnEnd can fire + // the cycle again. (OpponentTurn is set transiently inside ComputeResponses to document + // intent, but is never externally observable.) + Assert.That(s.Phase, Is.EqualTo(BattleSessionPhase.AfterReady)); } [Test]