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();
});
});