156 lines
4.1 KiB
TypeScript
156 lines
4.1 KiB
TypeScript
import { describe, expect, it } from "vitest"
|
|
|
|
import {
|
|
buildCreateItemSchema,
|
|
buildGetItemByIdSchema,
|
|
buildUpdateItemSchema,
|
|
} from "@/schemas/item.schema"
|
|
|
|
const schemaCopy = {
|
|
nameRequired: "El nombre es obligatorio",
|
|
categoryRequired: "La categoría es obligatoria",
|
|
stockRequired: "El stock es obligatorio",
|
|
trackingTypeRequired: "El tipo de seguimiento es obligatorio",
|
|
invalidTrackingType: "Tipo de seguimiento inválido",
|
|
statusRequired: "El estado es obligatorio",
|
|
invalidStatus: "Estado inválido",
|
|
itemRequired: "El artículo es obligatorio",
|
|
}
|
|
|
|
describe("item schema localization", () => {
|
|
it("uses localized create validation messages", () => {
|
|
const result = buildCreateItemSchema(schemaCopy).safeParse({
|
|
name: "",
|
|
categoryId: "",
|
|
stock: -1,
|
|
})
|
|
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const errors = result.error.flatten().fieldErrors
|
|
|
|
expect(errors.name).toContain(schemaCopy.nameRequired)
|
|
expect(errors.categoryId).toContain(schemaCopy.categoryRequired)
|
|
expect(errors.stock).toContain(schemaCopy.stockRequired)
|
|
}
|
|
})
|
|
|
|
it("supports operational item fields with default tracking metadata", () => {
|
|
const result = buildCreateItemSchema(schemaCopy).safeParse({
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: "2",
|
|
})
|
|
|
|
expect(result.success).toBe(true)
|
|
if (result.success) {
|
|
expect(result.data).toMatchObject({
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: 2,
|
|
trackingType: "QUANTITY",
|
|
status: "ACTIVE",
|
|
})
|
|
}
|
|
})
|
|
|
|
it("accepts explicit operational item fields", () => {
|
|
const result = buildCreateItemSchema(schemaCopy).safeParse({
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: "2",
|
|
trackingType: "SERIALIZED",
|
|
status: "DISCONTINUED",
|
|
minStock: "1",
|
|
targetStock: "5",
|
|
})
|
|
|
|
expect(result.success).toBe(true)
|
|
if (result.success) {
|
|
expect(result.data).toMatchObject({
|
|
trackingType: "SERIALIZED",
|
|
status: "DISCONTINUED",
|
|
minStock: 1,
|
|
targetStock: 5,
|
|
})
|
|
}
|
|
})
|
|
|
|
it("uses localized update identifier validation messages", () => {
|
|
const result = buildUpdateItemSchema(schemaCopy).safeParse({
|
|
id: "",
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: 1,
|
|
})
|
|
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
expect(result.error.flatten().fieldErrors.id).toContain(
|
|
schemaCopy.itemRequired,
|
|
)
|
|
}
|
|
})
|
|
|
|
it("allows operational item fields in update payloads", () => {
|
|
const result = buildUpdateItemSchema(schemaCopy).safeParse({
|
|
id: "item-1",
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: 3,
|
|
trackingType: "SERIALIZED",
|
|
status: "ARCHIVED",
|
|
minStock: "2",
|
|
targetStock: "6",
|
|
})
|
|
|
|
expect(result.success).toBe(true)
|
|
if (result.success) {
|
|
expect(result.data).toMatchObject({
|
|
id: "item-1",
|
|
trackingType: "SERIALIZED",
|
|
status: "ARCHIVED",
|
|
minStock: 2,
|
|
targetStock: 6,
|
|
})
|
|
}
|
|
})
|
|
|
|
it("uses localized get-by-id validation messages", () => {
|
|
const result = buildGetItemByIdSchema(schemaCopy).safeParse({ id: "" })
|
|
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
expect(result.error.flatten().fieldErrors.id).toContain(
|
|
schemaCopy.itemRequired,
|
|
)
|
|
}
|
|
})
|
|
|
|
it("preserves stock coercion and integer validation semantics", () => {
|
|
const validResult = buildCreateItemSchema(schemaCopy).safeParse({
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: "2",
|
|
})
|
|
|
|
expect(validResult.success).toBe(true)
|
|
if (validResult.success) {
|
|
expect(validResult.data.stock).toBe(2)
|
|
}
|
|
|
|
const invalidResult = buildCreateItemSchema(schemaCopy).safeParse({
|
|
name: "Laptop",
|
|
categoryId: "category-1",
|
|
stock: 1.5,
|
|
})
|
|
|
|
expect(invalidResult.success).toBe(false)
|
|
if (!invalidResult.success) {
|
|
expect(invalidResult.error.flatten().fieldErrors.stock).toContain(
|
|
schemaCopy.stockRequired,
|
|
)
|
|
}
|
|
})
|
|
})
|