import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("./calibre", () => ({ getCalibreStatus: vi.fn(), listCalibreBooks: vi.fn(), })); vi.mock("./calibre-reading", () => ({ getReadingProgress: vi.fn(), })); import { getCalibreStatus, listCalibreBooks } from "./calibre"; import { getReadingProgress } from "./calibre-reading"; import { formatLibraryContextForPrompt, getLibraryContextForTopic, shouldIncludeLibraryContextInChat, } from "./library-context"; describe("library-context", () => { beforeEach(() => { vi.clearAllMocks(); }); it("returns empty payload when Calibre unavailable", async () => { vi.mocked(getCalibreStatus).mockResolvedValue({ configured: false, online: false, bookCount: 0, lastCheckAt: new Date().toISOString(), }); const payload = await getLibraryContextForTopic("user-1", "Ottoman history"); expect(payload.available).toBe(false); expect(payload.relevantBooks).toEqual([]); }); it("limits and ranks relevant books for a topic", async () => { vi.mocked(getCalibreStatus).mockResolvedValue({ configured: true, online: true, bookCount: 2, lastCheckAt: new Date().toISOString(), }); vi.mocked(getReadingProgress).mockResolvedValue([]); vi.mocked(listCalibreBooks).mockResolvedValue([ { id: 1, uuid: "a", title: "The Ottoman Empire", authors: ["Author A"], tags: ["history", "ottoman"], comment: "A long ".repeat(50), series: null, seriesIndex: null, rating: null, formats: ["EPUB"], hasCover: true, }, { id: 2, uuid: "b", title: "Cooking Basics", authors: ["Chef"], tags: ["food"], comment: null, series: null, seriesIndex: null, rating: null, formats: ["EPUB"], hasCover: false, }, ]); const payload = await getLibraryContextForTopic("user-1", "Ottoman history", { limit: 3 }); expect(payload.available).toBe(true); expect(payload.relevantBooks.length).toBeGreaterThan(0); expect(payload.relevantBooks[0]?.title).toBe("The Ottoman Empire"); expect(payload.relevantBooks[0]?.description?.length).toBeLessThanOrEqual(200); const formatted = formatLibraryContextForPrompt(payload); expect(formatted).toContain("Ottoman Empire"); expect(formatted).not.toMatch(/\/home\//); expect(formatted).not.toContain("uuid"); }); it("detects chat messages about reading", () => { expect(shouldIncludeLibraryContextInChat("What book should I read about history?")).toBe(true); expect(shouldIncludeLibraryContextInChat("How is my day going?")).toBe(false); }); });