FEAT-13: SaleContract + BreederSettings entities (additive migration, join table justified in code docs), /contracts + /settings/breeder-profile Minimal-API endpoints w/ Abgabe-completion transaction + SQLite-backed endpoint round-trip tests (21/21)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
61
GerbilManager.Tests/ApiFactory.cs
Normal file
61
GerbilManager.Tests/ApiFactory.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace GerbilManager.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// FEAT-13: In-Memory-Test-Host für Endpoint-Round-Trips. Ersetzt die
|
||||
/// Aspire/Npgsql-Registrierung durch SQLite in-memory (eine offene Verbindung
|
||||
/// hält die DB am Leben), Umgebung "Testing" überspringt Database.Migrate()
|
||||
/// (Npgsql-Migrationen laufen nicht auf SQLite) — Schema via EnsureCreated,
|
||||
/// inklusive der HasData-Seeds (73 Farbschläge + Zuchtprofil-Singleton).
|
||||
/// Vertrags-Dateien landen in einem Temp-Ordner, der mit dem Host stirbt.
|
||||
/// </summary>
|
||||
public sealed class ApiFactory : WebApplicationFactory<Program>
|
||||
{
|
||||
private readonly SqliteConnection _connection = new("DataSource=:memory:");
|
||||
|
||||
public string ContractRoot { get; } =
|
||||
Path.Combine(Path.GetTempPath(), $"gerbil-contract-tests-{Guid.NewGuid():N}");
|
||||
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
builder.UseEnvironment("Testing");
|
||||
// Dummy, damit Aspires AddNpgsqlDbContext beim Host-Aufbau zufrieden ist;
|
||||
// die eigentliche Registrierung wird unten durch SQLite ersetzt.
|
||||
builder.UseSetting("ConnectionStrings:gerbilmanager",
|
||||
"Host=localhost;Database=test;Username=test;Password=test");
|
||||
builder.UseSetting("Contracts:RootPath", ContractRoot);
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
// EF 9+: AddDbContext registriert die Provider-Konfiguration als
|
||||
// IDbContextOptionsConfiguration<T> — ohne deren Entfernung blieben
|
||||
// Npgsql UND SQLite registriert (ein Provider pro ServiceProvider).
|
||||
services.RemoveAll<Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsConfiguration<ApplicationContext>>();
|
||||
services.RemoveAll<DbContextOptions<ApplicationContext>>();
|
||||
services.RemoveAll<ApplicationContext>();
|
||||
|
||||
_connection.Open();
|
||||
services.AddDbContext<ApplicationContext>(o => o.UseSqlite(_connection));
|
||||
|
||||
using var provider = services.BuildServiceProvider();
|
||||
using var scope = provider.CreateScope();
|
||||
scope.ServiceProvider.GetRequiredService<ApplicationContext>().Database.EnsureCreated();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
{
|
||||
_connection.Dispose();
|
||||
if (Directory.Exists(ContractRoot)) Directory.Delete(ContractRoot, recursive: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user