154 lines · 4.6 KB · TypeScript
RawDownload
import {  DEFAULT_PREVIEW_APPEARANCE,  DEFAULT_PREVIEW_ZOOM_FACTOR,  EnvironmentId,  ThreadId,} from "@t3tools/contracts";import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test"; const { closeTab, createTab, stopBrowserRecording } = vi.hoisted(() => ({  closeTab: vi.fn<(tabId: string) => Promise<void>>(async () => undefined),  createTab: vi.fn<() => Promise<void>>(),  stopBrowserRecording: vi.fn(async () => null),})); vi.mock("~/components/preview/previewBridge", () => ({  previewBridge: { closeTab, createTab },})); vi.mock("./browserRecording", () => ({  stopBrowserRecording,})); import { acquireDesktopTab } from "./desktopTabLifetime"; /** Client settings are unset in tests, so creation carries the schema defaults. */const DEFAULT_TAB_STATE = {  zoomFactor: DEFAULT_PREVIEW_ZOOM_FACTOR,  colorScheme: DEFAULT_PREVIEW_APPEARANCE,};import { previewRuntimeTabId } from "./previewRuntimeTabId"; describe("desktopTabLifetime", () => {  beforeEach(() => {    closeTab.mockClear();    createTab.mockClear();    stopBrowserRecording.mockClear();    vi.stubGlobal("window", globalThis);  });   afterEach(() => {    vi.useRealTimers();    vi.unstubAllGlobals();  });   it("shares tab creation readiness across concurrent leases", async () => {    let resolveCreation: (() => void) | undefined;    createTab.mockReturnValueOnce(      new Promise<void>((resolve) => {        resolveCreation = resolve;      }),    );     const first = acquireDesktopTab("tab_readiness");    const second = acquireDesktopTab("tab_readiness");     // Both leases share one creation, and it is still in flight: creation now    // waits for client settings to hydrate so the guest is born at the user's    // zoom and appearance rather than painting at the defaults first.    expect(first.ready).toBe(second.ready);     let ready = false;    void first.ready.then(() => {      ready = true;    });    await vi.waitFor(() => expect(createTab).toHaveBeenCalledOnce());    expect(ready).toBe(false);     resolveCreation?.();    await first.ready;    expect(ready).toBe(true);  });   it("keeps identical server tab ids from two environments in separate desktop slots", async () => {    vi.useFakeTimers();    createTab.mockResolvedValue(undefined);    const tabA = previewRuntimeTabId(      {        environmentId: EnvironmentId.make("environment-a"),        threadId: ThreadId.make("thread-a"),      },      "epoch-a",      "tab_1",    );    const tabB = previewRuntimeTabId(      {        environmentId: EnvironmentId.make("environment-b"),        threadId: ThreadId.make("thread-b"),      },      "epoch-b",      "tab_1",    );     const first = acquireDesktopTab(tabA);    const second = acquireDesktopTab(tabB);    await Promise.all([first.ready, second.ready]);     expect(createTab).toHaveBeenCalledWith(tabA, DEFAULT_TAB_STATE);    expect(createTab).toHaveBeenCalledWith(tabB, DEFAULT_TAB_STATE);    expect(createTab).toHaveBeenCalledTimes(2);     first.release();    second.release();    await vi.advanceTimersByTimeAsync(0);  });   it("stops recording before closing the final desktop tab lease", async () => {    vi.useFakeTimers();    let resolveStop: (() => void) | undefined;    stopBrowserRecording.mockReturnValueOnce(      new Promise<null>((resolve) => {        resolveStop = () => resolve(null);      }),    );    createTab.mockResolvedValueOnce(undefined);     const lease = acquireDesktopTab("tab_recording_cleanup");    await lease.ready;    lease.release();    await vi.advanceTimersByTimeAsync(0);     expect(stopBrowserRecording).toHaveBeenCalledWith("tab_recording_cleanup");    expect(closeTab).not.toHaveBeenCalled();     resolveStop?.();    await Promise.resolve();    await Promise.resolve();    expect(closeTab).toHaveBeenCalledWith("tab_recording_cleanup");  });   it("waits for an in-flight close before recreating a reacquired tab", async () => {    vi.useFakeTimers();    let resolveClose: (() => void) | undefined;    createTab.mockResolvedValue(undefined);    closeTab.mockReturnValueOnce(      new Promise<void>((resolve) => {        resolveClose = resolve;      }),    );     const initial = acquireDesktopTab("tab_close_reacquire");    await initial.ready;    initial.release();    await vi.advanceTimersByTimeAsync(0);     expect(closeTab).toHaveBeenCalledWith("tab_close_reacquire");     const reacquired = acquireDesktopTab("tab_close_reacquire");    expect(createTab).toHaveBeenCalledTimes(1);     resolveClose?.();    await reacquired.ready;    expect(createTab).toHaveBeenCalledTimes(2);  });});