Files
paliad/frontend/src/lib/docforge-editor/dom.test.ts
mAi b8709b903d feat(docforge): slice 5 — docforge-editor pkg + variable catalogue SSOT (t-paliad-349)
Establish the shared frontend editor package and make the Go resolvers the
single source of truth for variable labels.

Go — catalogue SSOT:
  - VariableResolver gains Keys() []VariableKey; ResolverSet gains
    Catalogue(). The 7 submission resolvers implement Keys() with the
    bilingual labels ported from the TS VARIABLE_LABELS table (incl. the
    legacy rule.* aliases). Keys() is entity-independent, so
    SubmissionVariableCatalogue() builds a metadata-only ResolverSet.
  - GET /api/docforge/variables serves the catalogue (auth-gated, static).
  - Tests: docforge ResolverSet (BuildBag merge + Catalogue order) and the
    submission catalogue integrity (no dupes, labels present, spot-checks).

Frontend — frontend/src/lib/docforge-editor/ (new shared package):
  - dom.ts: escapeHtml + cssEscape (pure), with bun tests. Dedupes the two
    identical escapeHtml/escapeHTML copies + the cssEscape copy that lived
    in the submission editor.
  - catalogue.ts: fetchVariableCatalogue() + labelMap() — the client for
    the Go catalogue.
  - submission-draft.ts now imports escapeHtml/cssEscape from the lib and
    fetches the catalogue on boot into state.varLabels (labelFor reads it,
    falling back to the raw key if the fetch fails — graceful degrade). The
    hardcoded VARIABLE_LABELS table is removed; VARIABLE_GROUPS stays
    (presentation: which keys to show + how to section them, legitimately
    frontend).

Scope note: the DOM-coupled editor plumbing (wireDraftVars/focus
preservation/autosave debounce) is extracted in slice 6 alongside its first
reuse — the authoring page — rather than speculatively now (extract with the
consumer; same principle as slices 2-3). Slice 5 lands the pure utilities +
the catalogue, which the slice-6 authoring palette consumes.

Verification: go build/vet/test green (Go files gofmt-clean; handlers.go
pre-existing drift, added region clean); bun run build.ts clean;
bun test 274/274 (incl. 5 new docforge-editor tests).

m/paliad#157
2026-05-29 15:50:42 +02:00

27 lines
987 B
TypeScript

import { test, expect } from "bun:test";
import { escapeHtml, cssEscape } from "./dom";
test("escapeHtml escapes the five HTML-significant characters", () => {
expect(escapeHtml(`<a href="x" title='y'>& z</a>`)).toBe(
"&lt;a href=&quot;x&quot; title=&#39;y&#39;&gt;&amp; z&lt;/a&gt;",
);
});
test("escapeHtml is a no-op on plain text", () => {
expect(escapeHtml("Aktenzeichen 4c O 12/23")).toBe("Aktenzeichen 4c O 12/23");
});
test("escapeHtml escapes & first to avoid double-encoding", () => {
expect(escapeHtml("&lt;")).toBe("&amp;lt;");
});
test("cssEscape backslash-escapes the dots in a placeholder key", () => {
// Both CSS.escape and the regex fallback escape '.' the same way, so the
// result is stable across environments (bun has no CSS global → fallback).
expect(cssEscape("project.case_number")).toBe("project\\.case_number");
});
test("cssEscape leaves identifier-safe characters untouched", () => {
expect(cssEscape("today")).toBe("today");
});