feat(teams): add team Zod schema and unit tests

This commit is contained in:
2026-06-25 23:58:59 +02:00
parent 65f9a6d6a4
commit f88d831f4c
2 changed files with 115 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
import { z } from "zod"
import type { Dictionary } from "@/i18n/dictionaries"
export type TeamSchemaCopy = Dictionary["inventory"]["teams"]["schema"]
const defaultTeamSchemaCopy: TeamSchemaCopy = {
nameRequired: "Name is required",
nameMaxLength: "Name must be at most 80 characters",
idRequired: "ID is required",
}
export function buildCreateTeamSchema(copy: TeamSchemaCopy) {
return z.object({
name: z
.string()
.trim()
.min(1, { error: copy.nameRequired })
.max(80, { error: copy.nameMaxLength }),
})
}
export function buildUpdateTeamSchema(copy: TeamSchemaCopy) {
return buildCreateTeamSchema(copy).extend({
id: z.string().nonempty(copy.idRequired),
})
}
export const createTeamSchema = buildCreateTeamSchema(defaultTeamSchemaCopy)
export type CreateTeamFormType = z.infer<typeof createTeamSchema>
export const updateTeamSchema = buildUpdateTeamSchema(defaultTeamSchemaCopy)
export type UpdateTeamFormType = z.infer<typeof updateTeamSchema>
+80
View File
@@ -0,0 +1,80 @@
import { describe, expect, it } from "vitest"
import {
buildCreateTeamSchema,
buildUpdateTeamSchema,
} from "@/schemas/team.schema"
const schemaCopy = {
nameRequired: "El nombre del equipo es obligatorio",
nameMaxLength: "El nombre del equipo no puede superar los 80 caracteres",
idRequired: "El ID es obligatorio",
}
describe("team schema", () => {
it("rejects blank names", () => {
const result = buildCreateTeamSchema(schemaCopy).safeParse({ name: "" })
expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.flatten().fieldErrors.name).toContain(
schemaCopy.nameRequired,
)
}
})
it("rejects whitespace-only names", () => {
const result = buildCreateTeamSchema(schemaCopy).safeParse({ name: " " })
expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.flatten().fieldErrors.name).toContain(
schemaCopy.nameRequired,
)
}
})
it("rejects names longer than 80 characters", () => {
const result = buildCreateTeamSchema(schemaCopy).safeParse({
name: "a".repeat(81),
})
expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.flatten().fieldErrors.name).toContain(
schemaCopy.nameMaxLength,
)
}
})
it("accepts valid create input", () => {
const result = buildCreateTeamSchema(schemaCopy).safeParse({
name: "Engineering",
})
expect(result.success).toBe(true)
})
it("rejects update with empty id", () => {
const result = buildUpdateTeamSchema(schemaCopy).safeParse({
id: "",
name: "Engineering",
})
expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.flatten().fieldErrors.id).toContain(
schemaCopy.idRequired,
)
}
})
it("accepts valid update input", () => {
const result = buildUpdateTeamSchema(schemaCopy).safeParse({
id: "some-id",
name: "Engineering",
})
expect(result.success).toBe(true)
})
})