// The pages and components, rendered on the server the way the shell renders them: the platform's // refusals are the page's own states, every control has a name, every table a caption and scoped // headers. import { AppError, buildRegistry, Container, type TransportCaller } from "@conusai-kit/core" import { builtInCatalogues, createI18n, uiLabels } from "@conusai-kit/i18n" import { tenancyModule } from "@conusai-kit/tenancy" import { createDataClient, DataProvider, type PermissionKey, PermissionsProvider } from "@conusai-kit/ui/data" import { UiLabelsProvider } from "@conusai-kit/ui/primitives" import type { ReactNode } from "react" import { renderToStaticMarkup as renderMarkup } from "react-dom/server" import { describe, expect, it, vi } from "vitest" import { modulePages } from "../../pages.js" import { inventoryModule } from "../module.js" import { inventoryPage } from "../ui/pages.js" const catalogues = buildRegistry([tenancyModule, inventoryModule]).catalogues const i18n = createI18n("en", { en: { inventory: catalogues.en?.inventory ?? {}, app: { failed: "That did not work: {detail}" } }, }) const slugs = { org: "acme", workspace: "ws", project: "p" } const ITEM = "0b5c8e9e-1f2a-4c55-9a77-3f1e2d4c5b6a" const LOCATION = "7d1e2f3a-0000-4000-8000-000000000001" const EVERYTHING: readonly PermissionKey[] = ["inventory.item.read", "inventory.item.write", "inventory.stock.reserve"] /** Rendered as the shell renders a page: a data client, and the caller's permissions in the page's scope. */ const kitStrings = uiLabels(createI18n("en", builtInCatalogues)) const renderToStaticMarkup = (node: React.ReactNode) => renderMarkup({node}) const inProvider = (node: ReactNode, permissions: readonly PermissionKey[] = EVERYTHING) => renderToStaticMarkup( new Response(null, { status: 501 }) })}> {node} , ) /** A caller that answers each procedure from `answers`, or throws what is there. */ const callerOf = (answers: Record): TransportCaller => ({ call: async (contract: { name: string }) => { const answer = answers[contract.name] if (answer instanceof Error) throw answer return answer }, }) as unknown as TransportCaller const load = (segments: string[], answers: Record, reader = i18n) => inventoryPage.load({ slugs, segments, search: {}, caller: callerOf(answers), i18n: reader, container: new Container(), }) /** The page as the shell renders it: the loader's data through JSON, as the browser receives it, then the view. */ const render = async (segments: string[], answers: Record, permissions?: readonly PermissionKey[]) => { const data = await load(segments, answers) expect(JSON.parse(JSON.stringify(data))).toEqual(data) const { View } = inventoryPage return inProvider( , permissions, ) } const platformRefusal = (status: number, code: string, detail: string) => new AppError({ type: `/problems/${code}`, title: "Refused", status, code, detail }) describe("the inventory page", () => { it("lists the items and this project's reservations", async () => { const html = await render([], { "inventory.item.list": { rows: [{ itemId: ITEM, sku: "BOLT-8", name: "Bolt M8", unit: "pcs", description: null, active: true }], }, "inventory.reservation.list": { rows: [ { reservationId: "r1", itemId: ITEM, locationId: LOCATION, quantity: 3, outstanding: 3, released: 0, issued: 0, status: "open", createdAt: "2026-11-02T00:00:00.000Z", }, ], }, }) expect(html).toContain(">Inventory") const link = html.match(/]*>BOLT-8<\/a>/)?.[0] ?? "" expect(link).toContain('data-slot="row-link"') expect(link.match(/class="([^"]*)"/)?.[1]?.split(/\s+/)).toContain("kit-row-link") expect(link).toContain(`href="/acme/ws/p/inventory/${ITEM}"`) expect(link).toContain('aria-label="Stock of BOLT-8"') expect(html).toContain('aria-label="Items"') expect(html).toContain('aria-label="Open reservations of this project"') expect(html).toContain("BOLT-8 Bolt M8") expect(html).toContain("SKU") expect(html).toContain('role="search"') }) it("shows an item's stock by location, and the form that reserves it for whoever may", async () => { const answers = { "inventory.item.availability": { item: { itemId: ITEM, sku: "BOLT-8", name: "Bolt M8", unit: "pcs", description: null, active: true }, availability: { itemId: ITEM, unit: "pcs", onHand: 10, reserved: 3, available: 7, locations: [{ locationId: LOCATION, onHand: 10, reserved: 3, available: 7 }], }, }, } const html = await render([ITEM], answers) expect(html).toContain("Counted in pcs") expect(html).toContain("1 location with stock") expect(html).toContain('aria-label="Stock by location"') expect(html).toContain("7d1e2f3a") expect(html).toContain("Reserve for this project") expect(html).toContain("7d1e2f3a (7)") const reader = await render([ITEM], answers, ["inventory.item.read"]) expect(reader).not.toContain("Reserve for this project") }) it("offers the item form only to a member who may write items", async () => { const answers = { "inventory.item.list": { rows: [] }, "inventory.reservation.list": { rows: [] } } expect(await render([], answers)).toContain("New item") const reader = await render([], answers, ["inventory.item.read"]) expect(reader).not.toContain("New item") expect(reader).toContain("No items yet.") }) it("shows the kit's not-enabled state when the organization has not enabled the service", async () => { const refused = platformRefusal(404, "service_not_enabled", "Service admission refused: not_enabled.") const html = await render([], { "inventory.item.list": refused, "inventory.reservation.list": refused }) expect(html).toContain('data-state="service_not_enabled"') expect(html).toContain("This service is not enabled for your organization.") expect(html).not.toContain('role="grid"') }) it("tells a Lithuanian reader in the kit's Lithuanian sentence", async () => { const lt = createI18n("lt", { lt: { inventory: catalogues.lt?.inventory ?? {} } }) const refused = platformRefusal(404, "service_not_enabled", "Service admission refused: not_enabled.") const data = await load([], { "inventory.item.list": refused, "inventory.reservation.list": refused }, lt) expect(data).toMatchObject({ kind: "state", notice: { code: "service_not_enabled", text: "Ši paslauga jūsų organizacijai neįjungta." }, }) const answers = { "inventory.item.list": { rows: [] }, "inventory.reservation.list": { rows: [] } } const list = await load([], answers, lt) expect(list.kind === "list" && list.itemForm.refusals.business_duplicate).toBe("Toks įrašas jau yra.") expect(list.kind === "list" && list.reservationList.refusals.business_reservation_state).toBe( "Šio rezervavimo dabartinėje būsenoje pakeisti negalima.", ) }) it("shows a missing permission and a silent service in the kit's words", async () => { const scoped = platformRefusal(403, "service_permission_missing", "Service admission refused: permission_missing.") expect(await render([ITEM], { "inventory.item.availability": scoped })).toContain( "This app is not allowed to use this service. Ask an administrator to grant it.", ) const silent = platformRefusal(503, "business_unavailable", "The service did not answer. Try again later.") const html = await render([ITEM], { "inventory.item.availability": silent }) expect(html).toContain('data-state="business_unavailable"') expect(html).toContain("The service did not answer. Try again later.") }) it("leaves any other refusal, and a path it does not have, to the shell", async () => { await expect( render([ITEM], { "inventory.item.availability": new AppError({ type: "/problems/not_found", title: "Not found", status: 404, code: "not_found", }), }), ).rejects.toMatchObject({ problem: { code: "not_found" }, }) await expect(render(["not-an-id"], {})).rejects.toMatchObject({ problem: { status: 404 } }) await expect(render([ITEM, "more"], {})).rejects.toMatchObject({ problem: { status: 404 } }) }) it("is listed for the shell", async () => { await expect(modulePages.inventory?.()).resolves.toBe(inventoryPage) }) }) // Explicit synthetic admission: module-local fixtures exercise the selected module. vi.mock("../../inclusion.json", () => ({ default: { schemaVersion: 1, selected: ["inventory"], everAdopted: ["inventory"] }, }))