From e54e63a762b27f27df3d679c16e7bbbd5662bff8 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Fri, 12 Jun 2026 23:29:55 -0400 Subject: [PATCH] feat(mission): /mission/buy_additional_right stub (refresh-only, no decomp) Co-Authored-By: Claude Sonnet 4.6 --- .../Controllers/MissionController.cs | 17 +++++++++++++ ...issionControllerBuyAdditionalRightTests.cs | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 SVSim.UnitTests/Controllers/MissionControllerBuyAdditionalRightTests.cs diff --git a/SVSim.EmulatedEntrypoint/Controllers/MissionController.cs b/SVSim.EmulatedEntrypoint/Controllers/MissionController.cs index 0d729f90..ef5cb212 100644 --- a/SVSim.EmulatedEntrypoint/Controllers/MissionController.cs +++ b/SVSim.EmulatedEntrypoint/Controllers/MissionController.cs @@ -116,6 +116,23 @@ public class MissionController : SVSimController return Ok(dto); } + [HttpPost("buy_additional_right")] + public async Task BuyAdditionalRight(BaseRequest _, CancellationToken ct) + { + if (!TryGetViewerId(out long viewerId)) return Unauthorized(); + + // The client-side task class is absent from the decompilation; the URL is + // registered but no Parse() is documented. Spec marks the shape as INFERRED. + // Safe stub: refresh MissionInfoDetail and let the client re-render — same + // shape as /mission/info. No currency debit until we see a real wire call. + var viewer = await LoadViewer(viewerId, ct); + await _state.EnsureCurrentAsync(viewer.Id, ct); + await _db.SaveChangesAsync(ct); + + var dto = await _assembler.BuildAsync(viewer, ct); + return Ok(dto); + } + private Task LoadViewer(long viewerId, CancellationToken ct) => _db.Viewers .Include(v => v.MissionData) diff --git a/SVSim.UnitTests/Controllers/MissionControllerBuyAdditionalRightTests.cs b/SVSim.UnitTests/Controllers/MissionControllerBuyAdditionalRightTests.cs new file mode 100644 index 00000000..7d2d2b90 --- /dev/null +++ b/SVSim.UnitTests/Controllers/MissionControllerBuyAdditionalRightTests.cs @@ -0,0 +1,25 @@ +using System.Net; +using System.Text; +using NUnit.Framework; +using SVSim.UnitTests.Infrastructure; + +namespace SVSim.UnitTests.Controllers; + +public class MissionControllerBuyAdditionalRightTests +{ + [Test] + public async Task BuyAdditionalRight_returns_ok() + { + using var factory = new SVSimTestFactory(); + long viewerId = await factory.SeedViewerAsync(tutorialState: 0); + using var client = factory.CreateAuthenticatedClient(viewerId); + + // Body shape is INFERRED — we send the bare base envelope and expect the server + // to refresh MissionInfoDetail. + var requestJson = """{"viewer_id":"0","steam_id":0,"steam_session_ticket":""}"""; + var response = await client.PostAsync("/mission/buy_additional_right", + new StringContent(requestJson, Encoding.UTF8, "application/json")); + + Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); + } +}