feat(http): ArenaTwoPickController (6 actions)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-05-31 11:15:53 -04:00
parent e245d5b158
commit f272690a31
8 changed files with 141 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
using Microsoft.AspNetCore.Mvc;
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
using SVSim.EmulatedEntrypoint.Services;
namespace SVSim.EmulatedEntrypoint.Controllers;
[Route("arena_two_pick")]
public class ArenaTwoPickController : SVSimController
{
private readonly IArenaTwoPickService _svc;
public ArenaTwoPickController(IArenaTwoPickService svc) => _svc = svc;
[HttpPost("top")]
public async Task<IActionResult> Top([FromBody] TopRequest _)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return Ok(await _svc.GetTopAsync(vid));
}
[HttpPost("entry")]
public async Task<IActionResult> Entry([FromBody] EntryRequest req)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return await GuardAsync(() => _svc.EntryAsync(vid, req.ConsumeItemType));
}
[HttpPost("class_choose")]
public async Task<IActionResult> ClassChoose([FromBody] ClassChooseRequest req)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return await GuardAsync(() => _svc.ChooseClassAsync(vid, req.ClassId));
}
[HttpPost("card_choose")]
public async Task<IActionResult> CardChoose([FromBody] CardChooseRequest req)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return await GuardAsync(() => _svc.ChooseCardAsync(vid, req.SelectedId));
}
[HttpPost("retire")]
public async Task<IActionResult> Retire([FromBody] RetireRequest _)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return await GuardAsync(() => _svc.RetireAsync(vid));
}
[HttpPost("finish")]
public async Task<IActionResult> Finish([FromBody] FinishRequest _)
{
if (!TryGetViewerId(out var vid)) return Unauthorized();
return await GuardAsync(() => _svc.FinishAsync(vid));
}
private async Task<IActionResult> GuardAsync<T>(Func<Task<T>> action)
{
try { return Ok(await action()); }
catch (ArenaTwoPickException ex) { return BadRequest(new { error_code = ex.ErrorCode }); }
}
}

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class CardChooseRequest
{
[JsonPropertyName("selected_id")] [Key("selected_id")] public long SelectedId { get; set; }
}

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class ClassChooseRequest
{
[JsonPropertyName("class_id")] [Key("class_id")] public int ClassId { get; set; }
}

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class EntryRequest
{
[JsonPropertyName("consume_item_type")] [Key("consume_item_type")] public int ConsumeItemType { get; set; }
}

View File

@@ -0,0 +1,6 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class FinishRequest { }

View File

@@ -0,0 +1,6 @@
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class RetireRequest { }

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
using MessagePack;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
[MessagePackObject]
public class TopRequest
{
[JsonPropertyName("mode")] [Key("mode")] public int Mode { get; set; }
}

View File

@@ -0,0 +1,29 @@
using System.Net;
using System.Net.Http.Json;
using SVSim.UnitTests.Infrastructure;
namespace SVSim.UnitTests.Controllers;
public class ArenaTwoPickControllerTests
{
[Test]
public async Task Top_unauthenticated_returns_401()
{
using var factory = new SVSimTestFactory();
using var client = factory.CreateClient();
var resp = await client.PostAsync("/arena_two_pick/top", JsonContent.Create(new { mode = 0 }));
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
}
[Test]
public async Task Top_authed_with_no_run_returns_entry_info_null()
{
using var factory = new SVSimTestFactory();
var viewerId = await factory.SeedViewerAsync();
using var client = factory.CreateAuthenticatedClient(viewerId);
var resp = await client.PostAsync("/arena_two_pick/top", JsonContent.Create(new { mode = 0 }));
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var body = await resp.Content.ReadAsStringAsync();
StringAssert.Contains("\"entry_info\":null", body);
}
}