// The notes page on F10: the worked example. Its loader reads through the caller and returns plain data // with every label translated; the browser receives that data as JSON, so it must survive the round trip. import { notFound as notFoundError } from "@conusai-kit/core" import { describe, expect, it, vi } from "vitest" import { notesPage } from "../ui/pages.js" const slugs = { org: "acme", workspace: "general", project: "demo" } const i18n = { locale: "lt", message: (key: string, values?: Record) => `${key}${values ? ` ${JSON.stringify(values)}` : ""}`, date: (date: Date) => date.toISOString().slice(0, 10), } const load = (segments: readonly string[], call: (contract: unknown, input: unknown) => Promise) => notesPage.load({ slugs, segments, search: {}, caller: { call } as never, i18n: i18n as never, container: {} as never, }) const note = { noteId: "note-1", version: 3, title: "Roles", body: "text", attachmentCount: 0, createdAt: "2026-11-02T10:00:00.000Z", updatedAt: "2026-11-02T10:00:00.000Z", } describe("the notes page's loader", () => { it("returns the list, its first page and its labels as plain data", async () => { const call = vi.fn(async () => ({ notes: [note] })) const data = await load([], call) expect(call.mock.calls[0]?.[1 as never]).toEqual(slugs) expect(data).toMatchObject({ kind: "list", intro: "notes.intro", notes: [note] }) if (data.kind !== "list") throw new Error("not the list") expect(data.labels.title).toBe("notes.title") expect(JSON.parse(JSON.stringify(data))).toEqual(data) }) it("returns one note with its attachments as the live list's seed and its date already formatted", async () => { const call = vi.fn(async () => ({ note, attachments: [ { attachmentId: "a1", fileId: "f1", filename: "a.pdf", contentType: "application/pdf", size: 2048 }, ], attachmentsEnabled: true, })) const data = await load(["note-1"], call) expect(call.mock.calls[0]?.[1 as never]).toEqual({ ...slugs, noteId: "note-1" }) if (data.kind !== "note") throw new Error("not the note") expect(data.changed).toContain("2026-11-02") // The rows are the procedure's own: the live list reads the same shape again on a change. expect(data.attachments[0]).toMatchObject({ attachmentId: "a1", size: 2048 }) // The count and the size keep their placeholders for the browser, which knows the live numbers. expect(data.attachmentLabels.count).toBe("notes.attachments.count") expect(data.attachmentLabels.sizeKb).toBe("notes.attachments.sizeKb") expect(data.note).toEqual({ noteId: "note-1", title: "Roles", body: "text" }) expect(JSON.parse(JSON.stringify(data))).toEqual(data) }) it("answers a path it does not know as not found, without reading", async () => { const call = vi.fn() await expect(load(["note-1", "extra"], call)).rejects.toMatchObject({ status: 404 }) expect(call).not.toHaveBeenCalled() expect(notFoundError("no such page").status).toBe(404) }) it("hands a procedure's refusal on, for the shell to answer", async () => { await expect( load(["note-2"], async () => { throw notFoundError("no such note") }), ).rejects.toMatchObject({ status: 404 }) }) })