Following the 216dcab fix that added [FromBody] BaseRequest _ to the
Info action, the existing tests' empty new {} payloads no longer satisfy
[ApiController] model validation (BaseRequest.ViewerId is non-nullable
string). Use the same EmptyBody() shape as RankBattleControllerTests
to mirror the production wire.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
117 lines
4.6 KiB
C#
117 lines
4.6 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using SVSim.Database;
|
|
using SVSim.Database.Models;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Replay;
|
|
using SVSim.UnitTests.Infrastructure;
|
|
|
|
namespace SVSim.UnitTests.Controllers;
|
|
|
|
public class ReplayControllerTests
|
|
{
|
|
// Minimal BaseRequest-shaped body. The translation middleware (in prod) and the
|
|
// [FromBody] BaseRequest _ binding (in tests) both require the auth fields to
|
|
// be present even when their values are unused — same pattern as
|
|
// RankBattleControllerTests.FinishBody. The actual viewer_id comes from the
|
|
// session claim, not the body.
|
|
private static object EmptyBody() => new
|
|
{
|
|
viewer_id = "0",
|
|
steam_id = 0,
|
|
steam_session_ticket = "",
|
|
};
|
|
|
|
[Test]
|
|
public async Task ReplayInfo_returns_empty_list_for_fresh_viewer()
|
|
{
|
|
using var factory = new SVSimTestFactory();
|
|
long viewerId = await factory.SeedViewerAsync(steamId: 76_561_198_000_000_001UL);
|
|
var client = factory.CreateAuthenticatedClient(viewerId);
|
|
|
|
var resp = await client.PostAsJsonAsync("/replay/info", EmptyBody());
|
|
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
|
|
|
var body = await resp.Content.ReadFromJsonAsync<ReplayInfoResponseDto>();
|
|
Assert.That(body!.ReplayList, Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public async Task ReplayInfo_returns_recent_rows_newest_first()
|
|
{
|
|
using var factory = new SVSimTestFactory();
|
|
long viewerId = await factory.SeedViewerAsync(steamId: 76_561_198_000_000_001UL);
|
|
|
|
using (var seedScope = factory.Services.CreateScope())
|
|
{
|
|
var db = seedScope.ServiceProvider.GetRequiredService<SVSimDbContext>();
|
|
db.ViewerBattleHistories.AddRange(
|
|
NewRow(viewerId, battleId: 1, createTime: new DateTime(2026, 6, 1, 0, 0, 0, DateTimeKind.Utc)),
|
|
NewRow(viewerId, battleId: 2, createTime: new DateTime(2026, 6, 2, 0, 0, 0, DateTimeKind.Utc)),
|
|
NewRow(viewerId, battleId: 3, createTime: new DateTime(2026, 6, 3, 0, 0, 0, DateTimeKind.Utc)));
|
|
await db.SaveChangesAsync();
|
|
}
|
|
|
|
var client = factory.CreateAuthenticatedClient(viewerId);
|
|
var body = await client.PostAsJsonAsync("/replay/info", EmptyBody())
|
|
.ContinueWith(t => t.Result.Content.ReadFromJsonAsync<ReplayInfoResponseDto>())
|
|
.Unwrap();
|
|
|
|
Assert.That(body!.ReplayList.Select(r => r.BattleId).ToList(),
|
|
Is.EqualTo(new[] { "3", "2", "1" }));
|
|
}
|
|
|
|
[Test]
|
|
public async Task ReplayInfo_does_not_leak_other_viewers_rows()
|
|
{
|
|
using var factory = new SVSimTestFactory();
|
|
long viewerA = await factory.SeedViewerAsync(steamId: 76_561_198_000_000_001UL);
|
|
long viewerB = await factory.SeedViewerAsync(steamId: 76_561_198_000_000_002UL);
|
|
|
|
using (var scope = factory.Services.CreateScope())
|
|
{
|
|
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
|
|
db.ViewerBattleHistories.Add(NewRow(viewerA, battleId: 100, createTime: DateTime.UtcNow));
|
|
db.ViewerBattleHistories.Add(NewRow(viewerB, battleId: 200, createTime: DateTime.UtcNow));
|
|
await db.SaveChangesAsync();
|
|
}
|
|
|
|
var client = factory.CreateAuthenticatedClient(viewerA);
|
|
var body = await client.PostAsJsonAsync("/replay/info", EmptyBody())
|
|
.ContinueWith(t => t.Result.Content.ReadFromJsonAsync<ReplayInfoResponseDto>())
|
|
.Unwrap();
|
|
|
|
Assert.That(body!.ReplayList, Has.Count.EqualTo(1));
|
|
Assert.That(body.ReplayList[0].BattleId, Is.EqualTo("100"));
|
|
}
|
|
|
|
[Test]
|
|
public async Task ReplayDetail_returns_non_success_status()
|
|
{
|
|
using var factory = new SVSimTestFactory();
|
|
long viewerId = await factory.SeedViewerAsync(steamId: 76_561_198_000_000_001UL);
|
|
var client = factory.CreateAuthenticatedClient(viewerId);
|
|
|
|
var resp = await client.PostAsJsonAsync("/replay/detail", new
|
|
{
|
|
viewer_id = viewerId,
|
|
battle_id = 234_471_983_876L,
|
|
});
|
|
|
|
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
|
|
}
|
|
|
|
private static ViewerBattleHistory NewRow(long viewerId, long battleId, DateTime createTime) => new()
|
|
{
|
|
ViewerId = viewerId,
|
|
BattleId = battleId,
|
|
SelfRotationId = "0",
|
|
OpponentName = "",
|
|
OpponentCountryCode = "",
|
|
OpponentRotationId = "0",
|
|
BattleStartTime = createTime.AddMinutes(-3),
|
|
CreateTime = createTime,
|
|
};
|
|
}
|