230 lines
6.0 KiB
TypeScript
230 lines
6.0 KiB
TypeScript
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(() => ({
|
|
findAllWithPersonPaginated: vi.fn(),
|
|
getI18n: vi.fn(),
|
|
refresh: vi.fn(),
|
|
returnAssignment: vi.fn(),
|
|
toastError: vi.fn(),
|
|
toastSuccess: vi.fn(),
|
|
ReturnButton: vi.fn(),
|
|
}))
|
|
|
|
vi.mock("@/i18n/server", () => ({
|
|
getI18n: mocks.getI18n,
|
|
}))
|
|
|
|
vi.mock("@/services/assignment.service", () => ({
|
|
AssignmentService: {
|
|
findAllWithPersonPaginated: mocks.findAllWithPersonPaginated,
|
|
},
|
|
}))
|
|
|
|
vi.mock("@/actions/assignment.actions", () => ({
|
|
returnAssignment: mocks.returnAssignment,
|
|
}))
|
|
|
|
vi.mock("@/app/(dashboard)/assignments/_components/return.button", () => ({
|
|
default: mocks.ReturnButton,
|
|
}))
|
|
|
|
vi.mock("next/navigation", () => ({
|
|
useRouter: () => ({
|
|
refresh: mocks.refresh,
|
|
}),
|
|
}))
|
|
|
|
vi.mock("sonner", () => ({
|
|
toast: {
|
|
error: mocks.toastError,
|
|
success: mocks.toastSuccess,
|
|
},
|
|
}))
|
|
|
|
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("assignment pages localization", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mocks.getI18n.mockResolvedValue({ dictionary: es, locale: "es" })
|
|
mocks.ReturnButton.mockImplementation(
|
|
({
|
|
assignmentId,
|
|
ariaLabel,
|
|
assignmentLineId,
|
|
remainingQuantity,
|
|
}: {
|
|
assignmentId: string
|
|
ariaLabel: string
|
|
assignmentLineId?: string
|
|
remainingQuantity?: number
|
|
}) =>
|
|
createElement("button", {
|
|
type: "button",
|
|
"data-assignment-id": assignmentId,
|
|
"data-aria-label": ariaLabel,
|
|
"data-assignment-line-id": assignmentLineId,
|
|
"data-remaining-quantity": remainingQuantity,
|
|
"aria-label": ariaLabel,
|
|
}),
|
|
)
|
|
})
|
|
|
|
it("renders the assignment list in Spanish with localized action labels and unchanged assignment data", async () => {
|
|
const { default: AssignmentsPage } = await import(
|
|
"@/app/(dashboard)/assignments/page"
|
|
)
|
|
|
|
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
|
data: [
|
|
{
|
|
id: "assignment-1",
|
|
quantity: 2,
|
|
status: "OPEN",
|
|
person: {
|
|
id: "person-1",
|
|
firstName: "Ada",
|
|
lastName: "Lovelace",
|
|
},
|
|
item: {
|
|
id: "item-1",
|
|
name: "Laptop",
|
|
},
|
|
asset: {
|
|
serialNumber: null,
|
|
},
|
|
},
|
|
],
|
|
totalPages: 1,
|
|
})
|
|
|
|
const html = renderToStaticMarkup(
|
|
await AssignmentsPage({ searchParams: Promise.resolve({}) }),
|
|
)
|
|
|
|
expect(html).toContain("Asignaciones")
|
|
expect(html).toContain("Agregar asignación")
|
|
expect(html).toContain("Persona")
|
|
expect(html).toContain("Artículo")
|
|
expect(html).toContain("Número de serie")
|
|
expect(html).toContain("Cantidad")
|
|
expect(html).toContain("Acciones")
|
|
expect(html).toContain("Ada Lovelace")
|
|
expect(html).toContain("Laptop")
|
|
expect(html).toContain("No disponible")
|
|
expect(html).toContain('aria-label="Editar asignación"')
|
|
expect(html).toContain('data-aria-label="Devolver asignación"')
|
|
expect(html).toContain('data-assignment-id="assignment-1"')
|
|
})
|
|
|
|
it("renders the full quantity for OPEN rows and omits partial-return props", async () => {
|
|
const { default: AssignmentsPage } = await import(
|
|
"@/app/(dashboard)/assignments/page"
|
|
)
|
|
|
|
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
|
data: [
|
|
{
|
|
id: "assignment-1",
|
|
quantity: 5,
|
|
status: "OPEN",
|
|
assignmentLineId: "line-1",
|
|
remainingQuantity: 5,
|
|
person: {
|
|
id: "person-1",
|
|
firstName: "Ada",
|
|
lastName: "Lovelace",
|
|
},
|
|
item: {
|
|
id: "item-1",
|
|
name: "Laptop",
|
|
},
|
|
asset: {
|
|
serialNumber: null,
|
|
},
|
|
},
|
|
],
|
|
totalPages: 1,
|
|
})
|
|
|
|
const html = renderToStaticMarkup(
|
|
await AssignmentsPage({ searchParams: Promise.resolve({}) }),
|
|
)
|
|
|
|
expect(html).toContain('data-assignment-line-id="line-1"')
|
|
expect(html).toContain('data-remaining-quantity="5"')
|
|
expect(html).not.toContain("Restantes")
|
|
})
|
|
|
|
it("renders the remaining quantity for PARTIALLY_RETURNED rows", async () => {
|
|
const { default: AssignmentsPage } = await import(
|
|
"@/app/(dashboard)/assignments/page"
|
|
)
|
|
|
|
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
|
data: [
|
|
{
|
|
id: "assignment-1",
|
|
quantity: 5,
|
|
status: "PARTIALLY_RETURNED",
|
|
assignmentLineId: "line-1",
|
|
remainingQuantity: 3,
|
|
person: {
|
|
id: "person-1",
|
|
firstName: "Ada",
|
|
lastName: "Lovelace",
|
|
},
|
|
item: {
|
|
id: "item-1",
|
|
name: "Laptop",
|
|
},
|
|
asset: {
|
|
serialNumber: null,
|
|
},
|
|
},
|
|
],
|
|
totalPages: 1,
|
|
})
|
|
|
|
const html = renderToStaticMarkup(
|
|
await AssignmentsPage({ searchParams: Promise.resolve({}) }),
|
|
)
|
|
|
|
expect(html).toContain("Restantes")
|
|
expect(html).toContain("3 de 5")
|
|
})
|
|
|
|
it("renders the localized assignment empty state when no assignments exist", async () => {
|
|
const { default: AssignmentsPage } = await import(
|
|
"@/app/(dashboard)/assignments/page"
|
|
)
|
|
|
|
mocks.findAllWithPersonPaginated.mockResolvedValue({
|
|
data: [],
|
|
totalPages: 0,
|
|
})
|
|
|
|
const html = renderToStaticMarkup(
|
|
await AssignmentsPage({ searchParams: Promise.resolve({}) }),
|
|
)
|
|
|
|
expect(html).toContain("No se encontraron asignaciones.")
|
|
})
|
|
})
|