31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { describe, expect, it } from "vitest";
|
|
import { tryRemoveLocalPhotoFile } from "@/lib/admin/photo-files";
|
|
|
|
describe("admin-photos Content service contract", () => {
|
|
const wrapper = readFileSync("src/actions/admin-photos.ts", "utf8");
|
|
const runtime = readFileSync(
|
|
"src/features/housekeeping/domains/content/services/mutation-runtime-external.ts",
|
|
"utf8",
|
|
);
|
|
|
|
it("delegates while the runtime deletes CameraWeb and purges local files", () => {
|
|
expect(wrapper).toContain("contentMutationService.execute");
|
|
expect(wrapper).toContain('"photo.delete"');
|
|
expect(wrapper).toContain('revalidatePath("/photos")');
|
|
expect(runtime).toContain("@/lib/db");
|
|
expect(runtime).toContain("CameraWeb");
|
|
expect(runtime).toContain("tryRemoveLocalPhotoFile");
|
|
});
|
|
});
|
|
|
|
describe("tryRemoveLocalPhotoFile", () => {
|
|
it("rejects path traversal and remote CDN urls", async () => {
|
|
expect(await tryRemoveLocalPhotoFile("https://cdn.example/photo.png")).toBe(
|
|
false,
|
|
);
|
|
expect(await tryRemoveLocalPhotoFile("/../../etc/passwd")).toBe(false);
|
|
expect(await tryRemoveLocalPhotoFile("")).toBe(false);
|
|
});
|
|
});
|