import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { beforeEach, describe, expect, it, vi } from "vitest"; import AddCompanyWizardPage from "@/app/(app)/companies/new/page"; import { renderWithQueryClient } from "./test-utils"; vi.mock("next/navigation", () => ({ useRouter: () => ({ push: vi.fn(), replace: vi.fn() }), useSearchParams: () => new URLSearchParams(), })); const DISCOVERED_PROFILE = { name: "Acme Widgets", official_website: "https://acmewidgets.com", description: "Acme Widgets designs and sells handcrafted mechanical widgets.", monitoring_focus: null, industry: null, country: null, region: null, headquarters: "Austin, Texas", aliases: ["Acme Industries"], competitors: [], public_identifiers: {}, potential_sources: [ { source_type: "website", name: "Acme Widgets - Website", base_url: "https://acmewidgets.com" }, ], sources_consulted: ["https://acmewidgets.com"], }; const EXISTING_COMPANIES = [ { id: "existing-1", name: "Acme Widgets", slug: "acme-widgets", official_website: null, description: null, monitoring_focus: null, industry: null, country: null, region: null, headquarters: null, public_identifiers: {}, status: "active", created_at: "2026-01-01T00:00:00Z", updated_at: "2026-01-01T00:00:00Z", aliases: [], competitors: [], monitor_configuration: null, report_count: 0, unresolved_alert_count: 0, }, ]; function mockFetchImplementation(existingCompanies: unknown[] = []) { return vi.fn().mockImplementation((url: string, init?: RequestInit) => { const path = url.replace("http://localhost:8000", ""); if (path === "/api/v1/companies/discover" && init?.method === "POST") { return Promise.resolve({ ok: true, status: 200, json: async () => DISCOVERED_PROFILE }); } if (path === "/api/v1/companies" && (!init?.method || init.method === "GET")) { return Promise.resolve({ ok: true, status: 200, json: async () => existingCompanies }); } return Promise.resolve({ ok: false, status: 404, json: async () => ({ detail: "not found" }) }); }); } beforeEach(() => { vi.stubGlobal("fetch", mockFetchImplementation()); }); describe("AddCompanyWizardPage", () => { it("only requires a company name on the Discover step", async () => { const user = userEvent.setup(); renderWithQueryClient(); await user.click(screen.getByRole("button", { name: /discover company/i })); expect(await screen.findByText(/company name is required/i)).toBeInTheDocument(); }); it("discovers a profile and pre-fills the Review step, editable", async () => { const user = userEvent.setup(); renderWithQueryClient(); await user.type(screen.getByLabelText("Company name"), "Acme Widgets"); await user.click(screen.getByRole("button", { name: /discover company/i })); await waitFor(() => { expect(screen.getByText(/here's what we found for/i)).toBeInTheDocument(); }); const website = screen.getByLabelText("Official website") as HTMLInputElement; expect(website.value).toBe("https://acmewidgets.com"); const headquarters = screen.getByLabelText("Headquarters") as HTMLInputElement; expect(headquarters.value).toBe("Austin, Texas"); const description = screen.getByLabelText("Description") as HTMLTextAreaElement; expect(description.value).toBe( "Acme Widgets designs and sells handcrafted mechanical widgets.", ); const aliases = screen.getByLabelText(/known aliases/i) as HTMLInputElement; expect(aliases.value).toBe("Acme Industries"); expect(screen.getByText(/we'll start monitoring 1 source/i)).toBeInTheDocument(); // Still editable - the whole point of the review step. await user.clear(headquarters); await user.type(headquarters, "Denver, Colorado"); expect(headquarters.value).toBe("Denver, Colorado"); }); it("warns about a likely duplicate before discovering, and proceeds after Continue anyway", async () => { vi.stubGlobal("fetch", mockFetchImplementation(EXISTING_COMPANIES)); const user = userEvent.setup(); renderWithQueryClient(); await user.type(screen.getByLabelText("Company name"), "Acme Widgets"); await user.click(screen.getByRole("button", { name: /discover company/i })); expect(await screen.findByText(/you might already be monitoring/i)).toBeInTheDocument(); // Discovery must not have fired yet - still on the Discover step. expect(screen.queryByText(/here's what we found for/i)).not.toBeInTheDocument(); await user.click(screen.getByRole("button", { name: /continue anyway/i })); await user.click(screen.getByRole("button", { name: /discover company/i })); await waitFor(() => { expect(screen.getByText(/here's what we found for/i)).toBeInTheDocument(); }); expect(screen.queryByText(/you might already be monitoring/i)).not.toBeInTheDocument(); }); });