Files
SIG-CM2.0/tests/SIGCM2.TestSupport/SqlTestFixture.cs

99 lines
3.3 KiB
C#
Raw Normal View History

using Dapper;
using Microsoft.Data.SqlClient;
using Respawn;
using Xunit;
namespace SIGCM2.TestSupport;
/// <summary>
/// Manages a real SQL Server test database.
/// Resets state between test runs using Respawn.
/// Seeds the admin user after each reset.
/// </summary>
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.
// Permiso and RolPermiso are seeded by V005/V006 — never wipe or integration tests lose the permission catalog.
TablesToIgnore =
[
new Respawn.Graph.Table("dbo", "Rol"),
new Respawn.Graph.Table("dbo", "Permiso"),
new Respawn.Graph.Table("dbo", "RolPermiso"),
]
});
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);
}
}