import { cleanup, render, screen, waitFor } from "@testing-library/react"; import { useEffect } from "react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { StateProvider, useAppStoreApi } from "@/components/state-provider"; import type { Executor, ExecutorProfile } from "@/lib/types/http"; import { LegacyExecutorSettingsRoute } from "./legacy-executor-settings-route"; const LEGACY_EXECUTOR_TESTID = "legacy-executor"; const { replace } = vi.hoisted(() => ({ replace: vi.fn() })); vi.mock("@/lib/routing/client-router", () => ({ useRouter: () => ({ replace }), })); vi.mock("@/app/settings/executor/[id]/page", () => ({ default: ({ executorId }: { executorId: string }) => (
{executorId}
), })); const TIMESTAMP = "2026-08-24T00:00:00Z"; const PROFILE_ID = "profile/primary"; const CANONICAL_PROFILE_PATH = "/settings/executors/profile%2Fprimary"; const PROFILE_UNAVAILABLE_TESTID = "executor-profile-unavailable"; afterEach(() => { cleanup(); replace.mockReset(); window.history.replaceState({}, "", "/settings"); }); function executor(type: Executor["type"]): Executor { const id = "executor/primary"; const profile: ExecutorProfile = { id: PROFILE_ID, executor_id: id, executor_type: type, name: "Primary profile", config: {}, prepare_script: "", cleanup_script: "", env_vars: [], created_at: TIMESTAMP, updated_at: TIMESTAMP, }; return { id, name: "Primary executor", type, status: "active", is_system: false, config: {}, profiles: [profile], created_at: TIMESTAMP, updated_at: TIMESTAMP, }; } function renderRoute( record: Executor | null, profileId?: string, executorId?: string, options: { executorsLoaded?: boolean } = {}, ) { render( , ); } function HydrateExecutors({ record }: { record: Executor }) { const store = useAppStoreApi(); useEffect(() => { store.getState().setExecutors([record]); store.getState().setSettingsData({ executorsLoaded: true }); }, [record, store]); return null; } it("waits for executor hydration before rendering an unavailable profile state", () => { renderRoute(null, PROFILE_ID, "executor/missing", { executorsLoaded: false }); expect(screen.queryByTestId(PROFILE_UNAVAILABLE_TESTID)).toBeNull(); expect(replace).not.toHaveBeenCalled(); }); describe("LegacyExecutorSettingsRoute", () => { it("redirects a member's bookmarked Kubernetes executor before mounting legacy controls", async () => { renderRoute(executor("k8s")); await waitFor(() => expect(replace).toHaveBeenCalledWith(CANONICAL_PROFILE_PATH)); expect(screen.queryByTestId(LEGACY_EXECUTOR_TESTID)).toBeNull(); }); it("keeps an orphaned Kubernetes executor on the connection recovery page", async () => { const orphan = { ...executor("k8s"), profiles: [] }; renderRoute(orphan); await waitFor(() => expect(replace).toHaveBeenCalledWith("/settings/executors/k8s/executor%2Fprimary"), ); expect(screen.queryByTestId(LEGACY_EXECUTOR_TESTID)).toBeNull(); }); it("redirects a bookmarked Kubernetes profile to the Kubernetes-aware editor", async () => { renderRoute(executor("k8s"), PROFILE_ID); await waitFor(() => expect(replace).toHaveBeenCalledWith(CANONICAL_PROFILE_PATH)); expect(screen.queryByTestId("legacy-profile")).toBeNull(); }); it("does not redirect a Kubernetes executor to a profile owned by another executor", () => { renderRoute(executor("k8s"), "profile/from-another-executor"); expect(screen.getByTestId(PROFILE_UNAVAILABLE_TESTID)).toBeTruthy(); expect(replace).not.toHaveBeenCalled(); }); it.each([ "local", "local_docker", "ssh", "sprites", "local_pc", "worktree", "remote_docker", ] as const)("redirects a %s profile bookmark to the canonical editor", async (type) => { renderRoute(executor(type), PROFILE_ID); await waitFor(() => expect(replace).toHaveBeenCalledWith(CANONICAL_PROFILE_PATH)); expect(screen.queryByTestId(LEGACY_EXECUTOR_TESTID)).toBeNull(); }); it("keeps an executor-only SSH route on the connection editor", () => { renderRoute(executor("ssh")); expect(screen.getByTestId(LEGACY_EXECUTOR_TESTID)).toBeTruthy(); expect(replace).not.toHaveBeenCalled(); }); it("renders an unavailable state for a missing profile without choosing another profile", () => { const record = executor("local_docker"); record.profiles = [ { ...record.profiles![0], id: "profile/other", }, ]; renderRoute(record, PROFILE_ID); expect(screen.getByTestId(PROFILE_UNAVAILABLE_TESTID)).toBeTruthy(); expect(replace).not.toHaveBeenCalled(); }); it("renders an unavailable state for a missing executor", () => { renderRoute(null, PROFILE_ID, "executor/missing"); expect(screen.getByTestId(PROFILE_UNAVAILABLE_TESTID)).toBeTruthy(); expect(replace).not.toHaveBeenCalled(); }); it("preserves query parameters and fragments while replacing a valid bookmark", async () => { window.history.replaceState( {}, "", "/settings/executor/executor%2Fprimary/profile/profile%2Fprimary?tab=advanced#docker", ); renderRoute(executor("ssh"), PROFILE_ID); await waitFor(() => expect(replace).toHaveBeenCalledWith( "/settings/executors/profile%2Fprimary?tab=advanced#docker", ), ); }); it("retries a valid bookmark when executor state hydrates after the route mounts", async () => { const record = executor("ssh"); render( , ); await waitFor(() => expect(replace).toHaveBeenCalledWith(CANONICAL_PROFILE_PATH)); }); });