diff --git a/apps/native/src/components/widget/steps/setup-step.test.tsx b/apps/native/src/components/widget/steps/setup-step.test.tsx new file mode 100644 index 00000000..6ab126ed --- /dev/null +++ b/apps/native/src/components/widget/steps/setup-step.test.tsx @@ -0,0 +1,72 @@ +import "@testing-library/jest-dom"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { useWidgetStore } from "@/stores/widget-store"; +import { SetupStep } from "./setup-step"; + +const mockSaveHost = vi.hoisted(() => vi.fn<(host: string) => Promise>()); + +vi.mock("@/lib/env", () => ({ + settings: { + NIX_INSTALLED_OVERRIDE: false, + }, +})); + +vi.mock("@/hooks/use-darwin-config", () => ({ + useDarwinConfig: () => ({ + saveHost: mockSaveHost, + }), +})); + +vi.mock("@/components/widget/controls/directory-picker", () => ({ + DirectoryPicker: ({ label }: { label: string }) => ( +
{label}
+ ), +})); + +vi.mock("@/components/widget/controls/bootstrap-config", () => ({ + BootstrapConfig: ({ label }: { label: string }) => ( +
{label}
+ ), +})); + +function resetStore() { + const store = useWidgetStore.getState(); + store.setConfigDir(""); + store.setHosts([]); + store.setHost(""); + store.setError(null); + store.setBootstrapping(false); +} + +describe("", () => { + beforeEach(() => { + mockSaveHost.mockReset(); + resetStore(); + }); + + it("persists the displayed host when Next is clicked without changing the dropdown", async () => { + const store = useWidgetStore.getState(); + store.setConfigDir("/Users/me/.darwin"); + store.setHosts(["mbp"]); + store.setHost("mbp"); + + render(); + + fireEvent.click(await screen.findByRole("button", { name: "Next" })); + + expect(mockSaveHost).toHaveBeenCalledWith("mbp"); + expect(mockSaveHost).not.toHaveBeenCalledWith(""); + }); + + it("does not allow Next to persist an empty host", async () => { + const store = useWidgetStore.getState(); + store.setConfigDir("/Users/me/.darwin"); + store.setHosts(["mbp"]); + + render(); + + expect(await screen.findByRole("button", { name: "Next" })).toBeDisabled(); + }); +}); diff --git a/apps/native/src/components/widget/steps/setup-step.tsx b/apps/native/src/components/widget/steps/setup-step.tsx index a3ddf4f9..21ac369e 100644 --- a/apps/native/src/components/widget/steps/setup-step.tsx +++ b/apps/native/src/components/widget/steps/setup-step.tsx @@ -21,6 +21,7 @@ export function SetupStep() { const host = useWidgetStore((state) => state.host); const [configDirConfirmed, setConfigDirConfirmed] = useState(false); const [selectedHost, setSelectedHost] = useState(""); + const effectiveHost = selectedHost || host; const { saveHost } = useDarwinConfig(); @@ -82,7 +83,7 @@ export function SetupStep() { ) : ( )} -