feat(platzhalter): Aufloesung, Namensregeln und Shell-Maskierung (#26)
This commit was merged in pull request #26.
This commit is contained in:
+362
-127
@@ -1,150 +1,385 @@
|
||||
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";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { Betriebsmodus, Herkunft } from "@/generated/prisma/enums";
|
||||
import { ouAusDn, platzhalterWerteDesLaufs } from "@/server/services/platzhalter";
|
||||
import { platzhalterErsetzen } from "@/lib/platzhalter-werte";
|
||||
import { datenbankLeeren, datenbankVerfuegbar, testPrisma } from "./helpers/db";
|
||||
|
||||
/**
|
||||
* Die eingebauten Platzhalter (#010).
|
||||
* Die Werte hinter den Platzhaltern (#012).
|
||||
*
|
||||
* 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.
|
||||
* Aus diesen Werten entsteht der PowerShell-Befehl, den ein Techniker auf einem
|
||||
* Domaenencontroller ausfuehrt. Deshalb steht hier jede Regel des Auftrags
|
||||
* einzeln, mit den Daten, die im Haus wirklich vorkommen — einschliesslich
|
||||
* „Jörg Müller-Lüdenscheid“.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
const DN = "CN=Maria Huber,OU=Buchhaltung,OU=Benutzer,DC=firma,DC=local";
|
||||
|
||||
async function aufbau(modus: Betriebsmodus = Betriebsmodus.INTERN) {
|
||||
const eigene = await testPrisma.kunde.create({
|
||||
data: { name: "Muster GmbH", kuerzel: "MUS", istEigeneOrganisation: true },
|
||||
});
|
||||
await testPrisma.einstellung.create({ data: { id: "global", modus } });
|
||||
|
||||
const abteilung = await testPrisma.abteilung.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
name: "Buchhaltung",
|
||||
zielOu: "OU=Buchhaltung,OU=Benutzer,DC=firma,DC=de",
|
||||
standardGruppen: ["G-Buchhaltung", "G-Alle"],
|
||||
},
|
||||
});
|
||||
|
||||
it("nennt jeden Schluessel nur einmal", () => {
|
||||
const schluessel = EINGEBAUTE_PLATZHALTER.map((p) => p.schluessel);
|
||||
expect(new Set(schluessel).size).toBe(schluessel.length);
|
||||
const quelle = await testPrisma.verzeichnisquelle.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
name: "AD",
|
||||
url: "ldaps://dc01.firma.local:636",
|
||||
basisDn: "DC=firma,DC=local",
|
||||
filter: "(objectClass=user)",
|
||||
attributZuordnung: {},
|
||||
bindDn: "CN=svc,DC=firma,DC=local",
|
||||
bindPasswortVerschluesselt: "v1.egal",
|
||||
},
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
const chefin = await testPrisma.mitarbeiter.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
quelleId: quelle.id,
|
||||
externeId: "guid-chefin",
|
||||
vorname: "Sonja",
|
||||
nachname: "Brand",
|
||||
anzeigename: "Sonja Brand",
|
||||
sam: "sbrand",
|
||||
herkunft: Herkunft.ABGLEICH,
|
||||
},
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
const person = await testPrisma.mitarbeiter.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
quelleId: quelle.id,
|
||||
externeId: "guid-maria",
|
||||
vorname: "Maria",
|
||||
nachname: "Huber",
|
||||
anzeigename: "Maria Huber",
|
||||
mail: "maria.huber@firma.de",
|
||||
upn: "maria.huber@firma.de",
|
||||
sam: "mhuber",
|
||||
abteilung: "Buchhaltung",
|
||||
titel: "Sachbearbeiterin",
|
||||
dn: DN,
|
||||
vorgesetzterExterneId: "guid-chefin",
|
||||
herkunft: Herkunft.ABGLEICH,
|
||||
},
|
||||
});
|
||||
|
||||
it("kennzeichnet die Platzhalter, die nur im Modus Dienstleistung gefuellt sind", () => {
|
||||
const nurDienstleistung = EINGEBAUTE_PLATZHALTER.filter((p) => p.nurDienstleistung).map(
|
||||
(p) => p.schluessel,
|
||||
const geraet = await testPrisma.geraet.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
tagCode: "LZ-7K3F9Q",
|
||||
hostname: "PC-001",
|
||||
seriennummer: "SN-4711",
|
||||
inventarnummer: "INV-99",
|
||||
registriertAm: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
const vorlage = await testPrisma.vorlage.create({ data: { name: "Onboarding" } });
|
||||
const version = await testPrisma.vorlagenVersion.create({
|
||||
data: { vorlageId: vorlage.id, version: 1, status: "ENTWURF" },
|
||||
});
|
||||
await testPrisma.vorlagenVersion.update({
|
||||
where: { id: version.id },
|
||||
data: { status: "VEROEFFENTLICHT", veroeffentlichtAm: new Date() },
|
||||
});
|
||||
|
||||
return { eigene, abteilung, person, chefin, geraet, versionId: version.id };
|
||||
}
|
||||
|
||||
async function laufAnlegen(daten: Parameters<typeof testPrisma.lauf.create>[0]["data"]): Promise<string> {
|
||||
const lauf = await testPrisma.lauf.create({ data: daten });
|
||||
return lauf.id;
|
||||
}
|
||||
|
||||
describe("OU aus dem DN", () => {
|
||||
it("nimmt alles nach dem ersten Komma", () => {
|
||||
// Akzeptanzkriterium. Das ist der Ort, an dem das Konto liegt – genau den
|
||||
// braucht ein New-ADUser -Path.
|
||||
expect(ouAusDn(DN)).toBe("OU=Buchhaltung,OU=Benutzer,DC=firma,DC=local");
|
||||
});
|
||||
|
||||
it("übergeht ein maskiertes Komma im Namen", () => {
|
||||
// Im DN ist ein Komma innerhalb eines Namens mit Backslash maskiert. Ohne
|
||||
// diese Regel bliebe von „Huber\, Maria“ nur „ Maria,OU=…“ übrig.
|
||||
expect(ouAusDn("CN=Huber\\, Maria,OU=Buchhaltung,DC=firma,DC=local")).toBe(
|
||||
"OU=Buchhaltung,DC=firma,DC=local",
|
||||
);
|
||||
expect(nurDienstleistung.sort()).toEqual(["kunde", "kundenkuerzel"]);
|
||||
});
|
||||
|
||||
it("liefert nichts bei einem DN ohne Komma", () => {
|
||||
expect(ouAusDn("CN=Allein")).toBe("");
|
||||
expect(ouAusDn("")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unbekannte Platzhalter", () => {
|
||||
it("meldet, was weder eingebaut noch als Variable definiert ist", () => {
|
||||
expect(unbekanntePlatzhalter(["hostname", "os_version", "tipfehler"], ["os_version"])).toEqual([
|
||||
"tipfehler",
|
||||
]);
|
||||
describe.runIf(datenbankVerfuegbar)("Werte eines Laufs", () => {
|
||||
beforeEach(async () => {
|
||||
await datenbankLeeren();
|
||||
});
|
||||
|
||||
it("meldet nichts, wenn alles bekannt ist", () => {
|
||||
expect(unbekanntePlatzhalter(["hostname", "generiertes_passwort"], [])).toEqual([]);
|
||||
it("liefert Gerät, Lauf, Mitarbeiter und Abteilung", async () => {
|
||||
const { eigene, abteilung, person, geraet, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Onboarding Maria Huber",
|
||||
kundeId: eigene.id,
|
||||
mitarbeiterId: person.id,
|
||||
geraetId: geraet.id,
|
||||
abteilungId: abteilung.id,
|
||||
ticket: "INC-4711",
|
||||
});
|
||||
|
||||
const werte = await platzhalterWerteDesLaufs({
|
||||
laufId,
|
||||
technikerName: "Ali Demir",
|
||||
jetzt: new Date("2026-09-25T10:00:00Z"),
|
||||
});
|
||||
|
||||
expect(werte).toMatchObject({
|
||||
hostname: "PC-001",
|
||||
seriennummer: "SN-4711",
|
||||
inventarnummer: "INV-99",
|
||||
ticket: "INC-4711",
|
||||
datum: "25.09.2026",
|
||||
techniker: "Ali Demir",
|
||||
mitarbeiter: "Maria Huber",
|
||||
benutzer: "Maria Huber",
|
||||
vorname: "Maria",
|
||||
nachname: "Huber",
|
||||
upn: "maria.huber@firma.de",
|
||||
sam: "mhuber",
|
||||
mail: "maria.huber@firma.de",
|
||||
abteilung: "Buchhaltung",
|
||||
titel: "Sachbearbeiterin",
|
||||
dn: DN,
|
||||
gruppen: "G-Buchhaltung, G-Alle",
|
||||
vorgesetzter: "Sonja Brand",
|
||||
vorgesetzter_sam: "sbrand",
|
||||
});
|
||||
});
|
||||
|
||||
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([]);
|
||||
it("nimmt für die OU den Eltern-Container des dn, nicht die Ziel-OU", async () => {
|
||||
// Der dn sagt, wo das Konto **wirklich** liegt; die Ziel-OU der Abteilung
|
||||
// ist die Absicht fuer ein Konto, das es noch nicht gibt.
|
||||
const { eigene, abteilung, person, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Umzug",
|
||||
kundeId: eigene.id,
|
||||
mitarbeiterId: person.id,
|
||||
abteilungId: abteilung.id,
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["ou"]).toBe("OU=Buchhaltung,OU=Benutzer,DC=firma,DC=local");
|
||||
});
|
||||
|
||||
it("nimmt die Ziel-OU der Abteilung, wenn die Person keinen dn hat", async () => {
|
||||
// Der Onboarding-Fall: das Konto gibt es noch nicht.
|
||||
const { eigene, abteilung, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Onboarding",
|
||||
kundeId: eigene.id,
|
||||
mitarbeiterName: "Jörg Müller-Lüdenscheid",
|
||||
abteilungId: abteilung.id,
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["ou"]).toBe("OU=Buchhaltung,OU=Benutzer,DC=firma,DC=de");
|
||||
expect(werte["mitarbeiter"]).toBe("Jörg Müller-Lüdenscheid");
|
||||
expect(werte["benutzer"]).toBe("Jörg Müller-Lüdenscheid");
|
||||
});
|
||||
|
||||
it("lässt im Modus Intern Kunde und Kürzel leer", async () => {
|
||||
// Akzeptanzkriterium: im Modus Intern gibt es die Kundenebene fuer den
|
||||
// Benutzer nicht – ihren Namen in einen Befehl zu schreiben waere eine
|
||||
// Auskunft ueber etwas, das es dort nicht gibt.
|
||||
const { eigene, versionId } = await aufbau(Betriebsmodus.INTERN);
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Patchday",
|
||||
kundeId: eigene.id,
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["kunde"]).toBeUndefined();
|
||||
expect(werte["kundenkuerzel"]).toBeUndefined();
|
||||
|
||||
// Und in der Ersetzung wird daraus leer, nicht „unbekannt“.
|
||||
const ergebnis = platzhalterErsetzen("[{{kunde}}]", werte);
|
||||
expect(ergebnis.text).toBe("[]");
|
||||
expect(ergebnis.unbekannt).toEqual([]);
|
||||
});
|
||||
|
||||
it("füllt im Modus Dienstleistung Kunde und Kürzel", async () => {
|
||||
const { eigene, versionId } = await aufbau(Betriebsmodus.DIENSTLEISTUNG);
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Patchday",
|
||||
kundeId: eigene.id,
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["kunde"]).toBe("Muster GmbH");
|
||||
expect(werte["kundenkuerzel"]).toBe("MUS");
|
||||
});
|
||||
|
||||
it("nimmt die Bezeichnung, wenn ein Gerät keinen Hostname hat", async () => {
|
||||
const { eigene, versionId } = await aufbau();
|
||||
const schrank = await testPrisma.geraet.create({
|
||||
data: {
|
||||
kundeId: eigene.id,
|
||||
tagCode: "LZ-8M4G2R",
|
||||
bezeichnung: "Serverschrank Keller",
|
||||
registriertAm: new Date(),
|
||||
},
|
||||
});
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Wartung",
|
||||
kundeId: eigene.id,
|
||||
geraetId: schrank.id,
|
||||
});
|
||||
expect((await platzhalterWerteDesLaufs({ laufId }))["hostname"]).toBe("Serverschrank Keller");
|
||||
});
|
||||
|
||||
it("lässt eine Vorlagenvariable den Gerätewert überschreiben", async () => {
|
||||
/*
|
||||
* Die Variable ist die ausdrueckliche Angabe **dieses** Laufs, der
|
||||
* Geraetewert nur die Voreinstellung. Beim Umbenennen eines Rechners steht
|
||||
* im Befehl der neue Name, nicht der alte aus der Datenbank.
|
||||
*/
|
||||
const { eigene, geraet, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Umbenennen",
|
||||
kundeId: eigene.id,
|
||||
geraetId: geraet.id,
|
||||
variablen: { hostname: "PC-NEU-007", os_version: "Windows 11 Pro" },
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["hostname"]).toBe("PC-NEU-007");
|
||||
expect(werte["os_version"]).toBe("Windows 11 Pro");
|
||||
});
|
||||
|
||||
it("lässt eine Variable die gesperrten Platzhalter nicht überschreiben", async () => {
|
||||
/*
|
||||
* Der Blocker aus dem Review: die Vorlagenvariablen gewannen gegen **alles**.
|
||||
* Eine Variable `techniker` liess einen Befehl mit fremdem Namen
|
||||
* unterschreiben, eine Variable `kunde` holte im Modus INTERN die
|
||||
* Kundenebene zurueck, die es dort ausdruecklich nicht gibt.
|
||||
*/
|
||||
const { eigene, versionId } = await aufbau(Betriebsmodus.INTERN);
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Angriff",
|
||||
kundeId: eigene.id,
|
||||
variablen: {
|
||||
kunde: "Fremde AG",
|
||||
kundenkuerzel: "FRD",
|
||||
techniker: "Nicht ich",
|
||||
datum: "01.01.1999",
|
||||
generiertes_passwort: "geheim",
|
||||
},
|
||||
});
|
||||
|
||||
const werte = await platzhalterWerteDesLaufs({
|
||||
laufId,
|
||||
technikerName: "Ali Demir",
|
||||
jetzt: new Date("2026-09-25T10:00:00Z"),
|
||||
});
|
||||
|
||||
expect(werte["kunde"]).toBeUndefined();
|
||||
expect(werte["kundenkuerzel"]).toBeUndefined();
|
||||
expect(werte["techniker"]).toBe("Ali Demir");
|
||||
expect(werte["datum"]).toBe("25.09.2026");
|
||||
expect(werte["generiertes_passwort"]).toBeUndefined();
|
||||
|
||||
// Und das Passwort bleibt das erzeugte, nicht das aus der Variablen.
|
||||
const ergebnis = platzhalterErsetzen("{{generiertes_passwort}}", werte);
|
||||
expect(ergebnis.text).not.toBe("geheim");
|
||||
expect(ergebnis.text).toHaveLength(20);
|
||||
});
|
||||
|
||||
it("nimmt Zahlen und Haken aus den Variablen als Text auf", async () => {
|
||||
const { eigene, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Prüfung",
|
||||
kundeId: eigene.id,
|
||||
variablen: { arbeitsspeicher: 32, verschluesselt: true, kaputt: { tief: 1 } },
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["arbeitsspeicher"]).toBe("32");
|
||||
expect(werte["verschluesselt"]).toBe("true");
|
||||
// Was kein einfacher Wert ist, bleibt draussen – im Befehl stuende sonst
|
||||
// „[object Object]“.
|
||||
expect(werte["kaputt"]).toBeUndefined();
|
||||
});
|
||||
|
||||
it("kommt mit einem Lauf ohne Gerät und ohne Person aus", async () => {
|
||||
// Ein Lauf ohne beides ist gueltig: Server, Firewall, Patchday. Abzubrechen
|
||||
// hiesse, dem Techniker die Arbeit zu verweigern.
|
||||
const { eigene, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Patchday",
|
||||
kundeId: eigene.id,
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
expect(werte["hostname"]).toBeUndefined();
|
||||
expect(werte["mitarbeiter"]).toBeUndefined();
|
||||
expect(werte["datum"]).toBeTruthy();
|
||||
});
|
||||
|
||||
it("liefert nichts für einen Lauf, den es nicht gibt", async () => {
|
||||
expect(await platzhalterWerteDesLaufs({ laufId: "gibtsnicht" })).toEqual({});
|
||||
});
|
||||
|
||||
it("baut einen vollständigen New-ADUser-Befehl", async () => {
|
||||
/*
|
||||
* Der Ablauf aus dem Auftrag, Ende zu Ende: Abteilung „Buchhaltung“ gewählt,
|
||||
* daraus `-Path "OU=Buchhaltung,…"` und die Gruppen `G-Buchhaltung, G-Alle`.
|
||||
*/
|
||||
const { eigene, abteilung, versionId } = await aufbau();
|
||||
const laufId = await laufAnlegen({
|
||||
vorlagenVersionId: versionId,
|
||||
titel: "Onboarding",
|
||||
kundeId: eigene.id,
|
||||
mitarbeiterName: "Jörg Müller-Lüdenscheid",
|
||||
abteilungId: abteilung.id,
|
||||
variablen: { upn: "joerg.mueller-luedenscheid@firma.de", sam: "jmuellerluedensch" },
|
||||
});
|
||||
const werte = await platzhalterWerteDesLaufs({ laufId });
|
||||
|
||||
const befehl = platzhalterErsetzen(
|
||||
'New-ADUser -Name "{{mitarbeiter}}" -UserPrincipalName "{{upn}}" ' +
|
||||
'-SamAccountName "{{sam}}" -Path "{{ou}}"',
|
||||
werte,
|
||||
{ art: "befehl", maskieren: (wert) => wert },
|
||||
);
|
||||
|
||||
expect(befehl.text).toBe(
|
||||
'New-ADUser -Name "Jörg Müller-Lüdenscheid" ' +
|
||||
'-UserPrincipalName "joerg.mueller-luedenscheid@firma.de" ' +
|
||||
'-SamAccountName "jmuellerluedensch" ' +
|
||||
'-Path "OU=Buchhaltung,OU=Benutzer,DC=firma,DC=de"',
|
||||
);
|
||||
expect(befehl.unbekannt).toEqual([]);
|
||||
|
||||
const gruppen = platzhalterErsetzen("Add-ADGroupMember {{gruppen}}", werte, {
|
||||
art: "befehl",
|
||||
maskieren: (wert) => wert,
|
||||
});
|
||||
expect(gruppen.text).toBe("Add-ADGroupMember G-Buchhaltung, G-Alle");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user