using SIGCM2.Domain.Entities; namespace SIGCM2.Application.Tests.Domain; // ── UDT-008 tests ──────────────────────────────────────────────────────────── public class UsuarioTests { // Happy path: constructor sets all properties correctly [Fact] public void Constructor_SetsAllProperties() { var usuario = new Usuario( id: 1, username: "admin", passwordHash: "$2a$12$hash", nombre: "Administrador", apellido: "Sistema", email: null, rol: "admin", permisosJson: "[\"*\"]", activo: true ); Assert.Equal(1, usuario.Id); Assert.Equal("admin", usuario.Username); Assert.Equal("$2a$12$hash", usuario.PasswordHash); Assert.Equal("Administrador", usuario.Nombre); Assert.Equal("Sistema", usuario.Apellido); Assert.Null(usuario.Email); Assert.Equal("admin", usuario.Rol); Assert.Equal("[\"*\"]", usuario.PermisosJson); Assert.True(usuario.Activo); } // Triangulation: inactive user [Fact] public void Constructor_WithActivo_False_SetsActivo_False() { var usuario = new Usuario( id: 2, username: "vendedor", passwordHash: "$2a$12$hash2", nombre: "Juan", apellido: "Pérez", email: "juan@example.com", rol: "vendedor", permisosJson: "[]", activo: false ); Assert.Equal(2, usuario.Id); Assert.Equal("vendedor", usuario.Username); Assert.Equal("juan@example.com", usuario.Email); Assert.Equal("vendedor", usuario.Rol); Assert.Equal("[]", usuario.PermisosJson); Assert.False(usuario.Activo); } // Activo property reflects the actual state [Fact] public void Activo_IsTrue_WhenConstructedActive() { var usuario = new Usuario(1, "admin", "$2a$12$hash", "Admin", "Sys", null, "admin", "[\"*\"]", true); Assert.True(usuario.Activo); } [Fact] public void Activo_IsFalse_WhenConstructedInactive() { var usuario = new Usuario(2, "inactive", "$2a$12$hash", "Old", "User", null, "consulta", "[]", false); Assert.False(usuario.Activo); } // ── UDT-008: new properties ─────────────────────────────────────────────── [Fact] public void ForCreation_Defaults_MustChangePassword_False() { var u = Usuario.ForCreation("user", "hash", "A", "B", null, "cajero"); Assert.False(u.MustChangePassword); } [Fact] public void ForCreation_Defaults_FechaModificacion_Null() { var u = Usuario.ForCreation("user", "hash", "A", "B", null, "cajero"); Assert.Null(u.FechaModificacion); } [Fact] public void ForCreation_Defaults_UltimoLogin_Null() { var u = Usuario.ForCreation("user", "hash", "A", "B", null, "cajero"); Assert.Null(u.UltimoLogin); } // ── UDT-008: WithUpdatedProfile ────────────────────────────────────────── [Fact] public void WithUpdatedProfile_Returns_NewInstance() { var u = MakeUsuario(); var updated = u.WithUpdatedProfile("NuevoNombre", "NuevoApellido", "new@x.com", "cajero", true, DateTime.UtcNow); Assert.NotSame(u, updated); } [Fact] public void WithUpdatedProfile_Sets_Fields_Correctly() { var u = MakeUsuario(); var updated = u.WithUpdatedProfile("Pedro", "Gómez", "p@g.com", "cajero", false, DateTime.UtcNow); Assert.Equal("Pedro", updated.Nombre); Assert.Equal("Gómez", updated.Apellido); Assert.Equal("p@g.com", updated.Email); Assert.Equal("cajero", updated.Rol); Assert.False(updated.Activo); } [Fact] public void WithUpdatedProfile_Sets_FechaModificacion_To_UtcNow() { var before = DateTime.UtcNow.AddSeconds(-1); var now = DateTime.UtcNow; var u = MakeUsuario(); var updated = u.WithUpdatedProfile("A", "B", null, "admin", true, now); Assert.NotNull(updated.FechaModificacion); Assert.True(updated.FechaModificacion >= before); } [Fact] public void WithUpdatedProfile_Preserves_Immutable_Fields() { var u = MakeUsuario(); var updated = u.WithUpdatedProfile("X", "Y", null, "cajero", true, DateTime.UtcNow); Assert.Equal(u.Id, updated.Id); Assert.Equal(u.Username, updated.Username); Assert.Equal(u.PasswordHash, updated.PasswordHash); } // ── UDT-008: WithNewPasswordHash ───────────────────────────────────────── [Fact] public void WithNewPasswordHash_Returns_NewInstance() { var u = MakeUsuario(); var updated = u.WithNewPasswordHash("newhash", mustChangePassword: false, DateTime.UtcNow); Assert.NotSame(u, updated); } [Fact] public void WithNewPasswordHash_Sets_Hash_And_MustChange() { var u = MakeUsuario(); var updated = u.WithNewPasswordHash("newhash", mustChangePassword: true, DateTime.UtcNow); Assert.Equal("newhash", updated.PasswordHash); Assert.True(updated.MustChangePassword); } [Fact] public void WithNewPasswordHash_Clears_MustChange_When_False() { var u = MakeUsuario(mustChangePassword: true); var updated = u.WithNewPasswordHash("hash2", mustChangePassword: false, DateTime.UtcNow); Assert.False(updated.MustChangePassword); } [Fact] public void WithNewPasswordHash_Sets_FechaModificacion() { var before = DateTime.UtcNow.AddSeconds(-1); var now = DateTime.UtcNow; var u = MakeUsuario(); var updated = u.WithNewPasswordHash("hash2", false, now); Assert.NotNull(updated.FechaModificacion); Assert.True(updated.FechaModificacion >= before); } // ── UDT-008: WithUltimoLogin ────────────────────────────────────────────── [Fact] public void WithUltimoLogin_Returns_NewInstance() { var u = MakeUsuario(); var updated = u.WithUltimoLogin(DateTime.UtcNow); Assert.NotSame(u, updated); } [Fact] public void WithUltimoLogin_Sets_UltimoLogin() { var ts = new DateTime(2026, 1, 15, 10, 0, 0, DateTimeKind.Utc); var u = MakeUsuario(); var updated = u.WithUltimoLogin(ts); Assert.Equal(ts, updated.UltimoLogin); } [Fact] public void WithUltimoLogin_Does_NOT_Touch_FechaModificacion() { var u = MakeUsuario(); var originalFecha = u.FechaModificacion; var updated = u.WithUltimoLogin(DateTime.UtcNow); Assert.Equal(originalFecha, updated.FechaModificacion); } // ── UDT-008: WithMustChangePassword ────────────────────────────────────── [Fact] public void WithMustChangePassword_Sets_Value_True() { var u = MakeUsuario(mustChangePassword: false); var updated = u.WithMustChangePassword(true, DateTime.UtcNow); Assert.True(updated.MustChangePassword); } [Fact] public void WithMustChangePassword_Sets_FechaModificacion() { var before = DateTime.UtcNow.AddSeconds(-1); var now = DateTime.UtcNow; var u = MakeUsuario(); var updated = u.WithMustChangePassword(true, now); Assert.NotNull(updated.FechaModificacion); Assert.True(updated.FechaModificacion >= before); } // ── helpers ─────────────────────────────────────────────────────────────── private static Usuario MakeUsuario(bool mustChangePassword = false) => new( id: 1, username: "testuser", passwordHash: "$2a$12$hash", nombre: "Test", apellido: "User", email: "test@x.com", rol: "admin", permisosJson: "[]", activo: true, fechaModificacion: null, ultimoLogin: null, mustChangePassword: mustChangePassword ); }