97 lines
5.6 KiB
TypeScript
97 lines
5.6 KiB
TypeScript
import { afterEach, expect, it, mock } from "bun:test";
|
||
import { promises as fs } from "node:fs";
|
||
import { tmpdir } from "node:os";
|
||
import { join } from "node:path";
|
||
import { createHash } from "node:crypto";
|
||
import { migrate } from "../tools/migrate-ki-datenschutz.mjs";
|
||
|
||
mock.module("@raycast/api", () => ({ environment: { supportPath: tmpdir() } }));
|
||
const { restorePath, restoreText } = await import("../src/lib/velum-project");
|
||
const roots: string[] = [];
|
||
afterEach(async () => { await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true }))); });
|
||
|
||
it("migriert einen künstlichen Altbestand verlustarm ohne den Quellordner zu ändern", async () => {
|
||
const root = await fs.mkdtemp(join(tmpdir(), "velum-legacy-test-"));
|
||
roots.push(root);
|
||
const project = join(root, "Projekt");
|
||
const targetSupport = join(root, "VelumSupport");
|
||
const oldSupport = join(root, "OldSupport");
|
||
const previewFile = join(root, "Migrationsvorschau.md");
|
||
await fs.mkdir(project);
|
||
await fs.mkdir(join(oldSupport, "projects"), { recursive: true });
|
||
const legacyName = "KUNDE ALPHA.txt";
|
||
const legacyContent = "kundeAlphaService und KUNDE ALPHA";
|
||
await fs.writeFile(join(project, legacyName), legacyContent);
|
||
await fs.writeFile(join(project, "Handbuch.docx"), "office");
|
||
await fs.writeFile(join(project, "leer.txt"), "Ohne Platzhalter");
|
||
const projectId = createHash("sha1").update(project).digest("hex").slice(0, 16);
|
||
const manifestFile = join(oldSupport, "projects", `${projectId}.json`);
|
||
await fs.writeFile(manifestFile, JSON.stringify({
|
||
version: 1, projectPath: project, projectTerms: [{ id: "t1", term: "Müller GmbH", category: "Kunde", enabled: true, aliases: [] }],
|
||
variantTable: [
|
||
{ termId: "t1", termVariant: "Müller GmbH", placeholderVariant: "KUNDE ALPHA", style: "typed", boundary: "strict" },
|
||
{ termId: "t1", termVariant: "muellerGmbh", placeholderVariant: "kundeAlpha", style: "camel", boundary: "identifier" },
|
||
],
|
||
}));
|
||
const preview = await migrate({ project, manifestFile, targetSupport, previewFile });
|
||
expect(preview.applied).toBe(false);
|
||
expect(preview.summary.files).toBe(2);
|
||
expect(preview.summary.skipped).toBe(1);
|
||
const report = await fs.readFile(previewFile, "utf8");
|
||
expect(report).toContain('"KUNDE ALPHA.txt"');
|
||
expect(report).toContain('"KUNDE_100001.txt"');
|
||
expect(report).toContain('"kundeAlpha" → "KUNDE_100002" (1×)');
|
||
expect(report).toContain('"Handbuch.docx": Office- oder PDF-Datei');
|
||
expect(report).toContain("Keine Änderung.");
|
||
expect(report).not.toContain("Müller GmbH");
|
||
expect((await fs.stat(previewFile)).mode & 0o777).toBe(0o600);
|
||
expect(await fs.readFile(join(project, legacyName), "utf8")).toBe(legacyContent);
|
||
expect(await fs.readdir(root)).not.toContain("VelumSupport");
|
||
await expect(migrate({ project, manifestFile, targetSupport, previewFile })).rejects.toMatchObject({ code: "EEXIST" });
|
||
await expect(migrate({ project, manifestFile, targetSupport, previewFile, apply: true })).rejects.toThrow();
|
||
await expect(migrate({ project, manifestFile, targetSupport,
|
||
previewFile: join(project, "vorschau.md") })).rejects.toThrow();
|
||
|
||
const result = await migrate({ project, manifestFile, targetSupport, apply: true });
|
||
expect(result.applied).toBe(true);
|
||
const run = JSON.parse(await fs.readFile(join(result.runDir!, "run.json"), "utf8"));
|
||
const file = run.files[0];
|
||
const content = await fs.readFile(join(result.runDir!, "files", file.output), "utf8");
|
||
expect(restoreText(content, run.mapping, run.matchModes)).toBe("muellerGmbhService und Müller GmbH");
|
||
expect(restorePath(file.output, run.mapping, run.matchModes)).toBe("Müller GmbH.txt");
|
||
expect(await fs.readFile(join(project, legacyName), "utf8")).toBe(legacyContent);
|
||
});
|
||
|
||
it("ersetzt Platzhalter hinter URL-kodierten Pfadtrennern im Dateinamen", async () => {
|
||
const root = await fs.mkdtemp(join(tmpdir(), "velum-encoded-name-test-"));
|
||
roots.push(root);
|
||
const project = join(root, "Projekt");
|
||
const targetSupport = join(root, "VelumSupport");
|
||
const manifestFile = join(root, "OldSupport", "projects", "manifest.json");
|
||
const previewFile = join(root, "Vorschau.md");
|
||
await fs.mkdir(join(project, "KUNDE_A"), { recursive: true });
|
||
await fs.mkdir(join(root, "OldSupport", "projects"), { recursive: true });
|
||
const source = "KUNDE_A/%2fkunde_a%2fzc.asddls";
|
||
await fs.writeFile(join(project, source), "Technischer Inhalt");
|
||
await fs.writeFile(manifestFile, JSON.stringify({
|
||
version: 1, projectPath: project,
|
||
projectTerms: [{ id: "t1", term: "Alpha GmbH", category: "Kunde", enabled: true, aliases: [] }],
|
||
variantTable: [
|
||
{ termId: "t1", termVariant: "Alpha GmbH", placeholderVariant: "KUNDE_A", style: "typed", boundary: "strict" },
|
||
{ termId: "t1", termVariant: "alpha_gmbh", placeholderVariant: "kunde_a", style: "snake", boundary: "strict" },
|
||
],
|
||
}));
|
||
const preview = await migrate({ project, manifestFile, targetSupport, previewFile });
|
||
expect(preview.summary.replacements).toBe(2);
|
||
const report = await fs.readFile(previewFile, "utf8");
|
||
expect(report).toContain('"KUNDE_A/%2fkunde_a%2fzc.asddls"');
|
||
expect(report).toContain('"KUNDE_100001/%2fKUNDE_100002%2fzc.asddls"');
|
||
expect(report).not.toContain("Alpha GmbH");
|
||
|
||
const result = await migrate({ project, manifestFile, targetSupport, apply: true });
|
||
const run = JSON.parse(await fs.readFile(join(result.runDir!, "run.json"), "utf8"));
|
||
expect(restorePath(run.files[0].output, run.mapping, run.matchModes))
|
||
.toBe("Alpha GmbH/%2falpha_gmbh%2fzc.asddls");
|
||
expect(await fs.readFile(join(project, source), "utf8")).toBe("Technischer Inhalt");
|
||
});
|