import { describe, expect, it, vi, beforeEach } from "vitest"; const fetchMock = vi.fn(); vi.mock("@bytelyst/api-client", () => ({ createApiClient: () => ({ fetch: fetchMock, }), })); import { listPromptTemplates, getPromptTemplate, createPromptTemplate, deletePromptTemplate, runPrompt, suggestTags, checkDuplicates, suggestLinks, getReadingTime, compareNotes, mergeNotes, getKnowledgeGaps, listPromptHistory, } from "@/lib/prompt-client"; describe("prompt-client", () => { beforeEach(() => { fetchMock.mockReset(); }); it("listPromptTemplates returns items array", async () => { fetchMock.mockResolvedValue({ items: [{ id: "t1", slug: "summarize" }] }); const result = await listPromptTemplates(); expect(result).toEqual([{ id: "t1", slug: "summarize" }]); expect(fetchMock).toHaveBeenCalledWith("/note-prompts"); }); it("getPromptTemplate fetches by id", async () => { fetchMock.mockResolvedValue({ id: "t1", slug: "summarize" }); const result = await getPromptTemplate("t1"); expect(result.id).toBe("t1"); }); it("createPromptTemplate posts body", async () => { fetchMock.mockResolvedValue({ id: "t-new", slug: "custom" }); const result = await createPromptTemplate({ slug: "custom", name: "Custom", description: "", category: "transform", inputType: "text", outputType: "new_note", } as never); expect(result.slug).toBe("custom"); expect(fetchMock).toHaveBeenCalledWith("/note-prompts", expect.objectContaining({ method: "POST" })); }); it("deletePromptTemplate sends DELETE", async () => { fetchMock.mockResolvedValue(undefined); await deletePromptTemplate("t1"); expect(fetchMock).toHaveBeenCalledWith("/note-prompts/t1", expect.objectContaining({ method: "DELETE" })); }); it("runPrompt posts run request", async () => { fetchMock.mockResolvedValue({ content: "Summary", templateSlug: "summarize" }); const result = await runPrompt({ templateId: "summarize", noteId: "n1", workspaceId: "ws1" }); expect(result.content).toBe("Summary"); }); it("suggestTags returns tag array", async () => { fetchMock.mockResolvedValue({ tags: ["tag1", "tag2"] }); const tags = await suggestTags("n1", "ws1"); expect(tags).toEqual(["tag1", "tag2"]); }); it("checkDuplicates returns duplicates array", async () => { fetchMock.mockResolvedValue({ duplicates: [{ id: "n2", title: "Dup", similarity: 0.9 }] }); const dups = await checkDuplicates("n1", "ws1"); expect(dups).toHaveLength(1); expect(dups[0].similarity).toBe(0.9); }); it("suggestLinks returns suggestions array", async () => { fetchMock.mockResolvedValue({ suggestions: [{ id: "n3", title: "Related", similarity: 0.7 }] }); const links = await suggestLinks("n1", "ws1"); expect(links).toHaveLength(1); }); it("getReadingTime returns word count and minutes", async () => { fetchMock.mockResolvedValue({ wordCount: 500, readingTimeMinutes: 3 }); const result = await getReadingTime("n1", "ws1"); expect(result.wordCount).toBe(500); expect(result.readingTimeMinutes).toBe(3); }); it("compareNotes sends noteIds", async () => { fetchMock.mockResolvedValue({ content: "Comparison", templateSlug: "compare" }); const result = await compareNotes(["n1", "n2"], "ws1"); expect(result.content).toBe("Comparison"); }); it("mergeNotes sends noteIds", async () => { fetchMock.mockResolvedValue({ content: "Merged", templateSlug: "merge" }); const result = await mergeNotes(["n1", "n2"], "ws1"); expect(result.content).toBe("Merged"); }); it("getKnowledgeGaps returns gaps and topicMap", async () => { fetchMock.mockResolvedValue({ gaps: [{ topic: "AI", description: "Missing", suggestedTitle: "AI Intro" }], topicMap: { AI: 1 } }); const result = await getKnowledgeGaps("ws1"); expect(result.gaps).toHaveLength(1); expect(result.topicMap.AI).toBe(1); }); it("listPromptHistory returns items", async () => { fetchMock.mockResolvedValue({ items: [{ id: "h1", noteId: "n1" }], total: 1 }); const result = await listPromptHistory("ws1", 10); expect(result.items).toHaveLength(1); expect(result.total).toBe(1); }); });