From c0ae7a034adb831b2a4696853ed1c59e1bb97c6e Mon Sep 17 00:00:00 2001 From: Asis Ferrer Date: Sun, 14 Jun 2026 18:33:57 +0200 Subject: [PATCH] feat(i18n): localize recipients UI --- .../recipients/[recipientId]/edit/page.tsx | 10 +- .../recipients/[recipientId]/page.tsx | 27 ++- .../recipients/_components/recipient.copy.ts | 24 +++ .../recipients/_components/recipient.form.tsx | 45 +++-- src/app/(dashboard)/recipients/new/page.tsx | 6 +- src/app/(dashboard)/recipients/page.tsx | 37 ++-- src/i18n/dictionaries/en.ts | 64 +++++++ src/i18n/dictionaries/es.ts | 64 +++++++ .../recipients/recipient-form-pages.test.ts | 125 +++++++++++++ .../app/recipients/recipient-pages.test.ts | 165 ++++++++++++++++++ tests/unit/i18n/dictionaries.test.ts | 132 ++++++++++++++ 11 files changed, 665 insertions(+), 34 deletions(-) create mode 100644 src/app/(dashboard)/recipients/_components/recipient.copy.ts create mode 100644 tests/unit/app/recipients/recipient-form-pages.test.ts create mode 100644 tests/unit/app/recipients/recipient-pages.test.ts diff --git a/src/app/(dashboard)/recipients/[recipientId]/edit/page.tsx b/src/app/(dashboard)/recipients/[recipientId]/edit/page.tsx index 81f76dd..d539580 100644 --- a/src/app/(dashboard)/recipients/[recipientId]/edit/page.tsx +++ b/src/app/(dashboard)/recipients/[recipientId]/edit/page.tsx @@ -9,21 +9,25 @@ export default async function RecipientEditPage({ params: Promise<{ recipientId: string }> }) { const { recipientId } = await params - const recipient = await RecipientService.findById(recipientId) const { dictionary } = await getI18n() + const copy = dictionary.inventory.recipients + const recipient = await RecipientService.findById(recipientId) if (!recipient) { - return
Recipient not found
+ return
{copy.edit.notFound}
} return (
-

Edit Recipient

+

{copy.edit.title}

diff --git a/src/app/(dashboard)/recipients/[recipientId]/page.tsx b/src/app/(dashboard)/recipients/[recipientId]/page.tsx index efb2e16..fa9edc9 100644 --- a/src/app/(dashboard)/recipients/[recipientId]/page.tsx +++ b/src/app/(dashboard)/recipients/[recipientId]/page.tsx @@ -1,18 +1,23 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { getI18n } from "@/i18n/server" import { AssignmentService } from "@/services/assignment.service" import { RecipientService } from "@/services/recipient.service" +import { formatRecipientDepartment } from "../_components/recipient.copy" + export default async function RecipientInfoPage({ params, }: { params: Promise<{ recipientId: string }> }) { const { recipientId } = await params + const { dictionary } = await getI18n() + const copy = dictionary.inventory.recipients const recipient = await RecipientService.findById(recipientId) const assignments = await AssignmentService.findAllByRecipient(recipientId) if (!recipient) { - return
Recipient not found
+ return
{copy.detail.notFound}
} return ( @@ -26,20 +31,30 @@ export default async function RecipientInfoPage({
- Username + + {copy.detail.labels.username} + {recipient.username}
- Email + {copy.detail.labels.email} {recipient.email}
- Phone + {copy.detail.labels.phone} {recipient.phone}
- Department - {recipient.department} + + {copy.detail.labels.department} + + + {formatRecipientDepartment( + recipient.department, + copy.departments, + copy.fallback, + )} +
diff --git a/src/app/(dashboard)/recipients/_components/recipient.copy.ts b/src/app/(dashboard)/recipients/_components/recipient.copy.ts new file mode 100644 index 0000000..ea0b6e7 --- /dev/null +++ b/src/app/(dashboard)/recipients/_components/recipient.copy.ts @@ -0,0 +1,24 @@ +import type { Dictionary } from "@/i18n/dictionaries" + +export type RecipientListCopy = Dictionary["inventory"]["recipients"]["list"] +export type RecipientDetailCopy = + Dictionary["inventory"]["recipients"]["detail"] +export type RecipientFormCopy = Dictionary["inventory"]["recipients"]["form"] +export type RecipientDepartmentCopy = + Dictionary["inventory"]["recipients"]["departments"] +export type RecipientFallbackCopy = + Dictionary["inventory"]["recipients"]["fallback"] + +export function formatRecipientDepartment( + department: string | null | undefined, + departmentCopy: RecipientDepartmentCopy, + fallbackCopy: RecipientFallbackCopy, +) { + if (!department) { + return fallbackCopy.unknownDepartment + } + + return department in departmentCopy + ? departmentCopy[department as keyof RecipientDepartmentCopy] + : fallbackCopy.unknownDepartment +} diff --git a/src/app/(dashboard)/recipients/_components/recipient.form.tsx b/src/app/(dashboard)/recipients/_components/recipient.form.tsx index bdd89de..9be3ce7 100644 --- a/src/app/(dashboard)/recipients/_components/recipient.form.tsx +++ b/src/app/(dashboard)/recipients/_components/recipient.form.tsx @@ -20,15 +20,28 @@ import { } from "@/schemas/recipient.schema" import type { Recipient } from "@/types" +import { + formatRecipientDepartment, + type RecipientDepartmentCopy, + type RecipientFallbackCopy, + type RecipientFormCopy, +} from "./recipient.copy" + interface RecipientFormProps { initialData?: Recipient mode?: "create" | "edit" + formCopy: RecipientFormCopy + departmentCopy: RecipientDepartmentCopy + fallbackCopy: RecipientFallbackCopy submitButtonCopy: SubmitButtonCopy } export default function RecipientForm({ initialData, mode = "create", + formCopy, + departmentCopy, + fallbackCopy, submitButtonCopy, }: RecipientFormProps) { const router = useRouter() @@ -81,12 +94,12 @@ export default function RecipientForm({
@@ -96,12 +109,12 @@ export default function RecipientForm({
@@ -111,12 +124,12 @@ export default function RecipientForm({
@@ -126,17 +139,21 @@ export default function RecipientForm({
@@ -146,12 +163,12 @@ export default function RecipientForm({
@@ -159,12 +176,12 @@ export default function RecipientForm({
@@ -175,7 +192,7 @@ export default function RecipientForm({ isSubmitting={isSubmitting} isSubmitSuccessful={isSubmitSuccessful} > - {mode === "create" ? "Create Recipient" : "Update Recipient"} + {mode === "create" ? formCopy.createSubmit : formCopy.updateSubmit} ) diff --git a/src/app/(dashboard)/recipients/new/page.tsx b/src/app/(dashboard)/recipients/new/page.tsx index b6ea5ad..0d9bedb 100644 --- a/src/app/(dashboard)/recipients/new/page.tsx +++ b/src/app/(dashboard)/recipients/new/page.tsx @@ -4,14 +4,18 @@ import RecipientForm from "../_components/recipient.form" export default async function NewRecipientPage() { const { dictionary } = await getI18n() + const copy = dictionary.inventory.recipients return (
-

Add Recipient

+

{copy.new.title}

diff --git a/src/app/(dashboard)/recipients/page.tsx b/src/app/(dashboard)/recipients/page.tsx index f361451..ee31e4d 100644 --- a/src/app/(dashboard)/recipients/page.tsx +++ b/src/app/(dashboard)/recipients/page.tsx @@ -5,8 +5,11 @@ import PageHeader from "@/components/common/pageheader" import PaginationButtons from "@/components/common/pagination" import { Button } from "@/components/ui/button" import type { Recipient } from "@/generated/prisma/client" +import { getI18n } from "@/i18n/server" import { RecipientService } from "@/services/recipient.service" +import { formatRecipientDepartment } from "./_components/recipient.copy" + export default async function RecipientsPage(props: { searchParams?: Promise<{ page?: string @@ -22,38 +25,41 @@ export default async function RecipientsPage(props: { pageSize: 10, search, }) + const { dictionary } = await getI18n() + const copy = dictionary.inventory.recipients return (
- {recipients.length === 0 &&
No recipients found
} + {recipients.length === 0 &&
{copy.list.empty}
} {recipients.length > 0 && (
@@ -66,10 +72,20 @@ export default async function RecipientsPage(props: { - +
- Username + {copy.list.columns.username} - Name + {copy.list.columns.name} - Email + {copy.list.columns.email} - Phone + {copy.list.columns.phone} - Department + {copy.list.columns.department} - Actions + {copy.list.columns.actions}
{recipient.email} {recipient.phone}{recipient.department} + {formatRecipientDepartment( + recipient.department, + copy.departments, + copy.fallback, + )} + - @@ -78,6 +94,7 @@ export default async function RecipientsPage(props: { className="btn btn-primary" variant="outline" size="icon" + aria-label={copy.list.actions.edit} > diff --git a/src/i18n/dictionaries/en.ts b/src/i18n/dictionaries/en.ts index d224073..09bc31b 100644 --- a/src/i18n/dictionaries/en.ts +++ b/src/i18n/dictionaries/en.ts @@ -255,6 +255,70 @@ export const en = { invalidUpdateStatus: "Invalid status", }, }, + recipients: { + list: { + title: "Recipients", + addLabel: "Add Recipient", + empty: "No recipients found.", + columns: { + username: "Username", + name: "Name", + email: "Email", + phone: "Phone", + department: "Department", + actions: "Actions", + }, + actions: { + view: "View recipient", + edit: "Edit recipient", + }, + }, + detail: { + notFound: "Recipient not found", + labels: { + username: "Username", + email: "Email", + phone: "Phone", + department: "Department", + }, + }, + new: { + title: "Add Recipient", + }, + edit: { + title: "Edit Recipient", + notFound: "Recipient not found", + }, + form: { + usernameLabel: "Username", + usernamePlaceholder: "Username", + 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 Recipient", + updateSubmit: "Update Recipient", + }, + fallback: { + unknownDepartment: "Unknown department", + }, + departments: { + IT: "IT", + ENGINEERING: "Engineering", + LOGISTICS: "Logistics", + TRAFFIC: "Traffic", + DRIVER: "Driver", + ADMINISTRATION: "Administration", + SALES: "Sales", + OTHER: "Other", + }, + }, movements: { list: { title: "Movements", diff --git a/src/i18n/dictionaries/es.ts b/src/i18n/dictionaries/es.ts index d00eb41..d2fc1c2 100644 --- a/src/i18n/dictionaries/es.ts +++ b/src/i18n/dictionaries/es.ts @@ -259,6 +259,70 @@ export const es = { invalidUpdateStatus: "Estado inválido", }, }, + recipients: { + list: { + title: "Destinatarios", + addLabel: "Agregar destinatario", + empty: "No se encontraron destinatarios.", + columns: { + username: "Usuario", + name: "Nombre", + email: "Correo electrónico", + phone: "Teléfono", + department: "Departamento", + actions: "Acciones", + }, + actions: { + view: "Ver destinatario", + edit: "Editar destinatario", + }, + }, + detail: { + notFound: "Destinatario no encontrado", + labels: { + username: "Usuario", + email: "Correo electrónico", + phone: "Teléfono", + department: "Departamento", + }, + }, + new: { + title: "Agregar destinatario", + }, + edit: { + title: "Editar destinatario", + notFound: "Destinatario no encontrado", + }, + form: { + usernameLabel: "Usuario", + usernamePlaceholder: "Usuario", + 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 destinatario", + updateSubmit: "Actualizar destinatario", + }, + 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", + }, + }, movements: { list: { title: "Movimientos", diff --git a/tests/unit/app/recipients/recipient-form-pages.test.ts b/tests/unit/app/recipients/recipient-form-pages.test.ts new file mode 100644 index 0000000..f4dab57 --- /dev/null +++ b/tests/unit/app/recipients/recipient-form-pages.test.ts @@ -0,0 +1,125 @@ +import { renderToStaticMarkup } from "react-dom/server" +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { en } from "@/i18n/dictionaries/en" +import { es } from "@/i18n/dictionaries/es" + +const mocks = vi.hoisted(() => ({ + getI18n: vi.fn(), + findById: vi.fn(), + createNewRecipient: vi.fn(), + updateRecipient: vi.fn(), + push: vi.fn(), + toastError: vi.fn(), + toastSuccess: vi.fn(), +})) + +vi.mock("@/i18n/server", () => ({ + getI18n: mocks.getI18n, +})) + +vi.mock("@/services/recipient.service", () => ({ + RecipientService: { + findById: mocks.findById, + }, +})) + +vi.mock("@/actions/recipient.actions", () => ({ + createNewRecipient: mocks.createNewRecipient, + updateRecipient: mocks.updateRecipient, +})) + +vi.mock("next/navigation", () => ({ + useRouter: () => ({ + push: mocks.push, + }), +})) + +vi.mock("sonner", () => ({ + toast: { + error: mocks.toastError, + success: mocks.toastSuccess, + }, +})) + +describe("recipient form pages localization", () => { + beforeEach(() => { + vi.clearAllMocks() + mocks.getI18n.mockResolvedValue({ dictionary: es, locale: "es" }) + }) + + it("renders the new recipient page with localized form copy and canonical department option values", async () => { + const { default: NewRecipientPage } = await import( + "@/app/(dashboard)/recipients/new/page" + ) + + const html = renderToStaticMarkup(await NewRecipientPage()) + + expect(html).toContain("Agregar destinatario") + expect(html).toContain("Usuario") + expect(html).toContain('placeholder="Usuario"') + expect(html).toContain("Nombre") + expect(html).toContain("Apellido") + expect(html).toContain("Selecciona un departamento") + expect(html).toContain('option value="ENGINEERING"') + expect(html).toContain(">Ingeniería") + expect(html).toContain("Correo electrónico") + expect(html).toContain("Teléfono") + expect(html).toContain("Crear destinatario") + }) + + it("renders the edit recipient page with localized heading and submit text", async () => { + const { default: RecipientEditPage } = await import( + "@/app/(dashboard)/recipients/[recipientId]/edit/page" + ) + + mocks.findById.mockResolvedValue({ + id: "recipient-1", + username: "ada", + firstName: "Ada", + lastName: "Lovelace", + email: "ada@example.test", + phone: "1234", + department: "ENGINEERING", + }) + + const html = renderToStaticMarkup( + await RecipientEditPage({ + params: Promise.resolve({ recipientId: "recipient-1" }), + }), + ) + + expect(html).toContain("Editar destinatario") + expect(html).toContain("Actualizar destinatario") + expect(html).toContain('placeholder="Correo electrónico"') + expect(html).toContain(">Ingeniería") + }) + + it("renders a localized edit-page not-found message", async () => { + const { default: RecipientEditPage } = await import( + "@/app/(dashboard)/recipients/[recipientId]/edit/page" + ) + + mocks.findById.mockResolvedValue(null) + + const html = renderToStaticMarkup( + await RecipientEditPage({ + params: Promise.resolve({ recipientId: "missing-recipient" }), + }), + ) + + expect(html).toContain("Destinatario no encontrado") + }) + + it("wires English recipient form submit copy through the new page", async () => { + const { default: NewRecipientPage } = await import( + "@/app/(dashboard)/recipients/new/page" + ) + + mocks.getI18n.mockResolvedValueOnce({ dictionary: en, locale: "en" }) + + const html = renderToStaticMarkup(await NewRecipientPage()) + + expect(html).toContain("Create Recipient") + }) +}) diff --git a/tests/unit/app/recipients/recipient-pages.test.ts b/tests/unit/app/recipients/recipient-pages.test.ts new file mode 100644 index 0000000..a0bf867 --- /dev/null +++ b/tests/unit/app/recipients/recipient-pages.test.ts @@ -0,0 +1,165 @@ +import { createElement } from "react" +import { renderToStaticMarkup } from "react-dom/server" +import { beforeEach, describe, expect, it, vi } from "vitest" + +import { es } from "@/i18n/dictionaries/es" + +const mocks = vi.hoisted(() => ({ + findAllPaginated: vi.fn(), + findById: vi.fn(), + findAllByRecipient: vi.fn(), + getI18n: vi.fn(), +})) + +vi.mock("@/i18n/server", () => ({ + getI18n: mocks.getI18n, +})) + +vi.mock("@/services/recipient.service", () => ({ + RecipientService: { + findAllPaginated: mocks.findAllPaginated, + findById: mocks.findById, + }, +})) + +vi.mock("@/services/assignment.service", () => ({ + AssignmentService: { + findAllByRecipient: mocks.findAllByRecipient, + }, +})) + +vi.mock("@/components/common/pageheader", () => ({ + default: ({ title, addLabel }: { title: string; addLabel?: string }) => + createElement( + "header", + null, + [title, addLabel].filter(Boolean).join(" | "), + ), +})) + +vi.mock("@/components/common/pagination", () => ({ + default: ({ totalPages }: { totalPages: number }) => + createElement("nav", { "aria-label": "Pagination" }, totalPages), +})) + +describe("recipient pages localization", () => { + beforeEach(() => { + vi.clearAllMocks() + mocks.getI18n.mockResolvedValue({ dictionary: es, locale: "es" }) + }) + + it("renders the recipient list in Spanish while keeping stored department values display-only", async () => { + const { default: RecipientsPage } = await import( + "@/app/(dashboard)/recipients/page" + ) + + mocks.findAllPaginated.mockResolvedValue({ + data: [ + { + id: "recipient-1", + username: "ada", + firstName: "Ada", + lastName: "Lovelace", + email: "ada@example.test", + phone: "1234", + department: "ENGINEERING", + }, + ], + totalPages: 1, + }) + + const html = renderToStaticMarkup( + await RecipientsPage({ searchParams: Promise.resolve({}) }), + ) + + expect(html).toContain("Destinatarios") + expect(html).toContain("Agregar destinatario") + expect(html).toContain("Usuario") + expect(html).toContain("Nombre") + expect(html).toContain("Correo electrónico") + expect(html).toContain("Teléfono") + expect(html).toContain("Departamento") + expect(html).toContain("Acciones") + expect(html).toContain("Ada Lovelace") + expect(html).toContain("Ingeniería") + expect(html).toContain('aria-label="Ver destinatario"') + expect(html).toContain('aria-label="Editar destinatario"') + expect(html).not.toContain(">ENGINEERING<") + }) + + it("renders the localized recipient empty state when no recipients exist", async () => { + const { default: RecipientsPage } = await import( + "@/app/(dashboard)/recipients/page" + ) + + mocks.findAllPaginated.mockResolvedValue({ + data: [], + totalPages: 0, + }) + + const html = renderToStaticMarkup( + await RecipientsPage({ searchParams: Promise.resolve({}) }), + ) + + expect(html).toContain("No se encontraron destinatarios.") + }) + + it("renders localized recipient-owned detail labels and keeps assignments copy unchanged", async () => { + const { default: RecipientInfoPage } = await import( + "@/app/(dashboard)/recipients/[recipientId]/page" + ) + + mocks.findById.mockResolvedValue({ + id: "recipient-1", + username: "ada", + firstName: "Ada", + lastName: "Lovelace", + email: "ada@example.test", + phone: "1234", + department: "DRIVER", + }) + mocks.findAllByRecipient.mockResolvedValue([ + { + id: "assignment-1", + item: { name: "Laptop" }, + asset: { serialNumber: "SN-001" }, + quantity: 1, + }, + ]) + + const html = renderToStaticMarkup( + await RecipientInfoPage({ + params: Promise.resolve({ recipientId: "recipient-1" }), + }), + ) + + expect(html).toContain("Usuario") + expect(html).toContain("Correo electrónico") + expect(html).toContain("Teléfono") + expect(html).toContain("Departamento") + expect(html).toContain("Chofer") + expect(html).toContain("ada") + expect(html).toContain("ada@example.test") + expect(html).toContain("Assignments") + expect(html).toContain("Laptop") + expect(html).not.toContain(">DRIVER<") + expect(html).not.toContain("Asignaciones") + }) + + it("renders a localized recipient detail not-found message", async () => { + const { default: RecipientInfoPage } = await import( + "@/app/(dashboard)/recipients/[recipientId]/page" + ) + + mocks.findById.mockResolvedValue(null) + mocks.findAllByRecipient.mockResolvedValue([]) + + const html = renderToStaticMarkup( + await RecipientInfoPage({ + params: Promise.resolve({ recipientId: "missing-recipient" }), + }), + ) + + expect(html).toContain("Destinatario no encontrado") + }) +}) diff --git a/tests/unit/i18n/dictionaries.test.ts b/tests/unit/i18n/dictionaries.test.ts index 391cd58..0cfe626 100644 --- a/tests/unit/i18n/dictionaries.test.ts +++ b/tests/unit/i18n/dictionaries.test.ts @@ -559,6 +559,138 @@ describe("i18n dictionaries", () => { }) }) + it("provides localized recipient UI copy for English and Spanish", () => { + expect(getDictionary("en").inventory.recipients).toEqual({ + list: { + title: "Recipients", + addLabel: "Add Recipient", + empty: "No recipients found.", + columns: { + username: "Username", + name: "Name", + email: "Email", + phone: "Phone", + department: "Department", + actions: "Actions", + }, + actions: { + view: "View recipient", + edit: "Edit recipient", + }, + }, + detail: { + notFound: "Recipient not found", + labels: { + username: "Username", + email: "Email", + phone: "Phone", + department: "Department", + }, + }, + new: { + title: "Add Recipient", + }, + edit: { + title: "Edit Recipient", + notFound: "Recipient not found", + }, + form: { + usernameLabel: "Username", + usernamePlaceholder: "Username", + 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 Recipient", + updateSubmit: "Update Recipient", + }, + fallback: { + unknownDepartment: "Unknown department", + }, + departments: { + IT: "IT", + ENGINEERING: "Engineering", + LOGISTICS: "Logistics", + TRAFFIC: "Traffic", + DRIVER: "Driver", + ADMINISTRATION: "Administration", + SALES: "Sales", + OTHER: "Other", + }, + }) + + expect(getDictionary("es").inventory.recipients).toEqual({ + list: { + title: "Destinatarios", + addLabel: "Agregar destinatario", + empty: "No se encontraron destinatarios.", + columns: { + username: "Usuario", + name: "Nombre", + email: "Correo electrónico", + phone: "Teléfono", + department: "Departamento", + actions: "Acciones", + }, + actions: { + view: "Ver destinatario", + edit: "Editar destinatario", + }, + }, + detail: { + notFound: "Destinatario no encontrado", + labels: { + username: "Usuario", + email: "Correo electrónico", + phone: "Teléfono", + department: "Departamento", + }, + }, + new: { + title: "Agregar destinatario", + }, + edit: { + title: "Editar destinatario", + notFound: "Destinatario no encontrado", + }, + form: { + usernameLabel: "Usuario", + usernamePlaceholder: "Usuario", + 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 destinatario", + updateSubmit: "Actualizar destinatario", + }, + 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", + }, + }) + }) + it("provides localized movement UI copy for English and Spanish", () => { expect(getDictionary("en").inventory.movements).toEqual({ list: {