using Dapper; using SIGCM2.Infrastructure.Persistence; using SIGCM2.TestSupport; namespace SIGCM2.Application.Tests.Integration; [Collection("Database")] public class UsuarioRepositoryTests : IAsyncLifetime { private readonly SqlTestFixture _db; private UsuarioRepository _repository = null!; public UsuarioRepositoryTests(SqlTestFixture db) { _db = db; } public async Task InitializeAsync() { await _db.ResetAndSeedAsync(); var factory = new SqlConnectionFactory(TestConnectionStrings.AppTestDb); _repository = new UsuarioRepository(factory); } public Task DisposeAsync() => Task.CompletedTask; // Scenario: GetByUsername returns correct entity when user exists [Fact] public async Task GetByUsernameAsync_ExistingUser_ReturnsUsuario() { var usuario = await _repository.GetByUsernameAsync("admin"); Assert.NotNull(usuario); Assert.Equal("admin", usuario.Username); Assert.Equal("admin", usuario.Rol); Assert.True(usuario.Activo); Assert.False(string.IsNullOrWhiteSpace(usuario.PasswordHash)); } // Triangulation: GetByUsername returns null when user does not exist [Fact] public async Task GetByUsernameAsync_NonExistentUser_ReturnsNull() { var usuario = await _repository.GetByUsernameAsync("noexiste"); Assert.Null(usuario); } // Triangulation: case-sensitive username lookup (SQL Server UNIQUE constraint is case-insensitive by default) [Fact] public async Task GetByUsernameAsync_DifferentUser_ReturnsCorrectUser_Cajero() { // Insert a second user with canonical rol 'cajero' (post-UDT-004 FK requires Rol.Codigo to exist). await _db.Connection.ExecuteAsync( "INSERT INTO dbo.Usuario (Username, PasswordHash, Nombre, Apellido, Rol, PermisosJson) " + "VALUES ('cajero1', '$2a$12$hash2', 'Juan', 'Pérez', 'cajero', '[]')"); var admin = await _repository.GetByUsernameAsync("admin"); var cajero = await _repository.GetByUsernameAsync("cajero1"); Assert.NotNull(admin); Assert.NotNull(cajero); Assert.NotEqual(admin.Id, cajero.Id); Assert.Equal("admin", admin.Rol); Assert.Equal("cajero", cajero.Rol); } }