using Dapper; using Microsoft.Data.SqlClient; using Respawn; using Xunit; namespace SIGCM2.TestSupport; /// /// Manages a real SQL Server test database. /// Resets state between test runs using Respawn. /// Seeds the admin user after each reset. /// public sealed class SqlTestFixture : IAsyncLifetime { private readonly string _connectionString; private SqlConnection _connection = null!; private Respawner _respawner = null!; public SqlTestFixture(string connectionString) { _connectionString = connectionString; } public async Task InitializeAsync() { _connection = new SqlConnection(_connectionString); await _connection.OpenAsync(); _respawner = await Respawner.CreateAsync(_connection, new RespawnerOptions { DbAdapter = DbAdapter.SqlServer, // Rol is a lookup table seeded by migration V003 — never wipe or Usuario FK breaks. TablesToIgnore = [new Respawn.Graph.Table("dbo", "Rol")] }); await ResetAndSeedAsync(); } public async Task ResetAndSeedAsync() { await _respawner.ResetAsync(_connection); await SeedRolCanonicalAsync(); await SeedAdminAsync(); } private async Task SeedRolCanonicalAsync() { const string sql = """ SET QUOTED_IDENTIFIER ON; MERGE dbo.Rol AS t USING (VALUES ('admin', N'Administrador', N'Supervisor total'), ('cajero', N'Cajero', N'Mostrador contado'), ('operador_ctacte', N'Operador Cta Cte', N'Cuenta corriente'), ('picadora', N'Picadora/Correctora', N'Edición de textos'), ('jefe_publicidad', N'Jefe de Publicidad', N'Supervisión de pauta'), ('productor', N'Productor', N'Carga restringida'), ('diagramacion', N'Diagramación/Taller', N'Solo lectura pauta'), ('reportes', N'Reportes', N'Solo lectura reportes') ) AS s (Codigo, Nombre, Descripcion) ON t.Codigo = s.Codigo WHEN NOT MATCHED BY TARGET THEN INSERT (Codigo, Nombre, Descripcion, Activo) VALUES (s.Codigo, s.Nombre, s.Descripcion, 1); """; await _connection.ExecuteAsync(sql); } public async Task DisposeAsync() { if (_connection is not null) { await _connection.CloseAsync(); await _connection.DisposeAsync(); } } private async Task SeedAdminAsync() { const string sql = """ SET QUOTED_IDENTIFIER ON; IF NOT EXISTS (SELECT 1 FROM dbo.Usuario WHERE Username = 'admin') INSERT INTO dbo.Usuario (Username, PasswordHash, Nombre, Apellido, Rol, PermisosJson, Activo) VALUES ( 'admin', '$2a$12$rmq6tlSAQ8WXhR2CwLCSeuwCJKz/.8Eab95UQCUNfwe4dokeOqMcW', 'Administrador', 'Sistema', 'admin', '["*"]', 1 ); """; await _connection.ExecuteAsync(sql); } }