694 lines · 22.2 KB · TypeScript
RawDownload
import "../../index.css"; import {  type AuthAccessStreamEvent,  type AuthAccessSnapshot,  AuthSessionId,  DEFAULT_SERVER_SETTINGS,  EnvironmentId,  type DesktopBridge,  type DesktopUpdateState,  type LocalApi,  type ServerConfig,} from "@t3tools/contracts";import { DateTime } from "effect";import { page } from "vitest/browser";import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";import { render } from "vitest-browser-react"; import { __resetLocalApiForTests } from "../../localApi";import { AppAtomRegistryProvider } from "../../rpc/atomRegistry";import { resetServerStateForTests, setServerConfigSnapshot } from "../../rpc/serverState";import { ConnectionsSettings } from "./ConnectionsSettings";import { GeneralSettingsPanel } from "./SettingsPanels"; const authAccessHarness = vi.hoisted(() => {  type Snapshot = AuthAccessSnapshot;  let snapshot: Snapshot = {    pairingLinks: [],    clientSessions: [],  };  let revision = 1;  const listeners = new Set<(event: AuthAccessStreamEvent) => void>();   const emitEvent = (event: AuthAccessStreamEvent) => {    for (const listener of listeners) {      listener(event);    }  };   return {    reset() {      snapshot = {        pairingLinks: [],        clientSessions: [],      };      revision = 1;      listeners.clear();    },    setSnapshot(next: Snapshot) {      snapshot = next;    },    emitSnapshot() {      emitEvent({        version: 1 as const,        revision,        type: "snapshot" as const,        payload: snapshot,      });      revision += 1;    },    emitEvent,    emitPairingLinkUpserted(pairingLink: Snapshot["pairingLinks"][number]) {      emitEvent({        version: 1,        revision,        type: "pairingLinkUpserted",        payload: pairingLink,      });      revision += 1;    },    emitPairingLinkRemoved(id: string) {      emitEvent({        version: 1,        revision,        type: "pairingLinkRemoved",        payload: { id },      });      revision += 1;    },    emitClientUpserted(clientSession: Snapshot["clientSessions"][number]) {      emitEvent({        version: 1,        revision,        type: "clientUpserted",        payload: clientSession,      });      revision += 1;    },    emitClientRemoved(sessionId: string) {      emitEvent({        version: 1,        revision,        type: "clientRemoved",        payload: {          sessionId: AuthSessionId.makeUnsafe(sessionId),        },      });      revision += 1;    },    subscribe(listener: (event: AuthAccessStreamEvent) => void) {      listeners.add(listener);      listener({        version: 1,        revision: 1,        type: "snapshot",        payload: snapshot,      });      return () => {        listeners.delete(listener);      };    },  };}); vi.mock("../../environments/runtime", () => {  const primaryConnection = {    kind: "primary" as const,    knownEnvironment: {      id: "environment-local",      label: "Local environment",      source: "manual" as const,      environmentId: EnvironmentId.makeUnsafe("environment-local"),      target: {        httpBaseUrl: "http://localhost:3000",        wsBaseUrl: "ws://localhost:3000",      },    },    environmentId: EnvironmentId.makeUnsafe("environment-local"),    client: {      server: {        subscribeAuthAccess: (listener: Parameters<typeof authAccessHarness.subscribe>[0]) =>          authAccessHarness.subscribe(listener),      },    },    ensureBootstrapped: async () => undefined,    reconnect: async () => undefined,    dispose: async () => undefined,  };   return {    getEnvironmentHttpBaseUrl: () => "http://localhost:3000",    getSavedEnvironmentRecord: () => null,    getSavedEnvironmentRuntimeState: () => null,    hasSavedEnvironmentRegistryHydrated: () => true,    listSavedEnvironmentRecords: () => [],    resetSavedEnvironmentRegistryStoreForTests: () => undefined,    resetSavedEnvironmentRuntimeStoreForTests: () => undefined,    resolveEnvironmentHttpUrl: (_environmentId: unknown, path: string) =>      new URL(path, "http://localhost:3000").toString(),    waitForSavedEnvironmentRegistryHydration: async () => undefined,    addSavedEnvironment: vi.fn(),    disconnectSavedEnvironment: vi.fn(),    ensureEnvironmentConnectionBootstrapped: async () => undefined,    getPrimaryEnvironmentConnection: () => primaryConnection,    readEnvironmentConnection: () => primaryConnection,    reconnectSavedEnvironment: vi.fn(),    removeSavedEnvironment: vi.fn(),    requireEnvironmentConnection: () => primaryConnection,    resetEnvironmentServiceForTests: () => undefined,    startEnvironmentConnectionService: () => undefined,    subscribeEnvironmentConnections: () => () => {},    useSavedEnvironmentRegistryStore: (      selector: (state: { byId: Record<string, never> }) => unknown,    ) => selector({ byId: {} }),    useSavedEnvironmentRuntimeStore: (      selector: (state: { byId: Record<string, never> }) => unknown,    ) => selector({ byId: {} }),  };}); function createBaseServerConfig(): ServerConfig {  return {    environment: {      environmentId: EnvironmentId.makeUnsafe("environment-local"),      label: "Local environment",      platform: { os: "darwin" as const, arch: "arm64" as const },      serverVersion: "0.0.0-test",      capabilities: { repositoryIdentity: true },    },    auth: {      policy: "loopback-browser",      bootstrapMethods: ["one-time-token"],      sessionMethods: ["browser-session-cookie", "bearer-session-token"],      sessionCookieName: "t3_session",    },    cwd: "/repo/project",    keybindingsConfigPath: "/repo/project/.t3code-keybindings.json",    keybindings: [],    issues: [],    providers: [],    availableEditors: ["cursor"],    observability: {      logsDirectoryPath: "/repo/project/.t3/logs",      localTracingEnabled: true,      otlpTracesUrl: "http://localhost:4318/v1/traces",      otlpTracesEnabled: true,      otlpMetricsEnabled: false,    },    settings: DEFAULT_SERVER_SETTINGS,  };} function makeUtc(value: string) {  return DateTime.makeUnsafe(Date.parse(value));} function makePairingLink(input: {  readonly id: string;  readonly credential: string;  readonly role: "owner" | "client";  readonly subject: string;  readonly label?: string;  readonly createdAt: string;  readonly expiresAt: string;}): AuthAccessSnapshot["pairingLinks"][number] {  return {    ...input,    createdAt: makeUtc(input.createdAt),    expiresAt: makeUtc(input.expiresAt),  };} function makeClientSession(input: {  readonly sessionId: string;  readonly subject: string;  readonly role: "owner" | "client";  readonly method: "browser-session-cookie";  readonly client?: {    readonly label?: string;    readonly ipAddress?: string;    readonly userAgent?: string;    readonly deviceType?: "desktop" | "mobile" | "tablet" | "bot" | "unknown";    readonly os?: string;    readonly browser?: string;  };  readonly issuedAt: string;  readonly expiresAt: string;  readonly lastConnectedAt?: string | null;  readonly connected: boolean;  readonly current: boolean;}): AuthAccessSnapshot["clientSessions"][number] {  return {    ...input,    client: {      deviceType: "unknown",      ...input.client,    },    sessionId: AuthSessionId.makeUnsafe(input.sessionId),    issuedAt: makeUtc(input.issuedAt),    expiresAt: makeUtc(input.expiresAt),    lastConnectedAt:      input.lastConnectedAt === undefined || input.lastConnectedAt === null        ? null        : makeUtc(input.lastConnectedAt),  };} const createDesktopBridgeStub = (overrides?: {  readonly serverExposureState?: Awaited<ReturnType<DesktopBridge["getServerExposureState"]>>;  readonly setServerExposureMode?: DesktopBridge["setServerExposureMode"];}): DesktopBridge => {  const idleUpdateState: DesktopUpdateState = {    enabled: false,    status: "idle",    currentVersion: "0.0.0-test",    hostArch: "arm64",    appArch: "arm64",    runningUnderArm64Translation: false,    availableVersion: null,    downloadedVersion: null,    downloadPercent: null,    checkedAt: null,    message: null,    errorContext: null,    canRetry: false,  };   return {    getLocalEnvironmentBootstrap: () => ({      label: "Local environment",      httpBaseUrl: "http://127.0.0.1:3773",      wsBaseUrl: "ws://127.0.0.1:3773",      bootstrapToken: "desktop-bootstrap-token",    }),    getClientSettings: vi.fn().mockResolvedValue(null),    setClientSettings: vi.fn().mockResolvedValue(undefined),    getSavedEnvironmentRegistry: vi.fn().mockResolvedValue([]),    setSavedEnvironmentRegistry: vi.fn().mockResolvedValue(undefined),    getSavedEnvironmentSecret: vi.fn().mockResolvedValue(null),    setSavedEnvironmentSecret: vi.fn().mockResolvedValue(true),    removeSavedEnvironmentSecret: vi.fn().mockResolvedValue(undefined),    getServerExposureState: vi.fn().mockResolvedValue(      overrides?.serverExposureState ?? {        mode: "local-only",        endpointUrl: null,        advertisedHost: null,      },    ),    setServerExposureMode:      overrides?.setServerExposureMode ??      vi.fn().mockImplementation(async (mode) => ({        mode,        endpointUrl: mode === "network-accessible" ? "http://192.168.1.44:3773" : null,        advertisedHost: mode === "network-accessible" ? "192.168.1.44" : null,      })),    pickFolder: vi.fn().mockResolvedValue(null),    confirm: vi.fn().mockResolvedValue(false),    setTheme: vi.fn().mockResolvedValue(undefined),    showContextMenu: vi.fn().mockResolvedValue(null),    openExternal: vi.fn().mockResolvedValue(true),    onMenuAction: () => () => {},    getUpdateState: vi.fn().mockResolvedValue(idleUpdateState),    checkForUpdate: vi.fn().mockResolvedValue({ checked: false, state: idleUpdateState }),    downloadUpdate: vi      .fn()      .mockResolvedValue({ accepted: false, completed: false, state: idleUpdateState }),    installUpdate: vi      .fn()      .mockResolvedValue({ accepted: false, completed: false, state: idleUpdateState }),    onUpdateState: () => () => {},  };}; describe("GeneralSettingsPanel observability", () => {  let mounted:    | (Awaited<ReturnType<typeof render>> & {        cleanup?: () => Promise<void>;        unmount?: () => Promise<void>;      })    | null = null;   beforeEach(async () => {    resetServerStateForTests();    await __resetLocalApiForTests();    localStorage.clear();    authAccessHarness.reset();  });   afterEach(async () => {    if (mounted) {      const teardown = mounted.cleanup ?? mounted.unmount;      await teardown?.call(mounted).catch(() => {});    }    mounted = null;    vi.unstubAllGlobals();    Reflect.deleteProperty(window, "desktopBridge");    Reflect.deleteProperty(window, "nativeApi");    document.body.innerHTML = "";    resetServerStateForTests();    await __resetLocalApiForTests();    authAccessHarness.reset();  });   it("hides owner pairing tools in browser-served loopback builds without remote exposure", async () => {    Reflect.deleteProperty(window, "desktopBridge");    authAccessHarness.setSnapshot({      pairingLinks: [],      clientSessions: [        makeClientSession({          sessionId: "session-owner",          subject: "browser-owner",          role: "owner",          method: "browser-session-cookie",          client: {            label: "Chrome on Mac",            deviceType: "desktop",            os: "macOS",            browser: "Chrome",            ipAddress: "127.0.0.1",          },          issuedAt: "2036-04-07T00:00:00.000Z",          expiresAt: "2036-05-07T00:00:00.000Z",          connected: true,          current: true,        }),      ],    });    const fetchMock = vi.fn<typeof fetch>().mockImplementation(async (input) => {      const url = String(input);      if (url.endsWith("/api/auth/session")) {        return new Response(          JSON.stringify({            authenticated: true,            auth: createBaseServerConfig().auth,            role: "owner",            sessionMethod: "browser-session-cookie",            expiresAt: "2036-05-07T00:00:00.000Z",          }),          {            status: 200,            headers: { "content-type": "application/json" },          },        );      }       throw new Error(`Unhandled fetch GET ${url}`);    });    vi.stubGlobal("fetch", fetchMock);     mounted = await render(      <AppAtomRegistryProvider>        <ConnectionsSettings />      </AppAtomRegistryProvider>,    );     await expect.element(page.getByText("Manage local backend")).toBeInTheDocument();    await expect.element(page.getByLabelText("Enable network access")).toBeDisabled();    await expect      .element(        page.getByText(          "This backend is only reachable on this machine. Restart it with a non-loopback host to enable remote pairing.",        ),      )      .toBeInTheDocument();    await expect.element(page.getByText("Authorized clients")).not.toBeInTheDocument();    await expect.element(page.getByText("Chrome on Mac")).not.toBeInTheDocument();    await expect      .element(page.getByRole("heading", { name: "Remote environments", exact: true }))      .toBeInTheDocument();  });   it("shows diagnostics inside About with a single logs-folder action", async () => {    setServerConfigSnapshot(createBaseServerConfig());     mounted = await render(      <AppAtomRegistryProvider>        <GeneralSettingsPanel />      </AppAtomRegistryProvider>,    );     await expect.element(page.getByText("About")).toBeInTheDocument();    await expect.element(page.getByText("Diagnostics")).toBeInTheDocument();    await expect.element(page.getByText("Open logs folder")).toBeInTheDocument();    await expect      .element(page.getByText("/repo/project/.t3/logs", { exact: true }))      .toBeInTheDocument();    await expect      .element(        page.getByText(          "Local trace file. OTLP exporting traces to http://localhost:4318/v1/traces.",        ),      )      .toBeInTheDocument();  });   it("creates and shows a pairing link when network access is enabled", async () => {    window.desktopBridge = createDesktopBridgeStub({      serverExposureState: {        mode: "network-accessible",        endpointUrl: "http://192.168.1.44:3773",        advertisedHost: "192.168.1.44",      },    });    let pairingLinks: Array<AuthAccessSnapshot["pairingLinks"][number]> = [];    let clientSessions: Array<AuthAccessSnapshot["clientSessions"][number]> = [      makeClientSession({        sessionId: "session-owner",        subject: "desktop-bootstrap",        role: "owner",        method: "browser-session-cookie",        client: {          label: "This Mac",          deviceType: "desktop",          os: "macOS",          browser: "Electron",          ipAddress: "127.0.0.1",        },        issuedAt: "2036-04-07T00:00:00.000Z",        expiresAt: "2036-05-07T00:00:00.000Z",        connected: true,        current: true,      }),    ];    authAccessHarness.setSnapshot({      pairingLinks,      clientSessions,    });    vi.stubGlobal(      "fetch",      vi.fn<typeof fetch>().mockImplementation(async (input, init) => {        const url = String(input);        const method = init?.method ?? "GET";        if (url.endsWith("/api/auth/pairing-token") && method === "POST") {          pairingLinks = [            makePairingLink({              id: "pairing-link-1",              credential: "pairing-token",              role: "client",              subject: "one-time-token",              label: "Julius iPhone",              createdAt: "2036-04-07T00:00:00.000Z",              expiresAt: "2036-04-10T00:05:00.000Z",            }),          ];          clientSessions = [            ...clientSessions,            makeClientSession({              sessionId: "session-client",              subject: "one-time-token",              role: "client",

Lines 1–500 of 694.