Files
fusion/packages/dashboard/app/components/__tests__/SettingsModal.worktrunk.test.tsx
gsxdsm f9f767c46a FN-7007: speed up SettingsModal interaction tests
Optimize the split SettingsModal test suite to avoid default user-event overhead while preserving interaction coverage.

- Add a shared no-delay SettingsModal test user with pointer-event tree checks disabled.
- Route split SettingsModal tests through the shared fast user and use fireEvent for simple form mutations.
- Shorten modal readiness checks to wait on settings loading instead of querying Save repeatedly.

Files changed:
 .../__tests__/SettingsModal.general.test.tsx       | 124 +++++++--------
 .../__tests__/SettingsModal.models-auth.test.tsx   | 136 ++++++++--------
 .../SettingsModal.remote-notifications.test.tsx    |  61 ++++----
 .../SettingsModal.scheduling-merge.test.tsx        | 174 ++++++++++-----------
 .../__tests__/SettingsModal.test-harness.tsx       |  32 ++--
 .../__tests__/SettingsModal.testMode.test.tsx      |   5 +-
 .../__tests__/SettingsModal.worktrunk.test.tsx     |   5 +-
 .../__tests__/SettingsModalNodeRouting.test.tsx    |   7 +-
 8 files changed, 273 insertions(+), 271 deletions(-)

Fusion-Task-Id: FN-7007

Fusion-Task-Lineage: 42cf8ce2-3da7-4607-8790-5bf46c07b417
2026-06-25 19:35:05 -07:00

105 lines
4.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, waitFor, fireEvent } from "@testing-library/react";
import { SettingsModal } from "../SettingsModal";
const mockFetchSettings = vi.fn();
const mockFetchSettingsByScope = vi.fn();
const mockFetchAuthStatus = vi.fn();
const mockFetchModels = vi.fn();
const mockFetchCustomProviders = vi.fn();
const mockFetchMemoryFiles = vi.fn();
const mockFetchGlobalConcurrency = vi.fn();
const mockFetchDashboardHealth = vi.fn();
const mockUseWorktrunkInstallStatus = vi.fn();
vi.mock("../../api", async (importOriginal) => {
const { createDashboardApiMock } = await import("../../test/mockApi");
return createDashboardApiMock(() => importOriginal<typeof import("../../api")>(), {
fetchSettings: (...args: unknown[]) => mockFetchSettings(...args),
fetchSettingsByScope: (...args: unknown[]) => mockFetchSettingsByScope(...args),
fetchAuthStatus: (...args: unknown[]) => mockFetchAuthStatus(...args),
fetchModels: (...args: unknown[]) => mockFetchModels(...args),
fetchCustomProviders: (...args: unknown[]) => mockFetchCustomProviders(...args),
fetchMemoryFiles: (...args: unknown[]) => mockFetchMemoryFiles(...args),
fetchGlobalConcurrency: (...args: unknown[]) => mockFetchGlobalConcurrency(...args),
fetchDashboardHealth: (...args: unknown[]) => mockFetchDashboardHealth(...args),
});
});
vi.mock("../../hooks/useWorktrunkInstallStatus", () => ({
useWorktrunkInstallStatus: (...args: unknown[]) => mockUseWorktrunkInstallStatus(...args),
}));
vi.mock("../../hooks/useViewportMode", () => ({
MOBILE_MEDIA_QUERY: "(max-width: 768px), (max-height: 480px)",
useViewportMode: () => "desktop",
getViewportMode: () => "desktop",
isMobileViewport: () => false,
}));
vi.mock("../../hooks/useMobileKeyboard", () => ({
useMobileKeyboard: () => ({ keyboardOpen: false, keyboardOverlap: 0, viewportHeight: null, viewportOffsetTop: 0 }),
}));
vi.mock("../../hooks/useConfirm", () => ({ useConfirm: () => ({ confirm: vi.fn().mockResolvedValue(true) }) }));
const defaultSettings = {
maxConcurrent: 2,
maxWorktrees: 4,
pollIntervalMs: 15000,
autoMerge: true,
worktrunk: { enabled: false, binaryPath: "", onFailure: "fail" },
};
function renderModal(onOpenApprovals = vi.fn()) {
return render(<SettingsModal onClose={() => {}} addToast={() => {}} initialSection="worktrees" onOpenApprovals={onOpenApprovals} />);
}
describe("SettingsModal worktrunk install affordance", () => {
beforeEach(() => {
vi.clearAllMocks();
mockFetchSettings.mockResolvedValue(defaultSettings);
mockFetchSettingsByScope.mockResolvedValue({ global: defaultSettings, project: {} });
mockFetchAuthStatus.mockResolvedValue({ providers: [] });
mockFetchModels.mockResolvedValue({ models: [], favoriteProviders: [], favoriteModels: [] });
mockFetchCustomProviders.mockResolvedValue({ providers: [] });
mockFetchMemoryFiles.mockResolvedValue({ files: [] });
mockFetchGlobalConcurrency.mockResolvedValue({ maxConcurrentRuns: 4 });
mockFetchDashboardHealth.mockResolvedValue({});
});
it.each([
{ status: "missing", button: "Install worktrunk binary", action: "request" },
{ status: "pending-approval", button: "Open Approvals", action: "open" },
{ status: "denied", button: "Try again", action: "request" },
{ status: "installed", text: /installed at/i },
])("renders state %#", async (scenario) => {
const requestInstall = vi.fn();
const onOpenApprovals = vi.fn();
mockUseWorktrunkInstallStatus.mockReturnValue({
status: scenario.status,
requestInstall,
requesting: false,
version: "v1.2.3",
installPath: "~/.fusion/bin/worktrunk",
pendingApprovalId: "apr-1",
error: "Denied",
});
renderModal(onOpenApprovals);
await waitFor(() => expect(mockFetchSettings).toHaveBeenCalled());
if (scenario.text) {
expect(screen.getByText(scenario.text)).toBeInTheDocument();
return;
}
const button = screen.getByRole("button", { name: scenario.button });
fireEvent.click(button);
if (scenario.action === "request") {
expect(requestInstall).toHaveBeenCalledTimes(1);
} else {
expect(onOpenApprovals).toHaveBeenCalledWith("apr-1");
}
});
});