feat(matching): MatchContextBuilder.BuildForRankBattleAsync for rank battles
Sibling to BuildForTwoPickAsync. Routes through IDeckRepository.GetDeck to pull the viewer's deck #1 for the requested format (avoiding the viewer-graph nav-ref auto-load pitfall — DeckCard.Card silently ships card_id=0 via the default include path). Throws if the viewer has no deck for the format. Cosmetics fall back to DefaultLoadoutConfig defaults when unequipped, same shape as TK2. Used by RankBattleController in a later task to build self-context for /ai_<fmt>_rank_battle/start and to pair-up under /<fmt>_rank_battle/do_matching. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SVSim.BattleNode.Bridge;
|
||||
using SVSim.Database;
|
||||
using SVSim.Database.Enums;
|
||||
using SVSim.Database.Models;
|
||||
using SVSim.EmulatedEntrypoint.Services;
|
||||
using SVSim.UnitTests.Infrastructure;
|
||||
@@ -116,6 +117,41 @@ public class MatchContextBuilderTests
|
||||
Assert.That(ex!.ErrorCode, Is.EqualTo("arena_two_pick_draft_incomplete"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task BuildForRankBattle_returns_MatchContext_with_format_specific_deck()
|
||||
{
|
||||
await using var factory = new SVSimTestFactory();
|
||||
var viewerId = await factory.SeedViewerAsync(displayName: "Ranker");
|
||||
await factory.SeedGlobalsAsync();
|
||||
await factory.SeedDeckAsync(viewerId, Format.Rotation, 1, "Rank Rotation Deck");
|
||||
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var builder = scope.ServiceProvider.GetRequiredService<IMatchContextBuilder>();
|
||||
|
||||
var ctx = await builder.BuildForRankBattleAsync(viewerId, Format.Rotation);
|
||||
|
||||
Assert.That(ctx.UserName, Is.EqualTo("Ranker"));
|
||||
Assert.That(ctx.BattleType, Is.EqualTo(11), "BattleType=11 matches the prod rank-battle wire value (same as TK2).");
|
||||
Assert.That(ctx.ClassId, Is.Not.Null.And.Not.Empty, "ClassId from the selected deck's class.");
|
||||
Assert.That(ctx.CardMasterName, Is.EqualTo("card_master_node_10015"));
|
||||
Assert.That(ctx.FieldId, Is.EqualTo(43));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task BuildForRankBattle_throws_when_no_deck_for_format()
|
||||
{
|
||||
await using var factory = new SVSimTestFactory();
|
||||
var viewerId = await factory.SeedViewerAsync();
|
||||
await factory.SeedGlobalsAsync();
|
||||
// Intentionally no SeedDeckAsync for Rotation.
|
||||
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var builder = scope.ServiceProvider.GetRequiredService<IMatchContextBuilder>();
|
||||
|
||||
Assert.That(async () => await builder.BuildForRankBattleAsync(viewerId, Format.Rotation),
|
||||
Throws.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task BuildForTwoPick_falls_back_to_default_loadout_when_unequipped()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user