diff --git a/SVSim.UnitTests/Controllers/FreeBattleControllerTests.cs b/SVSim.UnitTests/Controllers/FreeBattleControllerTests.cs index c0f3d5e8..ef9fbd26 100644 --- a/SVSim.UnitTests/Controllers/FreeBattleControllerTests.cs +++ b/SVSim.UnitTests/Controllers/FreeBattleControllerTests.cs @@ -112,4 +112,30 @@ public class FreeBattleControllerTests "Missing deck → RC_BATTLE_MATCHING_ILLEGAL."); Assert.That(data.GetProperty("node_server_url").GetString(), Is.EqualTo("")); } + + [Test] + public async Task Finish_emits_battle_result_echo_and_four_field_minimum() + { + await using var factory = new SVSimTestFactory(); + var viewerId = await factory.SeedViewerAsync(); + var client = factory.CreateAuthenticatedClient(viewerId); + + var resp = await client.PostAsJsonAsync("/unlimited_free_battle/finish", FinishBody(battleResult: 1)); + + Assert.That(resp.IsSuccessStatusCode, Is.True); + var raw = await resp.Content.ReadAsStringAsync(); + using var doc = JsonDocument.Parse(raw); + var data = doc.RootElement; + Assert.That(data.GetProperty("battle_result").GetInt32(), Is.EqualTo(1)); + Assert.That(data.GetProperty("get_class_experience").GetInt32(), Is.EqualTo(0)); + Assert.That(data.GetProperty("class_experience").GetInt32(), Is.EqualTo(0)); + Assert.That(data.GetProperty("class_level").GetInt32(), Is.EqualTo(1)); + + // Strict subset — no rank fields. The client doesn't read them on free-battle + // finish; emitting them would be wire-format pollution. + Assert.That(raw, Does.Not.Contain("\"rank\"")); + Assert.That(raw, Does.Not.Contain("\"after_battle_point\"")); + Assert.That(raw, Does.Not.Contain("\"after_master_point\"")); + Assert.That(raw, Does.Not.Contain("\"successive_win")); + } }