130 lines · 4.3 KB · TypeScript
RawDownload
import { ProjectId, ThreadId, type DesktopAppActivationRequest } from "@t3tools/contracts";import { describe, expect, it, vi } from "vite-plus/test"; import { DesktopAppActivationBroker } from "./DesktopAppActivationBroker.ts"; const request: DesktopAppActivationRequest = {  version: 1,  requestId: "request-1",  type: "open-workspace",  workspaceRoot: "/workspace/project",  platform: "linux",}; describe("DesktopAppActivationBroker", () => {  it("focuses immediately and waits for renderer readiness", async () => {    const activate = vi.fn();    const send = vi.fn();    const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate });     const response = broker.request(request);    expect(activate).toHaveBeenCalledOnce();    expect(send).not.toHaveBeenCalled();     broker.registerRenderer(send);    expect(send).toHaveBeenCalledWith(request);    broker.complete({      version: 1,      requestId: request.requestId,      ok: true,      projectId: ProjectId.make("project-1"),      threadId: ThreadId.make("thread-1"),    });     await expect(response).resolves.toMatchObject({ ok: true, projectId: "project-1" });    broker.close();  });   it("fails an in-flight request when the renderer goes away", async () => {    const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate: vi.fn() });    broker.registerRenderer(vi.fn());     const response = broker.request(request);    broker.clearRenderer();     await expect(response).resolves.toMatchObject({      ok: false,      code: "renderer-unavailable",    });    broker.close();  });   it("queues requests after unsubscribe until a new renderer registers", async () => {    const previousSend = vi.fn();    const nextSend = vi.fn();    const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate: vi.fn() });    broker.registerRenderer(previousSend);    broker.clearRenderer();     const response = broker.request(request);    expect(previousSend).not.toHaveBeenCalled();    expect(nextSend).not.toHaveBeenCalled();     broker.registerRenderer(nextSend);    expect(nextSend).toHaveBeenCalledWith(request);    broker.complete({      version: 1,      requestId: request.requestId,      ok: true,      projectId: ProjectId.make("project-1"),      threadId: ThreadId.make("thread-1"),    });     await expect(response).resolves.toMatchObject({ ok: true });    broker.close();  });   it("removes a queued request when its CLI connection closes", async () => {    const send = vi.fn();    const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate: vi.fn() });     const response = broker.request(request);    broker.cancel(request.requestId);    broker.registerRenderer(send);     await expect(response).resolves.toMatchObject({ ok: false, code: "renderer-unavailable" });    expect(send).not.toHaveBeenCalled();    broker.close();  });   it("never sends a canceled request that was queued behind another request", async () => {    const send = vi.fn();    const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate: vi.fn() });    broker.registerRenderer(send);    const secondRequest = { ...request, requestId: "request-2" };     const firstResponse = broker.request(request);    const secondResponse = broker.request(secondRequest);    expect(send).toHaveBeenCalledTimes(1);    expect(send).toHaveBeenLastCalledWith(request);     broker.cancel(secondRequest.requestId);    broker.complete({      version: 1,      requestId: request.requestId,      ok: true,      projectId: ProjectId.make("project-1"),      threadId: ThreadId.make("thread-1"),    });     await expect(firstResponse).resolves.toMatchObject({ ok: true });    await expect(secondResponse).resolves.toMatchObject({ ok: false });    expect(send).toHaveBeenCalledTimes(1);    broker.close();  });   it("times out a request without polling", async () => {    vi.useFakeTimers();    try {      const broker = new DesktopAppActivationBroker({ requestTimeoutMs: 1_000, activate: vi.fn() });      const response = broker.request(request);       await vi.advanceTimersByTimeAsync(1_000);       await expect(response).resolves.toMatchObject({ ok: false, code: "request-timeout" });      broker.close();    } finally {      vi.useRealTimers();    }  });});