test(udt-001): backend unit and integration tests (30 tests)
This commit is contained in:
94
tests/SIGCM2.TestSupport/TestWebAppFactory.cs
Normal file
94
tests/SIGCM2.TestSupport/TestWebAppFactory.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SIGCM2.Application.Abstractions.Security;
|
||||
using SIGCM2.Infrastructure.Security;
|
||||
using Xunit;
|
||||
|
||||
namespace SIGCM2.TestSupport;
|
||||
|
||||
/// <summary>
|
||||
/// WebApplicationFactory for integration tests against SIGCM2.Api.
|
||||
/// Uses SIGCM2_Test database (separate from production SIGCM2).
|
||||
/// </summary>
|
||||
public sealed class TestWebAppFactory : WebApplicationFactory<Program>, IAsyncLifetime
|
||||
{
|
||||
private const string TestConnectionString =
|
||||
"Server=TECNICA3;Database=SIGCM2_Test;User Id=desarrollo;Password=desarrollo2026;TrustServerCertificate=True;";
|
||||
|
||||
// Resolved once — absolute paths independent of working directory
|
||||
private static readonly string RepoRoot = ResolveRepoRoot();
|
||||
private static readonly string PrivateKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "private.pem");
|
||||
private static readonly string PublicKeyPath = Path.Combine(RepoRoot, "src", "api", "SIGCM2.Api", "keys", "public.pem");
|
||||
|
||||
private readonly SqlTestFixture _dbFixture = new(TestConnectionString);
|
||||
|
||||
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||
{
|
||||
// Step 1: Override configuration BEFORE services are built
|
||||
builder.ConfigureAppConfiguration((ctx, config) =>
|
||||
{
|
||||
// Clear all existing sources and rebuild with test values
|
||||
// This ensures our paths win over appsettings.json
|
||||
config.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["ConnectionStrings:SqlServer"] = TestConnectionString,
|
||||
["Jwt:Issuer"] = "sigcm2.api",
|
||||
["Jwt:Audience"] = "sigcm2.web",
|
||||
["Jwt:AccessTokenMinutes"] = "60",
|
||||
["Jwt:PrivateKeyPath"] = PrivateKeyPath,
|
||||
["Jwt:PublicKeyPath"] = PublicKeyPath,
|
||||
["Jwt:PrivateKey"] = null,
|
||||
["Jwt:PublicKey"] = null,
|
||||
["Cors:AllowedOrigins:0"] = "http://localhost:5173",
|
||||
["Serilog:MinimumLevel:Default"] = "Warning",
|
||||
});
|
||||
});
|
||||
|
||||
builder.UseEnvironment("Testing");
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _dbFixture.InitializeAsync();
|
||||
}
|
||||
|
||||
public new async Task DisposeAsync()
|
||||
{
|
||||
await _dbFixture.DisposeAsync();
|
||||
await base.DisposeAsync();
|
||||
}
|
||||
|
||||
private static string ResolveRepoRoot()
|
||||
{
|
||||
// Walk up from AppContext.BaseDirectory looking for SIGCM2.slnx
|
||||
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (dir is not null)
|
||||
{
|
||||
if (dir.GetFiles("SIGCM2.slnx").Length > 0)
|
||||
return dir.FullName;
|
||||
dir = dir.Parent;
|
||||
}
|
||||
|
||||
// Walk up from assembly location
|
||||
var assemblyLocation = typeof(TestWebAppFactory).Assembly.Location;
|
||||
dir = new DirectoryInfo(Path.GetDirectoryName(assemblyLocation)!);
|
||||
while (dir is not null)
|
||||
{
|
||||
if (dir.GetFiles("SIGCM2.slnx").Length > 0)
|
||||
return dir.FullName;
|
||||
dir = dir.Parent;
|
||||
}
|
||||
|
||||
// Known absolute path (last resort for this machine)
|
||||
const string knownPath = @"E:\SIG-CM2.0";
|
||||
if (Directory.Exists(knownPath) && File.Exists(Path.Combine(knownPath, "SIGCM2.slnx")))
|
||||
return knownPath;
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"Could not find repo root containing SIGCM2.slnx. " +
|
||||
$"AppContext.BaseDirectory: {AppContext.BaseDirectory}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user