90
apps/web/src/lib/services/library-context.test.ts
Normal file
90
apps/web/src/lib/services/library-context.test.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user