< Summary

Information
Class: FAU.Logica.Services.UsuarioService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/UsuarioService.cs
Line coverage
86%
Covered lines: 80
Uncovered lines: 12
Coverable lines: 92
Total lines: 211
Line coverage: 86.9%
Branch coverage
100%
Covered branches: 24
Total branches: 24
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetByIdAsync()100%11100%
GetByUsernameAsync()100%11100%
GetAllAsync()100%11100%
CreateAsync()100%2288.23%
UpdateAsync()100%4480%
CambiarEstadoAsync()100%4484.61%
CambiarPasswordAsync()100%6685.71%
AsignarRolAsync()100%6684.61%
RemoverRolAsync()100%4481.81%
DeleteAsync()100%11100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/UsuarioService.cs

#LineLine coverage
 1using FAU.DataAccess.Repositories;
 2using FAU.Entidades;
 3
 4namespace FAU.Logica.Services;
 5
 6public class UsuarioService : IUsuarioService
 7{
 8    private readonly IUsuarioRepository _usuarioRepository;
 9    private readonly IRolRepository _rolRepository;
 10
 2411    public UsuarioService(IUsuarioRepository usuarioRepository, IRolRepository rolRepository)
 12    {
 2413        _usuarioRepository = usuarioRepository;
 2414        _rolRepository = rolRepository;
 2415    }
 16
 17    public async Task<Usuario?> GetByIdAsync(long id)
 18    {
 219        return await _usuarioRepository.GetByIdAsync(id);
 220    }
 21
 22    public async Task<Usuario?> GetByUsernameAsync(string username)
 23    {
 124        return await _usuarioRepository.GetByUsernameAsync(username);
 125    }
 26
 27    public async Task<IEnumerable<Usuario>> GetAllAsync()
 28    {
 129        return await _usuarioRepository.GetAllAsync();
 130    }
 31
 32    public async Task<(bool Success, Usuario? Usuario, string? Error)> CreateAsync(string username, string password, lon
 33    {
 34        try
 35        {
 236            if (await _usuarioRepository.ExistsAsync(username))
 37            {
 138                return (false, null, "El nombre de usuario ya está en uso");
 39            }
 40
 141            var passwordHash = BCrypt.Net.BCrypt.HashPassword(password);
 42
 143            var nuevoUsuario = new Usuario
 144            {
 145                Username = username,
 146                PasswordHash = passwordHash,
 147                Estado = "activo",
 148                IntentosFallidos = 0,
 149                PersonaId = personaId,
 150                FechaActualizacion = DateTime.UtcNow
 151            };
 52
 153            var usuarioCreado = await _usuarioRepository.CreateAsync(nuevoUsuario);
 154            return (true, usuarioCreado, null);
 55        }
 056        catch (Exception ex)
 57        {
 058            return (false, null, $"Error al crear usuario: {ex.Message}");
 59        }
 260    }
 61
 62    public async Task<(bool Success, Usuario? Usuario, string? Error)> UpdateAsync(long id, string? newPassword = null)
 63    {
 64        try
 65        {
 366            var usuario = await _usuarioRepository.GetByIdAsync(id);
 367            if (usuario == null)
 68            {
 169                return (false, null, "Usuario no encontrado");
 70            }
 71
 272            if (!string.IsNullOrWhiteSpace(newPassword))
 73            {
 174                usuario.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
 75            }
 76
 277            var usuarioActualizado = await _usuarioRepository.UpdateAsync(usuario);
 278            return (true, usuarioActualizado, null);
 79        }
 080        catch (Exception ex)
 81        {
 082            return (false, null, $"Error al actualizar usuario: {ex.Message}");
 83        }
 384    }
 85
 86    public async Task<(bool Success, string? Error)> CambiarEstadoAsync(long id, string nuevoEstado)
 87    {
 88        try
 89        {
 390            var usuario = await _usuarioRepository.GetByIdAsync(id);
 391            if (usuario == null)
 92            {
 193                return (false, "Usuario no encontrado");
 94            }
 95
 96            // Validar estados permitidos
 297            var estadosPermitidos = new[] { "Activo", "Bloqueado", "Inactivo" };
 298            if (!estadosPermitidos.Contains(nuevoEstado, StringComparer.OrdinalIgnoreCase))
 99            {
 1100                return (false, "Estado inválido. Valores permitidos: Activo, Bloqueado, Inactivo");
 101            }
 102
 1103            usuario.Estado = nuevoEstado;
 1104            usuario.FechaActualizacion = DateTime.UtcNow;
 105
 1106            await _usuarioRepository.UpdateAsync(usuario);
 1107            return (true, null);
 108        }
 0109        catch (Exception ex)
 110        {
 0111            return (false, $"Error al cambiar estado del usuario: {ex.Message}");
 112        }
 3113    }
 114
 115    public async Task<(bool Success, string? Error)> CambiarPasswordAsync(long id, string nuevaPassword)
 116    {
 117        try
 118        {
 4119            var usuario = await _usuarioRepository.GetByIdAsync(id);
 4120            if (usuario == null)
 121            {
 1122                return (false, "Usuario no encontrado");
 123            }
 124
 3125            if (string.IsNullOrWhiteSpace(nuevaPassword))
 126            {
 1127                return (false, "La nueva contraseña no puede estar vacía");
 128            }
 129
 2130            if (nuevaPassword.Length < 6)
 131            {
 1132                return (false, "La contraseña debe tener al menos 6 caracteres");
 133            }
 134
 1135            usuario.PasswordHash = BCrypt.Net.BCrypt.HashPassword(nuevaPassword);
 1136            usuario.FechaActualizacion = DateTime.UtcNow;
 137
 1138            await _usuarioRepository.UpdateAsync(usuario);
 1139            return (true, null);
 140        }
 0141        catch (Exception ex)
 142        {
 0143            return (false, $"Error al cambiar contraseña: {ex.Message}");
 144        }
 4145    }
 146
 147    public async Task<(bool Success, string? Error)> AsignarRolAsync(long usuarioId, long rolId)
 148    {
 149        try
 150        {
 4151            var usuario = await _usuarioRepository.GetByIdAsync(usuarioId);
 4152            if (usuario == null)
 153            {
 1154                return (false, "Usuario no encontrado");
 155            }
 156
 3157            var rol = await _rolRepository.GetByIdAsync(rolId);
 3158            if (rol == null)
 159            {
 1160                return (false, "Rol no encontrado");
 161            }
 162
 3163            if (usuario.Roles.Any(r => r.Id == rolId))
 164            {
 1165                return (false, "El usuario ya tiene este rol asignado");
 166            }
 167
 1168            usuario.Roles.Add(rol);
 1169            await _usuarioRepository.UpdateAsync(usuario);
 170
 1171            return (true, null);
 172        }
 0173        catch (Exception ex)
 174        {
 0175            return (false, $"Error al asignar rol: {ex.Message}");
 176        }
 4177    }
 178
 179    public async Task<(bool Success, string? Error)> RemoverRolAsync(long usuarioId, long rolId)
 180    {
 181        try
 182        {
 3183            var usuario = await _usuarioRepository.GetByIdAsync(usuarioId);
 3184            if (usuario == null)
 185            {
 1186                return (false, "Usuario no encontrado");
 187            }
 188
 3189            var rol = usuario.Roles.FirstOrDefault(r => r.Id == rolId);
 2190            if (rol == null)
 191            {
 1192                return (false, "El usuario no tiene este rol asignado");
 193            }
 194
 1195            usuario.Roles.Remove(rol);
 1196            await _usuarioRepository.UpdateAsync(usuario);
 197
 1198            return (true, null);
 199        }
 0200        catch (Exception ex)
 201        {
 0202            return (false, $"Error al remover rol: {ex.Message}");
 203        }
 3204    }
 205
 206    public async Task DeleteAsync(long id)
 207    {
 1208        await _usuarioRepository.DeleteAsync(id);
 1209    }
 210}
 211