986 lines
30 KiB
TypeScript
986 lines
30 KiB
TypeScript
import { describe, expect, it } from "vitest"
|
|
|
|
import { dictionaries, getDictionary } from "@/i18n/dictionaries"
|
|
import { SUPPORTED_LOCALES } from "@/i18n/locales"
|
|
|
|
describe("i18n dictionaries", () => {
|
|
it("provides dictionaries for every supported locale and no extra locales", () => {
|
|
expect(Object.keys(dictionaries).sort()).toEqual(
|
|
[...SUPPORTED_LOCALES].sort(),
|
|
)
|
|
})
|
|
|
|
it("returns localized login copy for English and Spanish", () => {
|
|
expect(getDictionary("en").login).toEqual({
|
|
title: "Sign In",
|
|
emailLabel: "Email",
|
|
passwordLabel: "Password",
|
|
submitLabel: "Sign In",
|
|
})
|
|
|
|
expect(getDictionary("es").login).toEqual({
|
|
title: "Iniciar sesión",
|
|
emailLabel: "Correo electrónico",
|
|
passwordLabel: "Contraseña",
|
|
submitLabel: "Iniciar sesión",
|
|
})
|
|
})
|
|
|
|
it("provides localized language switcher copy for English and Spanish", () => {
|
|
expect(getDictionary("en").common.languageSwitcher).toEqual({
|
|
label: "Language",
|
|
options: {
|
|
en: "English",
|
|
es: "Spanish",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").common.languageSwitcher).toEqual({
|
|
label: "Idioma",
|
|
options: {
|
|
en: "Inglés",
|
|
es: "Español",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("provides localized shell and common copy for English and Spanish", () => {
|
|
expect(getDictionary("en").layout).toEqual({
|
|
sidebar: {
|
|
home: "Home",
|
|
inventory: "Inventory",
|
|
items: "Items",
|
|
categories: "Categories",
|
|
assets: "Assets",
|
|
people: "People",
|
|
movements: "Movements",
|
|
assignments: "Assignments",
|
|
users: "Users",
|
|
},
|
|
navbar: {
|
|
accountLabel: "My Account",
|
|
},
|
|
addMenu: {
|
|
add: "Add",
|
|
import: "Import",
|
|
category: "Category",
|
|
item: "Item",
|
|
asset: "Asset",
|
|
person: "Person",
|
|
assignment: "Assignment",
|
|
},
|
|
resetDatabase: {
|
|
idle: "Reset Database",
|
|
loading: "Resetting...",
|
|
successToast: "Database reset successfully",
|
|
errorToast: "Error resetting database",
|
|
},
|
|
logout: {
|
|
label: "Sign Out",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").layout).toEqual({
|
|
sidebar: {
|
|
home: "Inicio",
|
|
inventory: "Inventario",
|
|
items: "Artículos",
|
|
categories: "Categorías",
|
|
assets: "Activos",
|
|
people: "Personas",
|
|
movements: "Movimientos",
|
|
assignments: "Asignaciones",
|
|
users: "Usuarios",
|
|
},
|
|
navbar: {
|
|
accountLabel: "Mi cuenta",
|
|
},
|
|
addMenu: {
|
|
add: "Añadir",
|
|
import: "Importar",
|
|
category: "Categoría",
|
|
item: "Artículo",
|
|
asset: "Activo",
|
|
person: "Persona",
|
|
assignment: "Asignación",
|
|
},
|
|
resetDatabase: {
|
|
idle: "Reiniciar base de datos",
|
|
loading: "Reiniciando...",
|
|
successToast: "Base de datos reiniciada correctamente",
|
|
errorToast: "Error al reiniciar la base de datos",
|
|
},
|
|
logout: {
|
|
label: "Cerrar sesión",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("en").common.search).toEqual({
|
|
placeholder: "Search...",
|
|
label: "Search",
|
|
clearLabel: "Clear search",
|
|
})
|
|
expect(getDictionary("es").common.search).toEqual({
|
|
placeholder: "Buscar...",
|
|
label: "Buscar",
|
|
clearLabel: "Limpiar búsqueda",
|
|
})
|
|
|
|
expect(getDictionary("en").common.pagination).toEqual({
|
|
summaryPrefix: "Showing page",
|
|
summarySeparator: "of",
|
|
previous: "Previous",
|
|
next: "Next",
|
|
})
|
|
expect(getDictionary("es").common.pagination).toEqual({
|
|
summaryPrefix: "Mostrando página",
|
|
summarySeparator: "de",
|
|
previous: "Anterior",
|
|
next: "Siguiente",
|
|
})
|
|
|
|
expect(getDictionary("en").common.submitButton).toEqual({
|
|
defaultLabel: "Submit",
|
|
processing: "Processing",
|
|
success: "Success",
|
|
})
|
|
|
|
expect(getDictionary("en").common.forbidden).toEqual({
|
|
title: "Access denied",
|
|
description: "You do not have permission to access this section.",
|
|
homeLink: "Back to home",
|
|
})
|
|
expect(getDictionary("es").common.submitButton).toEqual({
|
|
defaultLabel: "Enviar",
|
|
processing: "Procesando",
|
|
success: "Completado",
|
|
})
|
|
|
|
expect(getDictionary("es").common.forbidden).toEqual({
|
|
title: "Acceso denegado",
|
|
description: "No tienes permisos para acceder a esta sección.",
|
|
homeLink: "Volver al inicio",
|
|
})
|
|
})
|
|
|
|
it("provides localized inventory category copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.categories).toEqual({
|
|
list: {
|
|
title: "Categories",
|
|
addLabel: "Add Category",
|
|
empty: "No categories found.",
|
|
columns: {
|
|
name: "Name",
|
|
items: "Items",
|
|
actions: "Actions",
|
|
},
|
|
actions: {
|
|
edit: "Edit category",
|
|
delete: "Delete category",
|
|
},
|
|
},
|
|
new: {
|
|
title: "New Category",
|
|
},
|
|
edit: {
|
|
title: "Edit Category",
|
|
},
|
|
form: {
|
|
nameLabel: "Name",
|
|
namePlaceholder: "Category name",
|
|
createSubmit: "Create Category",
|
|
updateSubmit: "Update Category",
|
|
},
|
|
delete: {
|
|
label: "Delete category",
|
|
pending: "Deleting...",
|
|
unknownError: "Unknown error",
|
|
},
|
|
actions: {
|
|
createSuccess: "Category created successfully",
|
|
createFailure: "Failed to create category",
|
|
updateSuccess: "Category updated successfully",
|
|
updateFailure: "Failed to update category",
|
|
deleteSuccess: "Category deleted successfully",
|
|
deleteFailure: "Failed to delete category",
|
|
duplicateName: "Category already exists",
|
|
unchangedName: "Category name unchanged",
|
|
notFound: "Category not found",
|
|
hasItems: "Cannot delete category with items",
|
|
},
|
|
schema: {
|
|
nameRequired: "Name is required and must be at least 3 characters long",
|
|
idRequired: "ID is required",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").inventory.categories).toEqual({
|
|
list: {
|
|
title: "Categorías",
|
|
addLabel: "Agregar categoría",
|
|
empty: "No se encontraron categorías.",
|
|
columns: {
|
|
name: "Nombre",
|
|
items: "Artículos",
|
|
actions: "Acciones",
|
|
},
|
|
actions: {
|
|
edit: "Editar categoría",
|
|
delete: "Eliminar categoría",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Nueva categoría",
|
|
},
|
|
edit: {
|
|
title: "Editar categoría",
|
|
},
|
|
form: {
|
|
nameLabel: "Nombre",
|
|
namePlaceholder: "Nombre de la categoría",
|
|
createSubmit: "Crear categoría",
|
|
updateSubmit: "Actualizar categoría",
|
|
},
|
|
delete: {
|
|
label: "Eliminar categoría",
|
|
pending: "Eliminando...",
|
|
unknownError: "Error desconocido",
|
|
},
|
|
actions: {
|
|
createSuccess: "Categoría creada correctamente",
|
|
createFailure: "Error al crear la categoría",
|
|
updateSuccess: "Categoría actualizada correctamente",
|
|
updateFailure: "Error al actualizar la categoría",
|
|
deleteSuccess: "Categoría eliminada correctamente",
|
|
deleteFailure: "Error al eliminar la categoría",
|
|
duplicateName: "La categoría ya existe",
|
|
unchangedName: "El nombre de la categoría no cambió",
|
|
notFound: "Categoría no encontrada",
|
|
hasItems: "No se puede eliminar una categoría con artículos",
|
|
},
|
|
schema: {
|
|
nameRequired:
|
|
"El nombre es obligatorio y debe tener al menos 3 caracteres",
|
|
idRequired: "El ID es obligatorio",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("provides localized inventory item copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.items).toEqual({
|
|
list: {
|
|
title: "Items",
|
|
addLabel: "Add Item",
|
|
empty: "No items found.",
|
|
columns: {
|
|
name: "Name",
|
|
category: "Category",
|
|
assets: "Assets",
|
|
stock: "Stock",
|
|
actions: "Actions",
|
|
},
|
|
actions: {
|
|
view: "View item",
|
|
edit: "Edit item",
|
|
delete: "Delete item",
|
|
},
|
|
},
|
|
detail: {
|
|
notFound: "Item not found",
|
|
labels: {
|
|
category: "Category",
|
|
stock: "Stock",
|
|
},
|
|
},
|
|
new: {
|
|
title: "New Item",
|
|
},
|
|
edit: {
|
|
title: "Edit Item",
|
|
notFound: "Item not found",
|
|
hasAssetsWarning: "This item has already assets assigned to it.",
|
|
},
|
|
form: {
|
|
nameLabel: "Name",
|
|
namePlaceholder: "Item name",
|
|
categoryLabel: "Category",
|
|
categoryPlaceholder: "Select a category",
|
|
stockLabel: "Stock",
|
|
stockPlaceholder: "0",
|
|
createSubmit: "Create Item",
|
|
updateSubmit: "Update Item",
|
|
},
|
|
delete: {
|
|
label: "Delete item",
|
|
pending: "Deleting...",
|
|
unknownError: "Unknown error",
|
|
},
|
|
actions: {
|
|
createSuccess: "Item created successfully!",
|
|
createFailure: "Error creating item",
|
|
updateSuccess: "Item updated successfully!",
|
|
updateFailure: "Failed to update item",
|
|
deleteSuccess: "Item deleted successfully!",
|
|
deleteFailure: "Failed to delete item",
|
|
duplicateName: "Item already exists",
|
|
notFound: "Item not found",
|
|
hasAssets: "Cannot delete item with assets",
|
|
hasStock: "Cannot delete item with stock",
|
|
invalidStock: "Invalid stock",
|
|
negativeStock: "Stock cannot be negative",
|
|
},
|
|
schema: {
|
|
nameRequired: "Name is required",
|
|
categoryRequired: "Category is required",
|
|
stockRequired: "Stock is required",
|
|
itemRequired: "Item is required",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").inventory.items).toEqual({
|
|
list: {
|
|
title: "Artículos",
|
|
addLabel: "Agregar artículo",
|
|
empty: "No se encontraron artículos.",
|
|
columns: {
|
|
name: "Nombre",
|
|
category: "Categoría",
|
|
assets: "Activos",
|
|
stock: "Stock",
|
|
actions: "Acciones",
|
|
},
|
|
actions: {
|
|
view: "Ver artículo",
|
|
edit: "Editar artículo",
|
|
delete: "Eliminar artículo",
|
|
},
|
|
},
|
|
detail: {
|
|
notFound: "Artículo no encontrado",
|
|
labels: {
|
|
category: "Categoría",
|
|
stock: "Stock",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Nuevo artículo",
|
|
},
|
|
edit: {
|
|
title: "Editar artículo",
|
|
notFound: "Artículo no encontrado",
|
|
hasAssetsWarning: "Este artículo ya tiene activos asignados.",
|
|
},
|
|
form: {
|
|
nameLabel: "Nombre",
|
|
namePlaceholder: "Nombre del artículo",
|
|
categoryLabel: "Categoría",
|
|
categoryPlaceholder: "Selecciona una categoría",
|
|
stockLabel: "Stock",
|
|
stockPlaceholder: "0",
|
|
createSubmit: "Crear artículo",
|
|
updateSubmit: "Actualizar artículo",
|
|
},
|
|
delete: {
|
|
label: "Eliminar artículo",
|
|
pending: "Eliminando...",
|
|
unknownError: "Error desconocido",
|
|
},
|
|
actions: {
|
|
createSuccess: "Artículo creado correctamente",
|
|
createFailure: "Error al crear el artículo",
|
|
updateSuccess: "Artículo actualizado correctamente",
|
|
updateFailure: "Error al actualizar el artículo",
|
|
deleteSuccess: "Artículo eliminado correctamente",
|
|
deleteFailure: "Error al eliminar el artículo",
|
|
duplicateName: "El artículo ya existe",
|
|
notFound: "Artículo no encontrado",
|
|
hasAssets: "No se puede eliminar un artículo con activos",
|
|
hasStock: "No se puede eliminar un artículo con stock",
|
|
invalidStock: "Stock inválido",
|
|
negativeStock: "El stock no puede ser negativo",
|
|
},
|
|
schema: {
|
|
nameRequired: "El nombre es obligatorio",
|
|
categoryRequired: "La categoría es obligatoria",
|
|
stockRequired: "El stock es obligatorio",
|
|
itemRequired: "El artículo es obligatorio",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("provides localized assignment copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.assignments).toEqual({
|
|
list: {
|
|
title: "Assignments",
|
|
addLabel: "Add Assignment",
|
|
empty: "No assignments found.",
|
|
columns: {
|
|
person: "Person",
|
|
item: "Item",
|
|
serialNumber: "Serial Number",
|
|
quantity: "Quantity",
|
|
actions: "Actions",
|
|
},
|
|
actions: {
|
|
edit: "Edit assignment",
|
|
return: "Return assignment",
|
|
},
|
|
},
|
|
new: {
|
|
title: "New Assignment",
|
|
},
|
|
edit: {
|
|
title: "Edit Assignment",
|
|
notFound: "Assignment not found",
|
|
},
|
|
form: {
|
|
personLabel: "Person",
|
|
personPlaceholder: "Select a person",
|
|
itemLabel: "Item",
|
|
itemPlaceholder: "Select an item",
|
|
assetLabel: "Asset",
|
|
assetPlaceholder: "Select an asset",
|
|
quantityLabel: "Quantity",
|
|
quantityPlaceholder: "1",
|
|
createSubmit: "Create Assignment",
|
|
updateSubmit: "Update Assignment",
|
|
},
|
|
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: {
|
|
personRequired: "Person 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({
|
|
list: {
|
|
title: "Asignaciones",
|
|
addLabel: "Agregar asignación",
|
|
empty: "No se encontraron asignaciones.",
|
|
columns: {
|
|
person: "Persona",
|
|
item: "Artículo",
|
|
serialNumber: "Número de serie",
|
|
quantity: "Cantidad",
|
|
actions: "Acciones",
|
|
},
|
|
actions: {
|
|
edit: "Editar asignación",
|
|
return: "Devolver asignación",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Nueva asignación",
|
|
},
|
|
edit: {
|
|
title: "Editar asignación",
|
|
notFound: "Asignación no encontrada",
|
|
},
|
|
form: {
|
|
personLabel: "Persona",
|
|
personPlaceholder: "Selecciona una persona",
|
|
itemLabel: "Artículo",
|
|
itemPlaceholder: "Selecciona un artículo",
|
|
assetLabel: "Activo",
|
|
assetPlaceholder: "Selecciona un activo",
|
|
quantityLabel: "Cantidad",
|
|
quantityPlaceholder: "1",
|
|
createSubmit: "Crear asignación",
|
|
updateSubmit: "Actualizar asignación",
|
|
},
|
|
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: {
|
|
personRequired: "La persona es obligatoria",
|
|
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",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("provides localized inventory asset UI copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.assets).toEqual({
|
|
list: {
|
|
title: "Assets",
|
|
addLabel: "Add Asset",
|
|
empty: "No assets found.",
|
|
columns: {
|
|
item: "Item",
|
|
category: "Category",
|
|
serialNumber: "Serial Number",
|
|
status: "Status",
|
|
actions: "Actions",
|
|
},
|
|
actions: {
|
|
edit: "Edit asset",
|
|
},
|
|
},
|
|
new: {
|
|
title: "New Asset",
|
|
},
|
|
edit: {
|
|
title: "Edit Asset",
|
|
notFound: "Asset not found",
|
|
},
|
|
form: {
|
|
itemLabel: "Item",
|
|
itemPlaceholder: "Select an item",
|
|
serialNumberLabel: "Serial Number",
|
|
serialNumberPlaceholder: "Serial number",
|
|
deliveryNoteLabel: "Delivery Note",
|
|
deliveryNotePlaceholder: "Delivery note",
|
|
statusLabel: "Status",
|
|
statusPlaceholder: "Select a status",
|
|
personLabel: "Person",
|
|
personPlaceholder: "Select a person",
|
|
createSubmit: "Create Asset",
|
|
updateSubmit: "Update Asset",
|
|
},
|
|
status: {
|
|
AVAILABLE: "Available",
|
|
ASSIGNED: "Assigned",
|
|
RESERVED: "Reserved",
|
|
IN_REPAIR: "In repair",
|
|
BROKEN: "Broken",
|
|
STOLEN: "Stolen",
|
|
DISPOSED: "Disposed",
|
|
},
|
|
fallback: {
|
|
unknownStatus: "Unknown status",
|
|
},
|
|
actions: {
|
|
createSuccess: "Asset created successfully",
|
|
createFailure: "Error creating asset",
|
|
updateSuccess: "Asset updated successfully",
|
|
updateFailure: "Error updating asset",
|
|
duplicateSerialNumber: "This serial number already exists",
|
|
notFound: "Asset not found",
|
|
itemNotFound: "Item not found",
|
|
assignmentAlreadyReturned: "Assignment already returned",
|
|
previousItemNotFound: "Previous item not found for available asset",
|
|
insufficientStock: "Item does not have enough stock",
|
|
personRequired: "Person is required",
|
|
invalidStatus: "Invalid status",
|
|
genericFailure: "Error processing asset",
|
|
},
|
|
schema: {
|
|
itemRequired: "Item is required",
|
|
serialNumberRequired: "Serial number is required",
|
|
idRequired: "ID is required",
|
|
statusRequired: "Status is required",
|
|
invalidCreateStatus: "Status must be Available or Assigned",
|
|
invalidUpdateStatus: "Invalid status",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").inventory.assets).toEqual({
|
|
list: {
|
|
title: "Activos",
|
|
addLabel: "Agregar activo",
|
|
empty: "No se encontraron activos.",
|
|
columns: {
|
|
item: "Artículo",
|
|
category: "Categoría",
|
|
serialNumber: "Número de serie",
|
|
status: "Estado",
|
|
actions: "Acciones",
|
|
},
|
|
actions: {
|
|
edit: "Editar activo",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Nuevo activo",
|
|
},
|
|
edit: {
|
|
title: "Editar activo",
|
|
notFound: "Activo no encontrado",
|
|
},
|
|
form: {
|
|
itemLabel: "Artículo",
|
|
itemPlaceholder: "Selecciona un artículo",
|
|
serialNumberLabel: "Número de serie",
|
|
serialNumberPlaceholder: "Número de serie",
|
|
deliveryNoteLabel: "Remito",
|
|
deliveryNotePlaceholder: "Remito",
|
|
statusLabel: "Estado",
|
|
statusPlaceholder: "Selecciona un estado",
|
|
personLabel: "Persona",
|
|
personPlaceholder: "Selecciona una persona",
|
|
createSubmit: "Crear activo",
|
|
updateSubmit: "Actualizar activo",
|
|
},
|
|
status: {
|
|
AVAILABLE: "Disponible",
|
|
ASSIGNED: "Asignado",
|
|
RESERVED: "Reservado",
|
|
IN_REPAIR: "En reparación",
|
|
BROKEN: "Roto",
|
|
STOLEN: "Robado",
|
|
DISPOSED: "Dado de baja",
|
|
},
|
|
fallback: {
|
|
unknownStatus: "Estado desconocido",
|
|
},
|
|
actions: {
|
|
createSuccess: "Activo creado correctamente",
|
|
createFailure: "Error al crear el activo",
|
|
updateSuccess: "Activo actualizado correctamente",
|
|
updateFailure: "Error al actualizar el activo",
|
|
duplicateSerialNumber: "El número de serie ya existe",
|
|
notFound: "Activo no encontrado",
|
|
itemNotFound: "Artículo no encontrado",
|
|
assignmentAlreadyReturned: "La asignación ya fue devuelta",
|
|
previousItemNotFound:
|
|
"Artículo anterior no encontrado para el activo disponible",
|
|
insufficientStock: "El artículo no tiene stock suficiente",
|
|
personRequired: "La persona es obligatoria",
|
|
invalidStatus: "Estado inválido",
|
|
genericFailure: "Error al procesar el activo",
|
|
},
|
|
schema: {
|
|
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 debe ser Disponible o Asignado",
|
|
invalidUpdateStatus: "Estado inválido",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("provides localized people UI copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.people).toEqual({
|
|
list: {
|
|
title: "People",
|
|
addLabel: "Add Person",
|
|
empty: "No people found.",
|
|
columns: {
|
|
name: "Name",
|
|
email: "Email",
|
|
phone: "Phone",
|
|
department: "Department",
|
|
actions: "Actions",
|
|
},
|
|
actions: {
|
|
view: "View person",
|
|
edit: "Edit person",
|
|
},
|
|
},
|
|
detail: {
|
|
notFound: "Person not found",
|
|
labels: {
|
|
email: "Email",
|
|
phone: "Phone",
|
|
department: "Department",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Add Person",
|
|
},
|
|
edit: {
|
|
title: "Edit Person",
|
|
notFound: "Person not found",
|
|
},
|
|
form: {
|
|
firstNameLabel: "First Name",
|
|
firstNamePlaceholder: "First name",
|
|
lastNameLabel: "Last Name",
|
|
lastNamePlaceholder: "Last name",
|
|
departmentLabel: "Department",
|
|
departmentPlaceholder: "Select a department",
|
|
emailLabel: "Email",
|
|
emailPlaceholder: "Email",
|
|
phoneLabel: "Phone",
|
|
phonePlaceholder: "Phone",
|
|
createSubmit: "Create Person",
|
|
updateSubmit: "Update Person",
|
|
},
|
|
fallback: {
|
|
unknownDepartment: "Unknown department",
|
|
},
|
|
departments: {
|
|
IT: "IT",
|
|
ENGINEERING: "Engineering",
|
|
LOGISTICS: "Logistics",
|
|
TRAFFIC: "Traffic",
|
|
DRIVER: "Driver",
|
|
ADMINISTRATION: "Administration",
|
|
SALES: "Sales",
|
|
OTHER: "Other",
|
|
},
|
|
actions: {
|
|
createSuccess: "Person created successfully",
|
|
createFailure: "Failed to create person",
|
|
updateSuccess: "Person updated successfully",
|
|
updateFailure: "Failed to update person",
|
|
duplicateEmail: "Email already exists",
|
|
},
|
|
schema: {
|
|
firstNameRequired: "First name is required",
|
|
lastNameRequired: "Last name is required",
|
|
departmentRequired: "Department is required",
|
|
emailInvalid: "Email format is invalid",
|
|
idRequired: "ID is required",
|
|
userIdInvalid: "User ID must be a valid UUID",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").inventory.people).toEqual({
|
|
list: {
|
|
title: "Personas",
|
|
addLabel: "Agregar persona",
|
|
empty: "No se encontraron personas.",
|
|
columns: {
|
|
name: "Nombre",
|
|
email: "Correo electrónico",
|
|
phone: "Teléfono",
|
|
department: "Departamento",
|
|
actions: "Acciones",
|
|
},
|
|
actions: {
|
|
view: "Ver persona",
|
|
edit: "Editar persona",
|
|
},
|
|
},
|
|
detail: {
|
|
notFound: "Persona no encontrada",
|
|
labels: {
|
|
email: "Correo electrónico",
|
|
phone: "Teléfono",
|
|
department: "Departamento",
|
|
},
|
|
},
|
|
new: {
|
|
title: "Agregar persona",
|
|
},
|
|
edit: {
|
|
title: "Editar persona",
|
|
notFound: "Persona no encontrada",
|
|
},
|
|
form: {
|
|
firstNameLabel: "Nombre",
|
|
firstNamePlaceholder: "Nombre",
|
|
lastNameLabel: "Apellido",
|
|
lastNamePlaceholder: "Apellido",
|
|
departmentLabel: "Departamento",
|
|
departmentPlaceholder: "Selecciona un departamento",
|
|
emailLabel: "Correo electrónico",
|
|
emailPlaceholder: "Correo electrónico",
|
|
phoneLabel: "Teléfono",
|
|
phonePlaceholder: "Teléfono",
|
|
createSubmit: "Crear persona",
|
|
updateSubmit: "Actualizar persona",
|
|
},
|
|
fallback: {
|
|
unknownDepartment: "Departamento desconocido",
|
|
},
|
|
departments: {
|
|
IT: "IT",
|
|
ENGINEERING: "Ingeniería",
|
|
LOGISTICS: "Logística",
|
|
TRAFFIC: "Tráfico",
|
|
DRIVER: "Chofer",
|
|
ADMINISTRATION: "Administración",
|
|
SALES: "Ventas",
|
|
OTHER: "Otro",
|
|
},
|
|
actions: {
|
|
createSuccess: "Persona creada correctamente",
|
|
createFailure: "Error al crear la persona",
|
|
updateSuccess: "Persona actualizada correctamente",
|
|
updateFailure: "Error al actualizar la persona",
|
|
duplicateEmail: "El correo electrónico ya existe",
|
|
},
|
|
schema: {
|
|
firstNameRequired: "El nombre es obligatorio",
|
|
lastNameRequired: "El apellido es obligatorio",
|
|
departmentRequired: "El departamento es obligatorio",
|
|
emailInvalid: "El correo electrónico no es válido",
|
|
idRequired: "El ID es obligatorio",
|
|
userIdInvalid: "El ID de usuario debe ser un UUID válido",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("does not have inventory.recipients or legacy recipient keys in either locale", () => {
|
|
expect("recipients" in getDictionary("en").inventory).toBe(false)
|
|
expect("recipients" in getDictionary("es").inventory).toBe(false)
|
|
expect("recipients" in getDictionary("en").layout.sidebar).toBe(false)
|
|
expect("recipient" in getDictionary("en").layout.addMenu).toBe(false)
|
|
expect("recipients" in getDictionary("es").layout.sidebar).toBe(false)
|
|
expect("recipient" in getDictionary("es").layout.addMenu).toBe(false)
|
|
expect("recipients" in getDictionary("en").dashboardHome.cards).toBe(false)
|
|
expect("recipients" in getDictionary("es").dashboardHome.cards).toBe(false)
|
|
})
|
|
|
|
it("provides localized movement UI copy for English and Spanish", () => {
|
|
expect(getDictionary("en").inventory.movements).toEqual({
|
|
list: {
|
|
title: "Movements",
|
|
empty: "No movements found",
|
|
columns: {
|
|
type: "Type",
|
|
item: "Item",
|
|
serialNumber: "Serial Number",
|
|
quantity: "Quantity",
|
|
person: "Person",
|
|
date: "Date",
|
|
},
|
|
},
|
|
snippet: {
|
|
title: "Movements",
|
|
labels: {
|
|
type: "Type",
|
|
quantity: "Quantity",
|
|
},
|
|
},
|
|
types: {
|
|
IN: "In",
|
|
OUT: "Out",
|
|
ASSIGNMENT: "Assignment",
|
|
RETURN: "Return",
|
|
ADJUSTMENT: "Adjustment",
|
|
DELETED: "Deleted",
|
|
},
|
|
fallback: {
|
|
missingValue: "-",
|
|
unknownType: "Unknown movement type",
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").inventory.movements).toEqual({
|
|
list: {
|
|
title: "Movimientos",
|
|
empty: "No se encontraron movimientos.",
|
|
columns: {
|
|
type: "Tipo",
|
|
item: "Artículo",
|
|
serialNumber: "Número de serie",
|
|
quantity: "Cantidad",
|
|
person: "Persona",
|
|
date: "Fecha",
|
|
},
|
|
},
|
|
snippet: {
|
|
title: "Movimientos",
|
|
labels: {
|
|
type: "Tipo",
|
|
quantity: "Cantidad",
|
|
},
|
|
},
|
|
types: {
|
|
IN: "Entrada",
|
|
OUT: "Salida",
|
|
ASSIGNMENT: "Asignación",
|
|
RETURN: "Devolución",
|
|
ADJUSTMENT: "Ajuste",
|
|
DELETED: "Eliminación",
|
|
},
|
|
fallback: {
|
|
missingValue: "-",
|
|
unknownType: "Tipo de movimiento desconocido",
|
|
},
|
|
})
|
|
})
|
|
|
|
it("keeps dashboard home dictionary keys aligned across locales", () => {
|
|
expect(getDictionary("en").dashboardHome).toEqual({
|
|
heading: "Dashboard",
|
|
cards: {
|
|
items: {
|
|
title: "Total Items",
|
|
countLabel: "Total",
|
|
},
|
|
assets: {
|
|
title: "Total Assets",
|
|
countLabel: "Total",
|
|
},
|
|
people: {
|
|
title: "Total People",
|
|
countLabel: "Total",
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(getDictionary("es").dashboardHome).toEqual({
|
|
heading: "Panel de control",
|
|
cards: {
|
|
items: {
|
|
title: "Total de artículos",
|
|
countLabel: "Total",
|
|
},
|
|
assets: {
|
|
title: "Total de activos",
|
|
countLabel: "Total",
|
|
},
|
|
people: {
|
|
title: "Total de personas",
|
|
countLabel: "Total",
|
|
},
|
|
},
|
|
})
|
|
})
|
|
|
|
it("has exact structural parity between English and Spanish dictionaries", () => {
|
|
expect(extractKeyPaths(getDictionary("es"))).toEqual(
|
|
extractKeyPaths(getDictionary("en")),
|
|
)
|
|
})
|
|
})
|
|
|
|
function extractKeyPaths(value: unknown, prefix = ""): string[] {
|
|
if (!isPlainObject(value)) return [prefix]
|
|
|
|
return Object.keys(value)
|
|
.sort()
|
|
.flatMap((key) =>
|
|
extractKeyPaths(value[key], prefix ? `${prefix}.${key}` : key),
|
|
)
|
|
}
|
|
|
|
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
}
|