Files
fusion/packages/dashboard/app/components/__tests__/SettingsModal.worktrunk.test.tsx
Fusion (runfusion.ai) 11a357d1d1 test(FN-4702): add dedicated settings worktrunk states test
Fusion-Task-Id: FN-4702
Fusion-Task-Lineage: 378b46bc-2e71-43bf-9ff7-85e7aed8bf85
2026-05-15 23:39:43 -07:00

101 lines
4.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
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", () => ({ useViewportMode: () => "desktop" }));
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 });
await userEvent.click(button);
if (scenario.action === "request") {
expect(requestInstall).toHaveBeenCalledTimes(1);
} else {
expect(onOpenApprovals).toHaveBeenCalledWith("apr-1");
}
});
});