Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions apps/web/src/components/settings/IntegrationsSettings.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { DEFAULT_CLIENT_SETTINGS, DEFAULT_UNIFIED_SETTINGS } from "@t3tools/contracts";
import { act, StrictMode, type ReactNode } from "react";
import { create, type ReactTestRenderer } from "react-test-renderer";
import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test";

const { listBrowserImportSources } = vi.hoisted(() => ({
listBrowserImportSources: vi.fn().mockResolvedValue([]),
}));

vi.mock("../preview/previewBridge", () => ({
previewBridge: { listBrowserImportSources },
}));
vi.mock("../../env", () => ({ isElectron: true }));
vi.mock("../../state/environments", () => ({
useEnvironments: () => ({ environments: [], isReady: true }),
usePrimaryEnvironment: () => null,
}));
vi.mock("../../hooks/useSettings", () => ({
PRIMARY_SETTINGS_UNAVAILABLE_MESSAGE: "Connect to an environment",
useClientSettings: (selector: (settings: typeof DEFAULT_CLIENT_SETTINGS) => unknown) =>
selector(DEFAULT_CLIENT_SETTINGS),
useClientSettingsHydrated: () => true,
usePrimarySettingsAvailable: () => true,
usePrimarySettings: () => DEFAULT_UNIFIED_SETTINGS,
useUpdatePrimarySettings: () => vi.fn(),
}));
vi.mock("./settingsLayout", async (importOriginal) => ({
...(await importOriginal<typeof import("./settingsLayout")>()),
SettingsPageContainer: ({ children }: { children: ReactNode }) => children,
}));

import { IntegrationsSettingsPanel } from "./IntegrationsSettings";

let renderer: ReactTestRenderer | undefined;

beforeEach(() => {
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
listBrowserImportSources.mockClear();
});

afterEach(async () => {
await act(() => renderer?.unmount());
vi.unstubAllGlobals();
});

async function openSettings() {
await act(() => {
renderer = create(
<StrictMode>
<IntegrationsSettingsPanel />
</StrictMode>,
);
});
}

describe("Integrations browser discovery", () => {
it("does not scan browser files when entering or revisiting settings", async () => {
await openSettings();
expect(listBrowserImportSources).not.toHaveBeenCalled();

await act(() => renderer?.unmount());
await openSettings();
expect(listBrowserImportSources).not.toHaveBeenCalled();
});
});
7 changes: 1 addition & 6 deletions apps/web/src/components/settings/IntegrationsSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
} from "@t3tools/contracts";
import { PREVIEW_VIEWPORT_PRESETS } from "@t3tools/shared/previewViewport";
import { InfoIcon, MoreVertical, Plus as PlusIcon } from "lucide-react";
import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import { useCallback, useRef, useState, type ReactNode } from "react";

import { ScreenRotationIcon } from "~/browser/ScreenRotationIcon";
import { resolveEnvironmentOptionLabel } from "~/components/BranchToolbar.logic";
Expand Down Expand Up @@ -802,11 +802,6 @@ function BrowserProfilesSetting({ disabled }: { readonly disabled: boolean }) {
.catch(() => setSources((previous) => previous ?? []));
}, []);

// Loaded once so the first open is instant instead of flashing a spinner.
useEffect(() => {
loadSources();
}, [loadSources]);

// Runs one import for the wizard. A new profile is registered only once the
// import succeeds — the cookies land in its partition first — so a blocked
// attempt never leaves an empty profile behind.
Expand Down
Loading