import { describe, it, expect, vi, beforeEach } from "vitest"; const invoke = vi.fn(); const listen = vi.fn(); vi.mock("@tauri-apps/api/core", () => ({ invoke: (...args: unknown[]) => invoke(...args), })); vi.mock("@tauri-apps/api/event", () => ({ listen: (...args: unknown[]) => listen(...args), })); import { TauriWindowGateway } from "./window"; describe("TauriWindowGateway (#23)", () => { beforeEach(() => { invoke.mockReset().mockResolvedValue({}); listen.mockReset(); }); it("open/close relay camelCase payloads to the backend commands", async () => { const gw = new TauriWindowGateway(); await gw.openViewWindow("tickets", "proj-1"); expect(invoke).toHaveBeenCalledWith("open_view_window", { panel: "tickets", projectId: "proj-1", }); await gw.closeViewWindow("git", "proj-2"); expect(invoke).toHaveBeenCalledWith("close_view_window", { panel: "git", projectId: "proj-2", }); }); it("onViewWindowClosed listens on the lifecycle channel and forwards only closes", async () => { // Capture the raw Tauri listener so we can drive lifecycle events at will. let raw: ((e: { payload: unknown }) => void) | undefined; const unlisten = vi.fn(); listen.mockImplementation((_name: string, cb: typeof raw) => { raw = cb; return Promise.resolve(unlisten); }); const gw = new TauriWindowGateway(); const handler = vi.fn(); const off = await gw.onViewWindowClosed(handler); expect(listen).toHaveBeenCalledWith( "view-window://lifecycle", expect.any(Function), ); // opened / focused are dropped… raw?.({ payload: { kind: "opened", panel: "git", projectId: "p", label: "view-git-p" }, }); raw?.({ payload: { kind: "focused", panel: "git", projectId: "p", label: "view-git-p" }, }); expect(handler).not.toHaveBeenCalled(); // …only closed reaches the port handler, narrowed to { panel, projectId }. raw?.({ payload: { kind: "closed", panel: "git", projectId: "p", label: "view-git-p" }, }); expect(handler).toHaveBeenCalledTimes(1); expect(handler).toHaveBeenCalledWith({ panel: "git", projectId: "p" }); off(); expect(unlisten).toHaveBeenCalled(); }); });