ConusAI vendor v0.1.0-beta.114
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-beta.114
2026-11-14 09:56:45 +00:00
commit 1ce8d23c35
867 changed files with 122104 additions and 0 deletions
+307
View File
@@ -0,0 +1,307 @@
// The components' markup, rendered on the server the way a page renders it: what a screen reader and
// a keyboard user get is in the HTML, so the accessibility basics are asserted there -- a name for
// every control, a caption and scoped headers for every table, a status that says what a colour would.
import { buildRegistry } from "@conusai-kit/core"
import { builtInCatalogues, createI18n, uiLabels } from "@conusai-kit/i18n"
import { createDataClient, DataProvider } from "@conusai-kit/ui/data"
import { UiLabelsProvider } from "@conusai-kit/ui/primitives"
import { renderToStaticMarkup as renderMarkup } from "react-dom/server"
import { describe, expect, it, vi } from "vitest"
import { appModules } from "../../index.js"
import type { DocumentView, LineView } from "../contract/index.js"
import {
DocumentList,
documentHeader,
ExportButton,
exportLabels,
headerLabels,
LineReview,
listLabels,
reviewLabels,
UploadForm,
uploadLabels,
} from "../ui/index.js"
const en = buildRegistry([...appModules]).catalogues.en?.documents ?? {}
const t = (key: string, values?: Record<string, string | number>) => {
let text = en[key as keyof typeof en] ?? `?${key}`
for (const [name, value] of Object.entries(values ?? {})) text = text.replace(`{${name}}`, String(value))
return text
}
const slugs = { org: "acme", workspace: "ws", project: "p" }
const shared = { failed: "That did not work: {detail}", aiDisclosure: "AI-generated content", pageWord: "Page" }
const line = (over: Partial<LineView> = {}): LineView => ({
lineId: "l1",
expectedVersion: 1,
status: "pending",
label: "Reference",
value: "QR-1",
page: 1,
quote: "Reference: QR-1",
box: { x: 0.1, y: 0.2, width: 0.5, height: 0.03 },
confidence: 0.97,
edited: false,
verification: "verified",
note: null,
blockId: null,
model: "fixture+gateway",
promptVersion: "extract-lines.v2",
decidedAt: null,
...over,
})
const kitStrings = uiLabels(createI18n("en", builtInCatalogues))
const renderToStaticMarkup = (node: React.ReactNode) =>
renderMarkup(<UiLabelsProvider labels={kitStrings}>{node}</UiLabelsProvider>)
const inProvider = (node: React.ReactNode) =>
renderToStaticMarkup(
<DataProvider client={createDataClient({ fetch: async () => new Response(null, { status: 501 }) })}>
{node}
</DataProvider>,
)
const review = (lines: LineView[]) =>
inProvider(
<LineReview
slugs={slugs}
fileId="f1"
lines={lines}
labels={reviewLabels(t, shared)}
locale="en"
onDecided={async () => undefined}
/>,
)
describe("the review table", () => {
const html = review([
line(),
line({ lineId: "l2", label: "Total", status: "approved" }),
line({ lineId: "l3", label: "Date", status: "rejected" }),
])
it("tells a reader the content is machine-proposed, in text", () => {
expect(html).toContain("AI-generated content")
expect(html).toContain("Proposed by fixture+gateway extract-lines.v2")
})
it("is a table with a caption and a scoped header for every column", () => {
expect(html).toMatch(/<caption\b[^>]*>Extracted lines<\/caption>/)
expect(html.match(/<th\b[^>]*scope="col"[^>]*>/g)).toHaveLength(7)
expect(html).toMatch(/<th\b[^>]*scope="row"[^>]*>Reference<\/th>/)
})
it("names each action by the line it acts on, so a list of buttons is not a list of 'Approve'", () => {
for (const name of ["Approve Reference", "Edit Reference", "Reject Reference"]) expect(html).toContain(name)
})
it("offers no action on a line that has been decided, and says what was decided in words", () => {
expect(html).not.toContain("Approve Total")
expect(html).not.toContain("Reject Date")
for (const word of ["To review", "Approved", "Rejected"]) expect(html).toContain(word)
})
it("shows the source of every line, labelled with its page", () => {
expect(html).toContain('aria-label="Source, page 1"')
expect(html).toContain("Reference: QR-1")
})
it("approves every verified pending line at once, only while there is one", () => {
expect(html).toContain("Approve all verified lines")
expect(review([line({ status: "approved" })])).not.toContain("Approve all verified lines")
})
it("marks a line whose quote was not found, and does not offer it to the bulk approval", () => {
const flagged = review([line({ verification: "needs_review" })])
expect(flagged).toContain("Needs review: the quoted words were not found on the page.")
expect(flagged).not.toContain("Approve all verified lines")
expect(html).not.toContain("Needs review")
})
it("says a quote read off a scanned page must be checked against the image, instead of the plain note", () => {
const flagged = review([line({ verification: "needs_review", note: "scanned_quote" })])
expect(flagged).toContain("comes from a scanned page")
expect(flagged).toContain("Check it against the page image.")
expect(flagged).not.toContain("were not found on the page")
})
it("names the reader's block beside the source when it gave one", () => {
expect(review([line({ blockId: "p3-b2" })])).toContain("Block p3-b2")
expect(review([line()])).not.toContain("Block ")
})
it("says so when there is nothing to review", () => {
expect(review([])).toContain("No lines were proposed for this document.")
})
})
describe("the document list", () => {
const documents: DocumentView[] = [
{
documentId: "d1",
fileId: "f1",
filename: "report.pdf",
status: "extracted",
failureCode: null,
pageCount: 2,
skippedPages: [],
pending: 3,
approved: 1,
uploadedAt: "2026-10-19T09:00:00.000Z",
},
{
documentId: "d2",
fileId: "f2",
filename: "scan.png",
status: "failed",
failureCode: "ocr_failed",
pageCount: null,
skippedPages: [],
pending: 0,
approved: 0,
uploadedAt: "2026-10-19T09:05:00.000Z",
},
{
documentId: null,
fileId: "f3",
filename: "new.pdf",
status: "queued",
failureCode: null,
pageCount: null,
skippedPages: [],
pending: 0,
approved: 0,
uploadedAt: "2026-10-19T09:06:00.000Z",
},
]
const html = renderToStaticMarkup(
<DocumentList
documents={documents}
hrefFor={(id) => `/d/${id}`}
downloadHrefFor={(id) => `/api/v1/files.file.download?fileId=${id}`}
labels={listLabels(t)}
formatDate={(iso) => iso.slice(0, 10)}
/>,
)
it("links each document by a name that says which one", () => {
expect(html).toContain('href="/d/f1"')
expect(html).toContain('aria-label="Review report.pdf"')
expect(html).toContain('href="/api/v1/files.file.download?fileId=f1"')
expect(html).toContain(">Download report.pdf</a>")
})
it("writes each state and each failure as text", () => {
expect(html).toContain("Ready for review")
expect(html).toContain("Could not be read The reader could not process this file.")
expect(html).toContain("Waiting to be read")
})
it("is a captioned table, or a sentence when there is nothing to list", () => {
expect(html).toContain('aria-label="Documents"')
expect(
renderToStaticMarkup(
<DocumentList
documents={[]}
hrefFor={() => ""}
downloadHrefFor={() => ""}
labels={listLabels(t)}
formatDate={() => ""}
/>,
),
).toContain("No documents yet.")
})
})
describe("the export button", () => {
const render = (approved: number) =>
inProvider(<ExportButton slugs={slugs} fileId="f1" approved={approved} labels={exportLabels(t, shared.failed)} />)
it("is disabled with nothing approved, and the reason is the text its description points at", () => {
const html = render(0)
expect(html).toMatch(/<button[^>]*disabled=""[^>]*aria-describedby="([^"]+)"/)
const id = /aria-describedby="([^"]+)"/.exec(html)?.[1] ?? ""
expect(html).toContain(`id="${id}">Approve at least one line to export.`)
})
it("waits for hydration even with approved lines, and explains what will be exported", () => {
const html = render(2)
expect(html).toContain('disabled=""')
expect(html).toContain("Only approved lines are exported.")
})
})
describe("the document's header", () => {
// Built wherever the live document renders, so the counts and the skipped pages follow a change.
const view = (over: Partial<DocumentView> = {}): DocumentView => ({
documentId: "d1",
fileId: "f1",
filename: "report.pdf",
status: "extracted",
failureCode: null,
pageCount: 3,
skippedPages: [],
pending: 1,
approved: 2,
uploadedAt: "2026-10-19T09:00:00.000Z",
...over,
})
it("says the status and counts the lines with the language's plurals", () => {
const header = documentHeader(view(), headerLabels(t), "en")
expect(header.status).toBe("Status: Ready for review")
expect(header.counts).toBe("1 line to review. 2 lines approved.")
expect(header.waiting).toBeUndefined()
expect(header.skipped).toBeUndefined()
})
it("says a document nobody has read yet is waiting, and names a failure", () => {
expect(documentHeader(view({ status: "processing" }), headerLabels(t), "en").waiting).toBeTruthy()
const failed = documentHeader(view({ status: "failed", failureCode: "ocr_failed" }), headerLabels(t), "en")
expect(failed.status).toMatch(/^Status: \S.* \S/)
})
it("lists the pages the extraction left out, each with its kind", () => {
const header = documentHeader(view({ skippedPages: [{ page: 3, pageClass: "drawing" }] }), headerLabels(t), "en")
expect(header.skipped).toEqual({
title: "Pages not read",
pages: [{ page: 3, text: "Page 3: drawing. It was left out of the extraction." }],
})
})
})
describe("the upload form", () => {
// The page's data client: the form uploads through the facade's `useUpload`, which asks the
// client the app provides for a way to send a body.
const html = renderToStaticMarkup(
<DataProvider client={createDataClient({ fetch: async () => new Response(null, { status: 501 }) })}>
<UploadForm
slugs={slugs}
accept={["application/pdf"]}
labels={uploadLabels(t)}
onUploaded={async () => undefined}
/>
</DataProvider>,
)
it("labels its file input and describes it with the hint", () => {
// React writes an input's attributes in its own order (`type` first), so the pattern does not fix one.
const id = /<input [^>]*\bid="([^"]+)"[^>]*\bname="file"/.exec(html)?.[1]
expect(id).toBeTruthy()
expect(html).toMatch(new RegExp(`<label [^>]*for="${id}"[^>]*>Upload a document</label>`))
expect(html).toContain("aria-describedby=")
expect(html).toContain("PDF, PNG or JPEG, up to 50 MB.")
})
it("asks the browser for the types the module reads and requires a file", () => {
expect(html).toContain('accept="application/pdf"')
expect(html).toContain('required=""')
})
})
// Explicit synthetic admission: module-local fixtures exercise the selected module.
vi.mock("../../inclusion.json", () => ({
default: { schemaVersion: 1, selected: ["documents"], everAdopted: ["documents"] },
}))