using System.Net.Http.Headers; using System.Net.Http.Json; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Vanguard.Server.Api; using Vanguard.Server.Auth; using Vanguard.Server.Meta; using Xunit.Sdk; namespace Vanguard.Server.Tests; [Collection("Orleans")] public class PracticeBotE2ETests { [Fact] public async Task Player_Can_Play_A_Practice_Match_Against_Bot() { using var factory = new WebApplicationFactory() .WithWebHostBuilder(builder => { builder.UseSetting("Orleans:Enabled", "true"); builder.UseSetting("Orleans:SiloPort", "21112"); builder.UseSetting("Orleans:GatewayPort", "21001"); }); using var anonymous = factory.CreateClient(); var register = await anonymous.PostAsJsonAsync( "/api/auth/register", new { userName = "practice-player", password = "Practice12345!" }); if (!register.IsSuccessStatusCode) throw new XunitException(await register.Content.ReadAsStringAsync()); var auth = (await register.Content.ReadFromJsonAsync())!; using var http = factory.CreateClient(); http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", auth.AccessToken); var onboarding = await http.PostAsJsonAsync( "/api/meta/onboarding", new { deckId = "td01" }); if (!onboarding.IsSuccessStatusCode) throw new XunitException(await onboarding.Content.ReadAsStringAsync()); var trialDeck = ServerTestData.TrialDecks.Decks.Single(deck => deck.Id == "td01"); var createDeck = await http.PostAsJsonAsync( "/api/decks", new { name = "Practice deck", cards = trialDeck.ToDeck() }); if (!createDeck.IsSuccessStatusCode) throw new XunitException(await createDeck.Content.ReadAsStringAsync()); var deck = (await createDeck.Content.ReadFromJsonAsync())!; var practice = await http.PostAsJsonAsync( "/api/game/practice", new { deckId = deck.Id }); if (!practice.IsSuccessStatusCode) throw new XunitException(await practice.Content.ReadAsStringAsync()); var start = (await practice.Content.ReadFromJsonAsync())!; Assert.Equal(0, start.Seat); Assert.False(string.IsNullOrWhiteSpace(start.Ticket)); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(120)); await using var client = await TestGameClient.ConnectAsync( factory, start.MatchId, start.Ticket, "practice-player", 0, cts.Token); await client.PlayRandomlyAsync(seed: 7, cts.Token); Assert.True(client.View.IsFinished, "Практика с ботом не завершилась."); Assert.InRange(client.View.Winner, 0, 1); var history = await http.GetFromJsonAsync("/api/matches"); Assert.NotNull(history); Assert.Empty(history!.Items); } }