diff --git a/apps/web/src/components/app/automations-launch-dialog.test.tsx b/apps/web/src/components/app/automations-launch-dialog.test.tsx new file mode 100644 index 00000000..b45d9384 --- /dev/null +++ b/apps/web/src/components/app/automations-launch-dialog.test.tsx @@ -0,0 +1,401 @@ +// @vitest-environment jsdom +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { + act, + cleanup, + fireEvent, + render, + screen, + waitFor, +} from "@testing-library/react"; +import { MemoryRouter, useLocation } from "react-router-dom"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import type { Agent } from "@/components/app/types"; +import type { Template } from "@/hooks/use-templates"; + +import { LaunchTemplateDialog } from "./automations-launch-dialog"; + +// The dialog renders its real children and the real useTemplateActions +// mutation; only the HTTP seam and toast sink are mocked. That pins the whole +// launch contract end to end: form state -> mutation input -> wire payload +// (JSON vs multipart), which is exactly what a stubbed launchTemplate mock +// could silently get wrong. +vi.mock("@/lib/api", () => ({ api: vi.fn() })); +vi.mock("sonner", () => ({ toast: { error: vi.fn() } })); + +const { api } = await import("@/lib/api"); +const { toast } = await import("sonner"); +const apiMock = vi.mocked(api); +const toastErrorMock = vi.mocked(toast.error); + +function makeTemplate(overrides: Partial