learning_ai_notes/web/src/lib/prompt-client.test.ts

123 lines
4.2 KiB
TypeScript

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);
});
});