feat: add project-aware agent workspace
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { act, createElement } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { SWRConfig } from "swr";
|
||||
import { expect, it, vi } from "vitest";
|
||||
import type { AgentApiClient, AgentTopic } from "@/features/agent";
|
||||
import { useAgentTopics } from "./use-agent-topics";
|
||||
import { WorkbenchSessionProvider } from "./workbench-session-provider";
|
||||
|
||||
it("reuses theme reads and keeps a late project result out of the personal theme list", async () => {
|
||||
const topic = (id: string): AgentTopic => ({ id, name: id, createdAt: "2026-10-22T01:00:00Z", updatedAt: "2026-10-22T01:00:00Z" });
|
||||
let finish!: (topics: AgentTopic[]) => void;
|
||||
const projectRead = vi.fn(() => new Promise<AgentTopic[]>((resolve) => { finish = resolve; }));
|
||||
const personalRead = vi.fn(async () => [topic("personal-theme")]);
|
||||
const clients = { project: { listTopics: projectRead }, personal: { listTopics: personalRead } } as unknown as Record<"project" | "personal", AgentApiClient>;
|
||||
const root = createRoot(document.createElement("div"));
|
||||
const cache = new Map();
|
||||
let topics!: ReturnType<typeof useAgentTopics>;
|
||||
function Probe({ scope }: { scope: "project" | "personal" }) { topics = useAgentTopics(clients[scope], scope); return null; }
|
||||
const render = (scope: "project" | "personal") => root.render(createElement(WorkbenchSessionProvider, null,
|
||||
createElement(SWRConfig, { value: { provider: () => cache, dedupingInterval: 0 } }, createElement(Probe, { scope }))));
|
||||
try {
|
||||
await act(async () => render("project"));
|
||||
let pending!: Promise<void>;
|
||||
await act(async () => { pending = topics.ensure(); });
|
||||
await act(async () => render("personal"));
|
||||
await act(async () => { finish([topic("project-theme")]); await pending; });
|
||||
expect(topics.topics.map((entry) => entry.id)).toEqual(["personal-theme"]);
|
||||
for (let i = 0; i < 10; i++) await act(async () => { await topics.ensure(); });
|
||||
expect(projectRead).toHaveBeenCalledTimes(1);
|
||||
expect(personalRead).toHaveBeenCalledTimes(1);
|
||||
} finally { await act(async () => root.unmount()); }
|
||||
});
|
||||
|
||||
it("keeps a newly created topic selectable when the open menu's older read finishes later", async () => {
|
||||
const topic = (id: string): AgentTopic => ({ id, name: id, createdAt: "2026-10-22T01:00:00Z", updatedAt: "2026-10-22T01:00:00Z" });
|
||||
let finish!: (topics: AgentTopic[]) => void;
|
||||
const client = {
|
||||
listTopics: vi.fn(() => new Promise<AgentTopic[]>((resolve) => { finish = resolve; })),
|
||||
createTopic: vi.fn(async () => topic("new-topic")),
|
||||
} as unknown as AgentApiClient;
|
||||
let topics!: ReturnType<typeof useAgentTopics>;
|
||||
function Probe() { topics = useAgentTopics(client, "project:slow-read"); return null; }
|
||||
const root = createRoot(document.createElement("div"));
|
||||
const cache = new Map();
|
||||
try {
|
||||
await act(async () => root.render(createElement(WorkbenchSessionProvider, null,
|
||||
createElement(SWRConfig, { value: { provider: () => cache, dedupingInterval: 0 } }, createElement(Probe)))));
|
||||
let reading!: Promise<void>;
|
||||
let creating!: Promise<AgentTopic>;
|
||||
await act(async () => { reading = topics.ensure(); });
|
||||
await act(async () => { creating = topics.create("new-topic"); });
|
||||
await act(async () => { finish([topic("existing-topic")]); await reading; await creating; });
|
||||
expect(topics.topics.map((entry) => entry.id)).toEqual(["existing-topic", "new-topic"]);
|
||||
await act(async () => { await topics.ensure(); });
|
||||
expect(topics.topics.map((entry) => entry.id)).toEqual(["existing-topic", "new-topic"]);
|
||||
expect(client.listTopics).toHaveBeenCalledTimes(1);
|
||||
} finally { await act(async () => root.unmount()); }
|
||||
});
|
||||
Reference in New Issue
Block a user