import { beforeEach, describe, expect, it, vi } 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(); vi.mock("../../api", async (importOriginal) => { const { createDashboardApiMock } = await import("../../test/mockApi"); return createDashboardApiMock(() => importOriginal(), { fetchSettings: (...args: unknown[]) => mockFetchSettings(...args), fetchSettingsByScope: (...args: unknown[]) => mockFetchSettingsByScope(...args), }); }); vi.mock("../../hooks/useMemoryBackendStatus", () => ({ useMemoryBackendStatus: () => ({ status: null, capabilities: null, loading: false, error: null, refresh: vi.fn() }), })); vi.mock("../../hooks/useViewportMode", () => ({ useViewportMode: () => "desktop" })); vi.mock("../../hooks/useMobileKeyboard", () => ({ useMobileKeyboard: () => ({ keyboardOverlap: 0, viewportHeight: null, viewportOffsetTop: 0, keyboardOpen: false }), })); vi.mock("../../hooks/useMobileScrollLock", () => ({ useMobileScrollLock: vi.fn() })); vi.mock("../../hooks/useConfirm", () => ({ useConfirm: () => ({ confirm: vi.fn() }) })); vi.mock("../../hooks/useWorkspaceFileBrowser", () => ({ useWorkspaceFileBrowser: () => ({ entries: [], currentPath: ".", setPath: vi.fn(), loading: false, error: null, refresh: vi.fn() }), })); vi.mock("../../hooks/useWorktrunkInstallStatus", () => ({ useWorktrunkInstallStatus: () => ({ status: "idle", requestInstall: vi.fn() }), })); function buildSettings(testMode: boolean) { return { autoMerge: true, testMode, maxConcurrent: 2, maxTriageConcurrent: 2, maxWorktrees: 4, pollIntervalMs: 15000, heartbeatMultiplier: 1, groupOverlappingFiles: true, overlapIgnorePaths: [], mergeStrategy: "direct", mergeIntegrationWorktree: "reuse-task-worktree", recycleWorktrees: false, executorAllowSiblingBranchRename: false, worktreeNaming: "random", worktreesDir: "", worktrunk: { enabled: false, binaryPath: "", onFailure: "fail" }, includeTaskIdInCommit: true, ntfyEnabled: false, failureNotificationMode: "sticky-only", failureNotificationDelayMs: 30000, webhookEnabled: false, experimentalFeatures: {}, }; } describe("SettingsModal testMode toggle", () => { beforeEach(() => { vi.clearAllMocks(); const merged = buildSettings(true); mockFetchSettings.mockResolvedValue(merged); mockFetchSettingsByScope.mockResolvedValue({ global: {}, project: { testMode: true } }); }); it("renders merge test mode toggle with initial checked state", async () => { render( {}} addToast={() => {}} initialSection="merge" />); const toggle = await screen.findByLabelText("Enable test mode"); expect(toggle).toBeChecked(); }); it("flips checkbox state when clicked", async () => { render( {}} addToast={() => {}} initialSection="merge" />); const toggle = await screen.findByLabelText("Enable test mode"); expect(toggle).toBeChecked(); await userEvent.click(toggle); await waitFor(() => { expect(toggle).not.toBeChecked(); }); }); });