207 lines
5.9 KiB
TypeScript
207 lines
5.9 KiB
TypeScript
import { describe, expect, it } from "vitest"
|
|
|
|
import {
|
|
buildCreateAssetSchema,
|
|
buildUpdateAssetSchema,
|
|
} from "@/schemas/asset.schema"
|
|
|
|
const schemaCopy = {
|
|
itemRequired: "El artículo es obligatorio",
|
|
serialNumberRequired: "El número de serie es obligatorio",
|
|
idRequired: "El activo es obligatorio",
|
|
statusRequired: "El estado es obligatorio",
|
|
invalidCreateStatus: "El estado inicial no es válido",
|
|
invalidUpdateStatus: "El estado no es válido",
|
|
personRequired: "La persona es obligatoria",
|
|
}
|
|
|
|
describe("asset schema localization", () => {
|
|
it("uses localized create validation messages", () => {
|
|
const result = buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "",
|
|
serialNumber: "",
|
|
status: "BROKEN",
|
|
})
|
|
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const errors = result.error.flatten().fieldErrors
|
|
|
|
expect(errors.itemId).toContain(schemaCopy.itemRequired)
|
|
expect(errors.serialNumber).toContain(schemaCopy.serialNumberRequired)
|
|
expect(errors.status).toContain(schemaCopy.invalidCreateStatus)
|
|
}
|
|
})
|
|
|
|
it("uses localized update identifier and status validation messages", () => {
|
|
const result = buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "UNSUPPORTED",
|
|
})
|
|
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const errors = result.error.flatten().fieldErrors
|
|
|
|
expect(errors.id).toContain(schemaCopy.idRequired)
|
|
expect(errors.status).toContain(schemaCopy.invalidUpdateStatus)
|
|
}
|
|
})
|
|
|
|
it("preserves raw status values for accepted create and update payloads", () => {
|
|
const createResult = buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "ASSIGNED",
|
|
personId: "person-1",
|
|
})
|
|
|
|
expect(createResult.success).toBe(true)
|
|
if (createResult.success) {
|
|
expect(createResult.data.status).toBe("ASSIGNED")
|
|
}
|
|
|
|
const updateResult = buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "asset-1",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "DISPOSED",
|
|
})
|
|
|
|
expect(updateResult.success).toBe(true)
|
|
if (updateResult.success) {
|
|
expect(updateResult.data.status).toBe("DISPOSED")
|
|
}
|
|
})
|
|
|
|
it("requires person when create or update status is assigned", () => {
|
|
const createResult = buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "ASSIGNED",
|
|
})
|
|
|
|
expect(createResult.success).toBe(false)
|
|
if (!createResult.success) {
|
|
expect(createResult.error.flatten().fieldErrors.personId).toContain(
|
|
schemaCopy.personRequired,
|
|
)
|
|
}
|
|
|
|
const updateResult = buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "asset-1",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "ASSIGNED",
|
|
})
|
|
|
|
expect(updateResult.success).toBe(false)
|
|
if (!updateResult.success) {
|
|
expect(updateResult.error.flatten().fieldErrors.personId).toContain(
|
|
schemaCopy.personRequired,
|
|
)
|
|
}
|
|
})
|
|
|
|
it("aligns create and update status options with the asset status contract", () => {
|
|
expect(
|
|
buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "IN_REPAIR",
|
|
}).success,
|
|
).toBe(false)
|
|
|
|
for (const status of ["LOST", "RETIRED"] as const) {
|
|
expect(
|
|
buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "asset-1",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status,
|
|
}).success,
|
|
).toBe(true)
|
|
}
|
|
|
|
expect(
|
|
buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "asset-1",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "RESERVED",
|
|
}).success,
|
|
).toBe(false)
|
|
})
|
|
|
|
it("keeps optional asset fields optional", () => {
|
|
const result = buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-1",
|
|
status: "AVAILABLE",
|
|
})
|
|
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it("accepts operational asset fields on create and update payloads", () => {
|
|
const createResult = buildCreateAssetSchema(schemaCopy).safeParse({
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-2",
|
|
status: "AVAILABLE",
|
|
assetTag: "IT-000123",
|
|
manufacturer: "Lenovo",
|
|
model: "ThinkPad T14",
|
|
purchaseDate: "2026-01-15",
|
|
purchasePrice: "1249.99",
|
|
warrantyEndsAt: "2028-01-15",
|
|
})
|
|
|
|
expect(createResult.success).toBe(true)
|
|
if (createResult.success) {
|
|
expect(createResult.data).toMatchObject({
|
|
assetTag: "IT-000123",
|
|
manufacturer: "Lenovo",
|
|
model: "ThinkPad T14",
|
|
purchasePrice: 1249.99,
|
|
})
|
|
expect(createResult.data.purchaseDate?.toISOString()).toBe(
|
|
"2026-01-15T00:00:00.000Z",
|
|
)
|
|
expect(createResult.data.warrantyEndsAt?.toISOString()).toBe(
|
|
"2028-01-15T00:00:00.000Z",
|
|
)
|
|
}
|
|
|
|
const updateResult = buildUpdateAssetSchema(schemaCopy).safeParse({
|
|
id: "asset-1",
|
|
itemId: "item-1",
|
|
serialNumber: "SERIAL-2",
|
|
status: "BROKEN",
|
|
assetTag: "IT-000124",
|
|
manufacturer: "Dell",
|
|
model: "Latitude 7420",
|
|
purchaseDate: "2026-02-01",
|
|
purchasePrice: "1499.5",
|
|
warrantyEndsAt: "2027-02-01",
|
|
})
|
|
|
|
expect(updateResult.success).toBe(true)
|
|
if (updateResult.success) {
|
|
expect(updateResult.data).toMatchObject({
|
|
assetTag: "IT-000124",
|
|
manufacturer: "Dell",
|
|
model: "Latitude 7420",
|
|
purchasePrice: 1499.5,
|
|
})
|
|
expect(updateResult.data.purchaseDate?.toISOString()).toBe(
|
|
"2026-02-01T00:00:00.000Z",
|
|
)
|
|
expect(updateResult.data.warrantyEndsAt?.toISOString()).toBe(
|
|
"2027-02-01T00:00:00.000Z",
|
|
)
|
|
}
|
|
})
|
|
})
|