import { describe, expect, it } from "vitest"; import { EINGEBAUTE_VORLAGEN } from "../prisma/vorlagen"; import { VorlagenFehler, istIpAdresse, platzhalterErsetzen, vorlageAufloesen, vorlagePruefen, type VorlageEingabe, } from "@/lib/vorlagen"; /** Vorlagen und Platzhalter (#019). */ const BASIS: VorlageEingabe = { name: "Test", schluesselTyp: "ED25519", kategorie: "DIENST", zielbenutzer: "deploy", zielbenutzerAnlegen: true, sudoModus: "KEINER", sudoBefehle: [], knownHostsEintragen: true, privatNachAusrollenLoeschen: false, }; describe("Platzhalter", () => { it("ersetzt bekannte Platzhalter", () => { expect(platzhalterErsetzen('from="{{quellHostIp}}"', { quellHostIp: "10.0.0.5" })).toBe( 'from="10.0.0.5"', ); expect(platzhalterErsetzen("deploy-{{ zielHost }}", { zielHost: "srv-app01" })).toBe("deploy-srv-app01"); }); it("verweigert unbekannte, fehlende und gefaehrliche Werte", () => { expect(() => platzhalterErsetzen("{{irgendwas}}", {})).toThrow(VorlagenFehler); expect(() => platzhalterErsetzen("{{quellHostIp}}", {})).toThrow(/fehlt ein Wert/); expect(() => platzhalterErsetzen('from="{{quellHostIp}}"', { quellHostIp: '1.2.3.4",command="id' }), ).toThrow(VorlagenFehler); }); it("erkennt IP-Adressen", () => { expect(istIpAdresse("10.0.0.5")).toBe(true); expect(istIpAdresse("10.0.0.0/24")).toBe(true); expect(istIpAdresse("fe80::1")).toBe(true); expect(istIpAdresse("srv-app01")).toBe(false); }); }); describe("Vorlage pruefen", () => { it("nimmt alle eingebauten Vorlagen an", () => { for (const vorlage of EINGEBAUTE_VORLAGEN) { expect(() => vorlagePruefen({ ...BASIS, ...vorlage, beschreibung: vorlage.beschreibung ?? null, kategorie: vorlage.kategorie as "PERSON" | "DIENST", schluesselTyp: (vorlage.schluesselTyp ?? "ED25519") as "ED25519", sudoBefehle: [], zielbenutzerAnlegen: vorlage.zielbenutzerAnlegen ?? false, sudoModus: (vorlage.sudoModus ?? "KEINER") as "KEINER", knownHostsEintragen: vorlage.knownHostsEintragen ?? true, privatNachAusrollenLoeschen: false, }), ).not.toThrow(); } }); it.each([ [{ zielbenutzer: "Root" }, "zielbenutzer"], [{ authorizedKeysOptionen: 'from="{{unbekannt}}"' }, "authorizedKeysOptionen"], [{ authorizedKeysOptionen: "restriktiv" }, "authorizedKeysOptionen"], [{ sudoModus: "BEFEHLE" as const, sudoBefehle: [] }, "sudoBefehle"], [{ sudoModus: "BEFEHLE" as const, sudoBefehle: ["systemctl restart x"] }, "sudoBefehle"], [{ zielbenutzerAnlegen: false, sudoModus: "VOLL" as const }, "sudoModus"], [{ sshConfigAlias: "a b {{zielHost}}" }, "sshConfigAlias"], [{ kategorie: "PERSON" as const }, "kategorie"], ])("weist ab: %o", (fehler, feld) => { try { vorlagePruefen({ ...BASIS, ...fehler }); throw new Error("kein Fehler"); } catch (fehlerObjekt) { expect(fehlerObjekt).toBeInstanceOf(VorlagenFehler); expect((fehlerObjekt as VorlagenFehler).feld).toBe(feld); } }); }); describe("Vorlage aufloesen", () => { it("liefert Optionen, Alias und Ablaufdatum", () => { const jetzt = new Date("2026-10-12T10:00:00Z"); expect( vorlageAufloesen( { zielbenutzer: "deploy", authorizedKeysOptionen: 'from="{{quellHostIp}}"', sshConfigAlias: "deploy-{{zielHost}}", standardLaufzeitTage: 90, }, { quellHostIp: "10.0.0.5", zielHost: "srv-app01" }, jetzt, ), ).toEqual({ zielbenutzer: "deploy", authorizedKeysOptionen: 'from="10.0.0.5"', sshConfigAlias: "deploy-srv-app01", ablaufAm: new Date("2027-01-10T10:00:00Z"), }); }); });