import { describe, it, expect, vi, beforeEach } from "vitest"; const mockFetch = vi.fn(); vi.mock("@/lib/api-helpers", () => ({ createNotesApiClient: () => ({ fetch: mockFetch }), })); import { searchPalace, listWings, getWingSummary, deleteWing, listRooms, storeMemory, listMemories, deleteMemory, queryEntity, getEntityTimeline, getKGContradictions, getWakeUpContext, getPalaceStats, backfillEmbeddings, pruneMemories, getPalaceHealth, } from "./palace-client"; beforeEach(() => { mockFetch.mockReset(); }); describe("palace-client", () => { it("searchPalace calls /palace/search with query params", async () => { mockFetch.mockResolvedValue([{ id: "m1", content: "JWT" }]); const result = await searchPalace("JWT", "wing-1", 5); expect(mockFetch).toHaveBeenCalledWith("/palace/search?q=JWT&limit=5&wingId=wing-1"); expect(result).toHaveLength(1); }); it("listWings calls /palace/wings", async () => { mockFetch.mockResolvedValue([]); await listWings(); expect(mockFetch).toHaveBeenCalledWith("/palace/wings"); }); it("getWingSummary calls /palace/wings/:wingId", async () => { mockFetch.mockResolvedValue({ wing: { id: "w1" }, rooms: [], totalMemories: 0 }); await getWingSummary("w1"); expect(mockFetch).toHaveBeenCalledWith("/palace/wings/w1"); }); it("deleteWing calls DELETE /palace/wings/:wingId", async () => { mockFetch.mockResolvedValue(undefined); await deleteWing("w1"); expect(mockFetch).toHaveBeenCalledWith("/palace/wings/w1", { method: "DELETE" }); }); it("listRooms calls /palace/wings/:wingId/rooms", async () => { mockFetch.mockResolvedValue([]); await listRooms("w1"); expect(mockFetch).toHaveBeenCalledWith("/palace/wings/w1/rooms"); }); it("storeMemory calls POST /palace/memories", async () => { mockFetch.mockResolvedValue({ stored: true }); const result = await storeMemory({ wingId: "w1", roomId: "r1", hall: "decisions", content: "test", }); expect(result.stored).toBe(true); expect(mockFetch).toHaveBeenCalledWith("/palace/memories", expect.objectContaining({ method: "POST" })); }); it("listMemories builds query string correctly", async () => { mockFetch.mockResolvedValue([]); await listMemories({ wingId: "w1", hall: "decisions", limit: 5 }); expect(mockFetch).toHaveBeenCalledWith("/palace/memories?wingId=w1&hall=decisions&limit=5"); }); it("deleteMemory calls DELETE /palace/memories/:id", async () => { mockFetch.mockResolvedValue(undefined); await deleteMemory("m1"); expect(mockFetch).toHaveBeenCalledWith("/palace/memories/m1", { method: "DELETE" }); }); it("queryEntity calls /palace/kg/entity/:entity", async () => { mockFetch.mockResolvedValue([]); await queryEntity("React"); expect(mockFetch).toHaveBeenCalledWith("/palace/kg/entity/React"); }); it("getEntityTimeline calls /palace/kg/timeline/:entity", async () => { mockFetch.mockResolvedValue([]); await getEntityTimeline("React"); expect(mockFetch).toHaveBeenCalledWith("/palace/kg/timeline/React"); }); it("getKGContradictions with wingId", async () => { mockFetch.mockResolvedValue([]); await getKGContradictions("w1"); expect(mockFetch).toHaveBeenCalledWith("/palace/kg/contradictions?wingId=w1"); }); it("getWakeUpContext with task", async () => { mockFetch.mockResolvedValue({ text: "context", wingName: "Work" }); await getWakeUpContext("w1", "auth migration"); expect(mockFetch).toHaveBeenCalledWith("/palace/wake-up/w1?task=auth%20migration"); }); it("getPalaceStats calls /palace/stats", async () => { mockFetch.mockResolvedValue({ wings: 1, rooms: 2, memories: 5, kgTriples: 3, tunnels: 0, diaries: 0 }); const stats = await getPalaceStats(); expect(stats.memories).toBe(5); }); it("backfillEmbeddings calls POST /palace/backfill-embeddings", async () => { mockFetch.mockResolvedValue({ backfilled: 3 }); const result = await backfillEmbeddings(); expect(result.backfilled).toBe(3); }); it("pruneMemories calls POST /palace/prune", async () => { mockFetch.mockResolvedValue({ pruned: 2 }); const result = await pruneMemories({ olderThanDays: 180, minRelevance: 0.1 }); expect(result.pruned).toBe(2); }); it("getPalaceHealth calls /palace/health", async () => { mockFetch.mockResolvedValue({ cosmos: true, llm: true }); const health = await getPalaceHealth(); expect(health.cosmos).toBe(true); }); });