feat(http): ArenaTwoPickController (6 actions)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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 }); }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
using MessagePack;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class FinishRequest { }
|
||||
@@ -0,0 +1,6 @@
|
||||
using MessagePack;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class RetireRequest { }
|
||||
@@ -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; }
|
||||
}
|
||||
29
SVSim.UnitTests/Controllers/ArenaTwoPickControllerTests.cs
Normal file
29
SVSim.UnitTests/Controllers/ArenaTwoPickControllerTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user