// 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"] },
}))