import { describe, expect, it } from "vitest" import { buildUnifiedCreateSchema, unifiedFormRoleSchema, 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 validPersonOnlyData = { firstName: "John", lastName: "Doe", department: "IT", email: "john@example.test", phone: null, role: "NO_USER" as const, password: undefined, isActive: true, } const validPersonWithUserData = { firstName: "Jane", lastName: "Smith", department: "ENGINEERING", email: "jane@example.test", phone: "1234567890", role: "ADMIN" as const, password: "securepassword", isActive: true, } describe("unifiedFormRoleSchema", () => { it("accepts all standard roles plus NO_USER", () => { const roles = ["ADMIN", "MANAGER", "STAFF", "VIEWER", "NO_USER"] for (const role of roles) { expect(unifiedFormRoleSchema.safeParse(role).success).toBe(true) } }) it("rejects invalid roles", () => { const result = unifiedFormRoleSchema.safeParse("SUPER_ADMIN") expect(result.success).toBe(false) }) }) describe("buildUnifiedCreateSchema", () => { describe("with NO_USER role (person-only creation)", () => { it("accepts valid data without password when role is NO_USER", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse(validPersonOnlyData) expect(result.success).toBe(true) if (result.success) { expect(result.data.firstName).toBe("John") expect(result.data.lastName).toBe("Doe") expect(result.data.role).toBe("NO_USER") expect(result.data.password).toBeUndefined() } }) it("accepts valid data with empty string password when role is NO_USER", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnlyData, password: "", }) expect(result.success).toBe(true) }) it("uses localized error messages for required fields", () => { const schema = buildUnifiedCreateSchema(esCopy) const result = schema.safeParse({ firstName: "", lastName: "", department: "", email: "not-an-email", role: "NO_USER", phone: null, isActive: true, }) expect(result.success).toBe(false) if (!result.success) { const errors = result.error.flatten().fieldErrors expect(errors.firstName).toContain(esCopy.firstNameRequired) expect(errors.lastName).toContain(esCopy.lastNameRequired) expect(errors.department).toContain(esCopy.departmentRequired) expect(errors.email).toContain(esCopy.emailInvalid) } }) }) describe("with a real User role (person + user creation)", () => { it("accepts valid data with password when role is ADMIN", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse(validPersonWithUserData) expect(result.success).toBe(true) if (result.success) { expect(result.data.firstName).toBe("Jane") expect(result.data.role).toBe("ADMIN") expect(result.data.password).toBe("securepassword") } }) it("accepts valid data with password for all real roles", () => { const schema = buildUnifiedCreateSchema(enCopy) for (const role of ["ADMIN", "MANAGER", "STAFF", "VIEWER"] as const) { const result = schema.safeParse({ ...validPersonWithUserData, role, }) expect(result.success).toBe(true) } }) it("rejects short password when role is not NO_USER", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUserData, password: "short", }) expect(result.success).toBe(false) if (!result.success) { const errors = result.error.flatten().fieldErrors expect(errors.password).toContain(enCopy.passwordMinLength) } }) it("rejects missing password when role is not NO_USER", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUserData, password: undefined, }) expect(result.success).toBe(false) if (!result.success) { const errors = result.error.flatten().fieldErrors expect(errors.password).toContain(enCopy.passwordMinLength) } }) it("rejects empty string password when role is not NO_USER", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonWithUserData, password: "", }) expect(result.success).toBe(false) if (!result.success) { const errors = result.error.flatten().fieldErrors expect(errors.password).toContain(enCopy.passwordMinLength) } }) it("uses localized password error message", () => { const schema = buildUnifiedCreateSchema(esCopy) const result = schema.safeParse({ firstName: "Jane", lastName: "Smith", department: "ENGINEERING", email: "jane@example.test", role: "ADMIN", password: "corta", phone: null, isActive: true, }) expect(result.success).toBe(false) if (!result.success) { const errors = result.error.flatten().fieldErrors expect(errors.password).toContain(esCopy.passwordMinLength) } }) }) describe("email validation", () => { it("rejects invalid email format", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnlyData, email: "not-an-email", }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.flatten().fieldErrors.email).toContain( enCopy.emailInvalid, ) } }) it("accepts valid email", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnlyData, email: "valid@example.com", }) expect(result.success).toBe(true) }) }) describe("department validation", () => { it("rejects invalid department", () => { const schema = buildUnifiedCreateSchema(enCopy) const result = schema.safeParse({ ...validPersonOnlyData, department: "INVALID_DEPT", }) expect(result.success).toBe(false) }) it("accepts valid departments", () => { const schema = buildUnifiedCreateSchema(enCopy) const validDepartments = [ "IT", "ENGINEERING", "TRAFFIC", "DRIVER", "LOGISTICS", "ADMINISTRATION", "SALES", "OTHER", ] for (const dept of validDepartments) { const result = schema.safeParse({ ...validPersonOnlyData, department: dept, }) expect(result.success).toBe(true) } }) }) })