Files
2026-11-14 09:56:45 +00:00

82 lines
3.3 KiB
TypeScript

// 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<string, string | number>) =>
`${key}${values ? ` ${JSON.stringify(values)}` : ""}`,
date: (date: Date) => date.toISOString().slice(0, 10),
}
const load = (segments: readonly string[], call: (contract: unknown, input: unknown) => Promise<unknown>) =>
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 })
})
})