import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { checkMediaLibraryFolder, mediaLibraryFileType, walkMediaLibrary, } from "./media-library.js"; const dirs: string[] = []; function tempDir() { const dir = mkdtempSync(path.join(tmpdir(), "rakazo-library-unit-")); dirs.push(dir); return dir; } afterEach(() => { for (const dir of dirs.splice(0)) rmSync(dir, { recursive: true, force: true }); }); async function walk(root: string) { const out: string[] = []; for await (const file of walkMediaLibrary(root)) out.push(file); return out; } describe("media library", () => { it("indexes photos and videos only", () => { expect(mediaLibraryFileType("IMG_0001.JPG")).toEqual({ kind: "photo", mimeType: "image/jpeg" }); expect(mediaLibraryFileType("clip.mp4")).toEqual({ kind: "video", mimeType: "video/mp4" }); expect(mediaLibraryFileType("song.mp3")).toBeNull(); expect(mediaLibraryFileType("notes.txt")).toBeNull(); }); it("walks below the folder without hidden entries or symlinks", async () => { const root = tempDir(); const outside = tempDir(); mkdirSync(path.join(root, "2024", "Summer"), { recursive: true }); mkdirSync(path.join(root, ".cache")); writeFileSync(path.join(root, "2024", "Summer", "b.jpg"), "x"); writeFileSync(path.join(root, "2024", "a.png"), "x"); writeFileSync(path.join(root, "2024", "readme.txt"), "x"); writeFileSync(path.join(root, ".cache", "c.jpg"), "x"); writeFileSync(path.join(root, ".hidden.jpg"), "x"); writeFileSync(path.join(outside, "d.jpg"), "x"); symlinkSync(path.join(outside, "d.jpg"), path.join(root, "link.jpg")); symlinkSync(outside, path.join(root, "linked-folder")); expect(await walk(root)).toEqual(["2024/Summer/b.jpg", "2024/a.png"]); }); it("accepts only an absolute path to an existing folder", async () => { const root = tempDir(); writeFileSync(path.join(root, "file.jpg"), "x"); expect(await checkMediaLibraryFolder(root)).toBeNull(); expect(await checkMediaLibraryFolder("photos")).toBe("Use an absolute folder path."); expect(await checkMediaLibraryFolder(path.join(root, "file.jpg"))).toBe( "This is not a folder.", ); expect(await checkMediaLibraryFolder(path.join(root, "missing"))).toBe("Folder not found."); }); });