using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using RpgRoller.Data; using RpgRoller.Hosting; namespace RpgRoller.Tests; public abstract class ApiTestBase(WebApplicationFactory factory) : IClassFixture> { private sealed class FixedDiceRoller(IEnumerable values) : IDiceRoller { public int Roll(int sides) { var next = m_Values.Count > 0 ? m_Values.Dequeue() : 1; return Math.Clamp(next, 1, sides); } private readonly Queue m_Values = new(values); } protected WebApplicationFactory CreateFactory(params int[] rollValues) { return factory.WithWebHostBuilder(builder => { builder.ConfigureLogging(logging => { logging.AddFilter("Microsoft.AspNetCore", LogLevel.Warning); logging.AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning); logging.AddFilter("Microsoft.Hosting", LogLevel.Warning); }); builder.ConfigureServices(services => { services.RemoveAll(); services.AddSingleton(new FixedDiceRoller(rollValues)); services.RemoveAll>(); services.RemoveAll>(); services.RemoveAll(); services.RemoveAll(); var dbPath = Path.Combine(Path.GetTempPath(), $"rpgroller-tests-{Guid.NewGuid():N}.db"); services.AddSingleton(new SqliteDatabaseFile(dbPath)); services.AddDbContextFactory(options => options.UseSqlite($"Data Source={dbPath}")); }); }); } protected static async Task RegisterAsync(HttpClient client, string username, string password, string displayName) { return await PostAsync(client, "/api/auth/register", new(username, password, displayName)); } protected static async Task LoginAsync(HttpClient client, string username, string password) { var response = await client.PostAsJsonAsync("/api/auth/login", new LoginRequest(username, password)); Assert.Equal(HttpStatusCode.OK, response.StatusCode); } protected static async Task PostAsync(HttpClient client, string uri, TRequest payload) { var response = await client.PostAsJsonAsync(uri, payload); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); return result; } protected static async Task PutAsync(HttpClient client, string uri, TRequest payload) { var response = await client.PutAsJsonAsync(uri, payload); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); return result; } protected static async Task GetAsync(HttpClient client, string uri) { var response = await client.GetAsync(uri); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); return result; } }