feat(vorlagen): Editor, Liste und Versionsgeschichte (#24)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

This commit was merged in pull request #24.
This commit is contained in:
2026-09-25 08:23:22 +00:00
parent d8d5444e9f
commit e3d80e5982
65 changed files with 5454 additions and 103 deletions
+150
View File
@@ -0,0 +1,150 @@
import { describe, expect, it } from "vitest";
import {
EINGEBAUTE_PLATZHALTER,
QUELLEN_TEXT,
istEingebaut,
unbekanntePlatzhalter,
unbenutzteVariablen,
} from "@/lib/platzhalter";
import { platzhalterDerStruktur, VariableSchema, type Struktur } from "@/lib/vorlagen-format";
/**
* Die eingebauten Platzhalter (#010).
*
* Die Liste ist Daten, und Daten koennen still falsch sein: ein Schluessel mit
* Bindestrich wuerde im Lauf nie ersetzt, weil `platzhalterFinden` ihn nicht als
* Platzhalter erkennt. Deshalb wird die Liste hier gegen genau dieselbe Regel
* geprueft, die auch fuer Variablen gilt.
*/
describe("Liste der eingebauten Platzhalter", () => {
it("haelt sich an die Schluesselregel der Variablen", () => {
const schluesselRegel = VariableSchema.shape.schluessel;
for (const platzhalter of EINGEBAUTE_PLATZHALTER) {
const ergebnis = schluesselRegel.safeParse(platzhalter.schluessel);
expect(ergebnis.success, `${platzhalter.schluessel}: ${ergebnis.error?.message}`).toBe(true);
}
});
it("nennt jeden Schluessel nur einmal", () => {
const schluessel = EINGEBAUTE_PLATZHALTER.map((p) => p.schluessel);
expect(new Set(schluessel).size).toBe(schluessel.length);
});
it("erklaert jeden Platzhalter und ordnet ihn einer benannten Quelle zu", () => {
for (const platzhalter of EINGEBAUTE_PLATZHALTER) {
expect(platzhalter.erklaerung.trim().length, platzhalter.schluessel).toBeGreaterThan(0);
expect(QUELLEN_TEXT[platzhalter.quelle], platzhalter.schluessel).toBeTruthy();
}
});
it("enthaelt die im Auftrag genannten Platzhalter", () => {
// Namentlich, damit das Verschwinden eines einzelnen auffaellt – eine
// Vorlage, die ihn benutzt, bekaeme sonst plötzlich eine Warnung.
for (const schluessel of [
"hostname",
"seriennummer",
"inventarnummer",
"ticket",
"datum",
"techniker",
"kunde",
"kundenkuerzel",
"mitarbeiter",
"benutzer",
"vorname",
"nachname",
"upn",
"sam",
"mail",
"abteilung",
"titel",
"vorgesetzter",
"vorgesetzter_sam",
"dn",
"ou",
"gruppen",
"generiertes_passwort",
]) {
expect(istEingebaut(schluessel), schluessel).toBe(true);
}
});
it("kennzeichnet die Platzhalter, die nur im Modus Dienstleistung gefuellt sind", () => {
const nurDienstleistung = EINGEBAUTE_PLATZHALTER.filter((p) => p.nurDienstleistung).map(
(p) => p.schluessel,
);
expect(nurDienstleistung.sort()).toEqual(["kunde", "kundenkuerzel"]);
});
});
describe("Unbekannte Platzhalter", () => {
it("meldet, was weder eingebaut noch als Variable definiert ist", () => {
expect(unbekanntePlatzhalter(["hostname", "os_version", "tipfehler"], ["os_version"])).toEqual([
"tipfehler",
]);
});
it("meldet nichts, wenn alles bekannt ist", () => {
expect(unbekanntePlatzhalter(["hostname", "generiertes_passwort"], [])).toEqual([]);
});
it("findet einen Tippfehler in einem echten Aufbau", () => {
// Der praktische Fall: „{{hostnmae}}" im Befehl. Ohne Warnung merkt es erst
// der Techniker, wenn der Befehl den Platzhalter im Klartext enthaelt.
const struktur: Struktur = {
variablen: [
{
schluessel: "os_version",
beschriftung: "Betriebssystem",
typ: "TEXT",
optionen: [],
pflicht: false,
},
],
abschnitte: [
{
titel: "Installation",
schritte: [
{
titel: "Rechner umbenennen",
typ: "BEFEHL",
pflicht: true,
konfig: {
shell: "powershell",
befehl: 'Rename-Computer -NewName "{{hostnmae}}" # soll {{hostname}} sein',
},
},
{
titel: "{{os_version}} installieren",
hilfetext: "Danach {{ datum }} im Ticket vermerken.",
typ: "HAKEN",
pflicht: true,
konfig: {},
},
],
},
],
};
const verwendet = platzhalterDerStruktur(struktur);
expect(verwendet).toContain("hostnmae");
expect(
unbekanntePlatzhalter(
verwendet,
struktur.variablen.map((v) => v.schluessel),
),
).toEqual(["hostnmae"]);
});
});
describe("Unbenutzte Variablen", () => {
it("meldet eine Variable, die nirgends vorkommt", () => {
// Eine definierte Variable, die kein Schritt benutzt, fragt den Techniker
// beim Start nach etwas, das nie irgendwo auftaucht.
expect(unbenutzteVariablen(["hostname"], ["os_version", "join_typ"])).toEqual(["os_version", "join_typ"]);
});
it("meldet nichts, wenn jede Variable benutzt wird", () => {
expect(unbenutzteVariablen(["os_version"], ["os_version"])).toEqual([]);
});
});