import { describe, expect, it } from "vitest" import { buildUnifiedUpdateSchema, type UnifiedSchemaCopy, } from "@/schemas/user.schema" const enCopy: UnifiedSchemaCopy = { firstNameRequired: "First name is required", lastNameRequired: "Last name is required", departmentRequired: "Department is required", emailInvalid: "Invalid email", passwordMinLength: "Password must be at least 8 characters", nameRequired: "Name is required", userIdRequired: "User id is required", idRequired: "ID is required", userIdInvalid: "User ID must be a valid UUID", } const esCopy: UnifiedSchemaCopy = { firstNameRequired: "El nombre es obligatorio", lastNameRequired: "El apellido es obligatorio", departmentRequired: "El departamento es obligatorio", emailInvalid: "Correo electrónico no válido", passwordMinLength: "La contraseña debe tener al menos 8 caracteres", nameRequired: "El nombre es obligatorio", userIdRequired: "El ID de usuario es obligatorio", idRequired: "El ID es obligatorio", userIdInvalid: "El ID de usuario debe ser un UUID válido", } const validPersonOnly = { id: "person-1", firstName: "John", lastName: "Doe", department: "IT", email: "john@example.test", phone: null, } const validPersonWithUser = { ...validPersonOnly, role: "ADMIN" as const, isActive: true, } describe("buildUnifiedUpdateSchema", () => { describe("person-only update (no user fields provided)", () => { it("accepts person fields without role/isActive/password when person has no User", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse(validPersonOnly) expect(result.success).toBe(true) if (result.success) { expect(result.data.id).toBe("person-1") expect(result.data.firstName).toBe("John") expect(result.data.role).toBeUndefined() expect(result.data.isActive).toBeUndefined() expect(result.data.password).toBeUndefined() } }) it("accepts person fields with isActive=false when person has no User", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnly, isActive: false }) expect(result.success).toBe(true) }) it("rejects empty id", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ id: "", firstName: "John", lastName: "Doe", department: "IT", email: "john@example.test", phone: null, }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.flatten().fieldErrors.id).toContain( enCopy.idRequired, ) } }) }) describe("person+user update (when person has User linked)", () => { it("accepts person and user fields with role and isActive when no password change", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse(validPersonWithUser) expect(result.success).toBe(true) if (result.success) { expect(result.data.role).toBe("ADMIN") expect(result.data.isActive).toBe(true) expect(result.data.password).toBeUndefined() } }) it("accepts password reset (>= 8 chars) when role is provided", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUser, password: "newpassword1", }) expect(result.success).toBe(true) if (result.success) { expect(result.data.password).toBe("newpassword1") } }) it("rejects short password when role is provided and password is non-empty", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUser, password: "short", }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.flatten().fieldErrors.password).toContain( enCopy.passwordMinLength, ) } }) it("accepts empty password string as 'do not change' (ignored)", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUser, password: "", }) expect(result.success).toBe(true) }) it("rejects invalid role enum", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUser, role: "SUPER_ADMIN", }) expect(result.success).toBe(false) }) it("rejects NO_USER role on update (cannot remove user from existing person)", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUser, role: "NO_USER" as unknown as "ADMIN", }) expect(result.success).toBe(false) }) it("uses localized password error message", () => { const schema = buildUnifiedUpdateSchema(esCopy) const result = schema.safeParse({ ...validPersonWithUser, password: "corta", }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.flatten().fieldErrors.password).toContain( esCopy.passwordMinLength, ) } }) }) describe("email validation", () => { it("rejects invalid email format", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnly, email: "not-an-email", }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.flatten().fieldErrors.email).toContain( enCopy.emailInvalid, ) } }) it("accepts null email (person can have no email)", () => { const schema = buildUnifiedUpdateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnly, email: null }) expect(result.success).toBe(true) }) }) })