using NSubstitute; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Usuarios.GetById; using SIGCM2.Domain.Entities; using SIGCM2.Domain.Exceptions; namespace SIGCM2.Application.Tests.Usuarios; public class GetUsuarioByIdQueryHandlerTests { private readonly IUsuarioRepository _repo = Substitute.For(); private readonly GetUsuarioByIdQueryHandler _handler; public GetUsuarioByIdQueryHandlerTests() { _handler = new GetUsuarioByIdQueryHandler(_repo); } [Fact] public async Task Handle_Returns_UsuarioDetailDto_When_Found() { var usuario = new Usuario(5, "jperez", "$2a$12$hash", "Juan", "Pérez", "j@x.com", "cajero", "[]", true, fechaModificacion: null, ultimoLogin: null, mustChangePassword: false); _repo.GetDetailAsync(5, Arg.Any()).Returns(usuario); var result = await _handler.Handle(new GetUsuarioByIdQuery(5)); Assert.Equal(5, result.Id); Assert.Equal("jperez", result.Username); Assert.Equal("Juan", result.Nombre); Assert.Equal("Pérez", result.Apellido); Assert.Equal("j@x.com", result.Email); Assert.Equal("cajero", result.Rol); Assert.True(result.Activo); Assert.False(result.MustChangePassword); } [Fact] public async Task Handle_DoesNotReturn_PasswordHash_In_Dto() { var usuario = new Usuario(5, "jperez", "$2a$12$SECRETHASH", "Juan", "Pérez", null, "cajero", "[]", true); _repo.GetDetailAsync(5, Arg.Any()).Returns(usuario); var result = await _handler.Handle(new GetUsuarioByIdQuery(5)); // UsuarioDetailDto must not expose PasswordHash var props = typeof(UsuarioDetailDto).GetProperties().Select(p => p.Name); Assert.DoesNotContain("PasswordHash", props); Assert.DoesNotContain("PermisosJson", props); } [Fact] public async Task Handle_Throws_UsuarioNotFoundException_When_Not_Found() { _repo.GetDetailAsync(9999, Arg.Any()).Returns((Usuario?)null); await Assert.ThrowsAsync( () => _handler.Handle(new GetUsuarioByIdQuery(9999))); } }