import { closeSync, existsSync, mkdtempSync, openSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { LibraryPathValidationError, resolveLibraryPath } from "./library-path.js"; const tempDirs: string[] = []; const realBooksPath = "/home/anthony/Documents/Projects/ReadaBook/Books"; afterEach(() => { for (const dir of tempDirs.splice(0)) { rmSync(dir, { recursive: true, force: true }); } }); describe("library path resolution", () => { it("resolves a readable directory", () => { const dir = mkdtempSync(join(tmpdir(), "readabook-library-")); tempDirs.push(dir); expect(resolveLibraryPath(dir)).toBe(resolve(dir)); }); it("maps a host path alias to the mounted container path", () => { const hostRoot = "/host/project/Books"; const mountedRoot = mkdtempSync(join(tmpdir(), "readabook-mounted-books-")); tempDirs.push(mountedRoot); expect(resolveLibraryPath(hostRoot, [{ from: hostRoot, to: mountedRoot }])).toBe(resolve(mountedRoot)); }); it("rejects regular files with a stable code", () => { const dir = mkdtempSync(join(tmpdir(), "readabook-library-")); tempDirs.push(dir); const file = join(dir, "book.epub"); closeSync(openSync(file, "w")); expect(() => resolveLibraryPath(file)).toThrowError(LibraryPathValidationError); try { resolveLibraryPath(file); } catch (error) { expect(error).toMatchObject({ code: "LIBRARY_PATH_NOT_DIRECTORY" }); } }); it.runIf(existsSync(realBooksPath))("accepts the real Books corpus path used by QA", () => { expect(resolveLibraryPath(realBooksPath)).toBe(resolve(realBooksPath)); }); });