feat(api): UDT-003 registro de usuarios — backend completo (Phases 1-6)

- Domain: Usuario.ForCreation factory, UsernameAlreadyExistsException, IUsuarioRepository extendido
- Application: CreateUsuarioCommand/Validator/Handler, UsuarioCreatedDto, AuthOptions password policy
- Infrastructure: UsuarioRepository.ExistsByUsernameAsync + AddAsync (INSERT OUTPUT INSERTED.Id), RoleClaimType="rol" en TokenValidationParameters
- Api: UsuariosController POST api/v1/users [Authorize(Roles="admin")], ExceptionFilter mapea UsernameAlreadyExistsException + SqlException 2627 → 409
- Tests (unit): 43 tests — 33 validator + 10 handler (107 total, green)
- Tests (integration): 7 tests CreateUsuarioEndpoint — 401/403/400/201/409/race/e2e (green)
- Fix: TestWebAppFactory.ConfigureTestServices reemplaza SqlConnectionFactory singleton con CS de test correcto
This commit is contained in:
2026-04-15 10:47:48 -03:00
parent 023d30fce4
commit 3d598faffc
19 changed files with 1079 additions and 1 deletions

View File

@@ -1,9 +1,11 @@
using System.Security.Cryptography;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SIGCM2.Application.Abstractions.Security;
using SIGCM2.Infrastructure.Persistence;
using SIGCM2.Infrastructure.Security;
using Xunit;
@@ -49,6 +51,22 @@ public sealed class TestWebAppFactory : WebApplicationFactory<Program>, IAsyncLi
});
builder.UseEnvironment("Testing");
// Step 2: Replace SqlConnectionFactory singleton with the correct test connection.
// ConfigureAppConfiguration alone is insufficient because WebApplication.CreateBuilder
// evaluates configuration for singleton construction before overrides apply.
// ConfigureTestServices runs AFTER all services are registered, so it wins.
builder.ConfigureTestServices(services =>
{
// Remove the existing SqlConnectionFactory singleton registered by AddInfrastructure
var descriptor = services.SingleOrDefault(
d => d.ServiceType == typeof(SqlConnectionFactory));
if (descriptor is not null)
services.Remove(descriptor);
// Re-register with the test connection string
services.AddSingleton(new SqlConnectionFactory(TestConnectionString));
});
}
public async Task InitializeAsync()