feat(i18n): localize assignment validation messages
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { describe, expect, it } from "vitest"
|
||||
|
||||
import { localizeAssignmentFieldErrors } from "@/actions/assignment.messages"
|
||||
|
||||
const actionCopy = {
|
||||
createSuccess: "Asignación creada correctamente",
|
||||
createFailure: "Error al crear la asignación",
|
||||
updateSuccess: "Asignación actualizada correctamente",
|
||||
updateFailure: "Error al actualizar la asignación",
|
||||
returnSuccess: "Asignación devuelta correctamente",
|
||||
returnFailure: "Error al devolver la asignación",
|
||||
notFound: "Asignación no encontrada",
|
||||
itemNotFound: "Artículo no encontrado",
|
||||
itemInsufficientStock: "El artículo no tiene stock suficiente",
|
||||
assetNotFound: "Activo no encontrado",
|
||||
assetItemMismatch: "El activo no pertenece al artículo",
|
||||
assignmentAlreadyReturned: "La asignación ya fue devuelta",
|
||||
invalidData: "Datos de asignación inválidos",
|
||||
genericFailure: "Error al procesar la asignación",
|
||||
}
|
||||
|
||||
describe("assignment action message localization", () => {
|
||||
it("localizes known assignment field errors from use-case output", () => {
|
||||
expect(
|
||||
localizeAssignmentFieldErrors(
|
||||
{
|
||||
itemId: ["Item not found"],
|
||||
quantity: ["Item does not have enough stock"],
|
||||
assetId: ["Asset not found"],
|
||||
id: ["Assignment not found", "Assignment already returned"],
|
||||
},
|
||||
actionCopy,
|
||||
),
|
||||
).toEqual({
|
||||
itemId: [actionCopy.itemNotFound],
|
||||
quantity: [actionCopy.itemInsufficientStock],
|
||||
assetId: [actionCopy.assetNotFound],
|
||||
id: [actionCopy.notFound, actionCopy.assignmentAlreadyReturned],
|
||||
})
|
||||
})
|
||||
|
||||
it("localizes asset-item mismatch and generic data errors", () => {
|
||||
expect(
|
||||
localizeAssignmentFieldErrors(
|
||||
{
|
||||
assetId: ["Asset does not belong to item"],
|
||||
error: ["Invalid assignment data"],
|
||||
},
|
||||
actionCopy,
|
||||
),
|
||||
).toEqual({
|
||||
assetId: [actionCopy.assetItemMismatch],
|
||||
error: [actionCopy.invalidData],
|
||||
})
|
||||
})
|
||||
|
||||
it("keeps unknown messages unchanged", () => {
|
||||
expect(
|
||||
localizeAssignmentFieldErrors(
|
||||
{ error: ["Unexpected assignment issue"] },
|
||||
actionCopy,
|
||||
),
|
||||
).toEqual({ error: ["Unexpected assignment issue"] })
|
||||
})
|
||||
|
||||
it("returns undefined when no errors are provided", () => {
|
||||
expect(localizeAssignmentFieldErrors(undefined, actionCopy)).toBeUndefined()
|
||||
})
|
||||
|
||||
it("returns undefined when errors object is empty", () => {
|
||||
expect(localizeAssignmentFieldErrors({}, actionCopy)).toEqual({})
|
||||
})
|
||||
})
|
||||
@@ -448,6 +448,29 @@ describe("i18n dictionaries", () => {
|
||||
fallback: {
|
||||
missingValue: "N/A",
|
||||
},
|
||||
actions: {
|
||||
createSuccess: "Assignment created successfully",
|
||||
createFailure: "Error creating assignment",
|
||||
updateSuccess: "Assignment updated successfully",
|
||||
updateFailure: "Error updating assignment",
|
||||
returnSuccess: "Assignment returned successfully",
|
||||
returnFailure: "Error returning assignment",
|
||||
notFound: "Assignment not found",
|
||||
itemNotFound: "Item not found",
|
||||
itemInsufficientStock: "Item does not have enough stock",
|
||||
assetNotFound: "Asset not found",
|
||||
assetItemMismatch: "Asset does not belong to item",
|
||||
assignmentAlreadyReturned: "Assignment already returned",
|
||||
invalidData: "Invalid assignment data",
|
||||
genericFailure: "Error processing assignment",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "Recipient is required",
|
||||
itemIdRequired: "Item is required",
|
||||
quantityMinOne: "Quantity must be at least 1",
|
||||
assetIdRequired: "Asset ID is required when item ID is provided",
|
||||
idRequired: "Assignment ID is required",
|
||||
},
|
||||
})
|
||||
|
||||
expect(getDictionary("es").inventory.assignments).toEqual({
|
||||
@@ -489,6 +512,30 @@ describe("i18n dictionaries", () => {
|
||||
fallback: {
|
||||
missingValue: "No disponible",
|
||||
},
|
||||
actions: {
|
||||
createSuccess: "Asignación creada correctamente",
|
||||
createFailure: "Error al crear la asignación",
|
||||
updateSuccess: "Asignación actualizada correctamente",
|
||||
updateFailure: "Error al actualizar la asignación",
|
||||
returnSuccess: "Asignación devuelta correctamente",
|
||||
returnFailure: "Error al devolver la asignación",
|
||||
notFound: "Asignación no encontrada",
|
||||
itemNotFound: "Artículo no encontrado",
|
||||
itemInsufficientStock: "El artículo no tiene stock suficiente",
|
||||
assetNotFound: "Activo no encontrado",
|
||||
assetItemMismatch: "El activo no pertenece al artículo",
|
||||
assignmentAlreadyReturned: "La asignación ya fue devuelta",
|
||||
invalidData: "Datos de asignación inválidos",
|
||||
genericFailure: "Error al procesar la asignación",
|
||||
},
|
||||
schema: {
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
itemIdRequired: "El artículo es obligatorio",
|
||||
quantityMinOne: "La cantidad debe ser al menos 1",
|
||||
assetIdRequired:
|
||||
"El activo es obligatorio cuando se especifica el artículo",
|
||||
idRequired: "El ID de asignación es obligatorio",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { describe, expect, it } from "vitest"
|
||||
|
||||
import {
|
||||
buildCreateAssignmentSchema,
|
||||
buildUpdateAssignmentSchema,
|
||||
} from "@/schemas/assignment.schema"
|
||||
|
||||
const schemaCopy = {
|
||||
recipientRequired: "El destinatario es obligatorio",
|
||||
itemIdRequired: "El artículo es obligatorio",
|
||||
quantityMinOne: "La cantidad debe ser al menos 1",
|
||||
assetIdRequired: "El activo es obligatorio cuando se especifica el artículo",
|
||||
idRequired: "El ID de asignación es obligatorio",
|
||||
}
|
||||
|
||||
describe("assignment schema localization", () => {
|
||||
it("uses localized create validation messages for missing required fields", () => {
|
||||
const result = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "",
|
||||
quantity: 0,
|
||||
})
|
||||
|
||||
expect(result.success).toBe(false)
|
||||
if (!result.success) {
|
||||
const errors = result.error.flatten().fieldErrors
|
||||
|
||||
expect(errors.recipientId).toContain(schemaCopy.recipientRequired)
|
||||
expect(errors.quantity).toContain(schemaCopy.quantityMinOne)
|
||||
}
|
||||
})
|
||||
|
||||
it("uses localized update validation messages for missing identifier and invalid item-asset combination", () => {
|
||||
const result = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "",
|
||||
itemId: "item-1",
|
||||
recipientId: "recipient-1",
|
||||
quantity: 1,
|
||||
assetId: "",
|
||||
})
|
||||
|
||||
expect(result.success).toBe(false)
|
||||
if (!result.success) {
|
||||
const errors = result.error.flatten().fieldErrors
|
||||
|
||||
expect(errors.id).toContain(schemaCopy.idRequired)
|
||||
expect(errors.assetId).toContain(schemaCopy.assetIdRequired)
|
||||
}
|
||||
})
|
||||
|
||||
it("preserves valid create and update payloads without errors", () => {
|
||||
const createResult = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "recipient-1",
|
||||
itemId: "item-1",
|
||||
quantity: 2,
|
||||
})
|
||||
|
||||
expect(createResult.success).toBe(true)
|
||||
if (createResult.success) {
|
||||
expect(createResult.data.recipientId).toBe("recipient-1")
|
||||
expect(createResult.data.quantity).toBe(2)
|
||||
}
|
||||
|
||||
const updateResult = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "assignment-1",
|
||||
recipientId: "recipient-1",
|
||||
itemId: "item-1",
|
||||
assetId: "asset-1",
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
expect(updateResult.success).toBe(true)
|
||||
if (updateResult.success) {
|
||||
expect(updateResult.data.id).toBe("assignment-1")
|
||||
}
|
||||
})
|
||||
|
||||
it("keeps optional assignment fields optional in create", () => {
|
||||
const result = buildCreateAssignmentSchema(schemaCopy).safeParse({
|
||||
recipientId: "recipient-1",
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
expect(result.success).toBe(true)
|
||||
})
|
||||
|
||||
it("allows update without itemId when no assetId is required", () => {
|
||||
const result = buildUpdateAssignmentSchema(schemaCopy).safeParse({
|
||||
id: "assignment-1",
|
||||
recipientId: "recipient-1",
|
||||
quantity: 1,
|
||||
})
|
||||
|
||||
expect(result.success).toBe(true)
|
||||
if (result.success) {
|
||||
expect(result.data.id).toBe("assignment-1")
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user