import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { MemoryRouter, Routes, Route } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import ModuleHub from "./ModuleHub"; import ModuleShell from "./ModuleShell"; import { LaunchProvider } from "./LaunchContext"; import { ThemeProvider } from "../context/ThemeContext"; import { ApiKeyProvider } from "../context/ApiKeyContext"; import { EDashboard, SCampaigns } from "./lazyPages"; import { apiClient } from "../lib/apiClient"; vi.mock("recharts", () => ({ ResponsiveContainer: ({ children }: any) =>
{children}
, AreaChart: () =>
AreaChart
, Area: () =>
, XAxis: () =>
, YAxis: () =>
, Tooltip: () =>
, LineChart: () =>
LineChart
, BarChart: () =>
BarChart
, Line: () =>
, Bar: () =>
, CartesianGrid: () =>
, Legend: () =>
, PieChart: () =>
PieChart
, Pie: () =>
, Cell: () =>
, })); vi.mock("../lib/apiClient", () => ({ apiClient: { get: vi.fn().mockResolvedValue({ data: [] }) }, })); vi.mock("../lib/supabaseClient", () => ({ supabase: null, isSupabaseConfigured: false, })); function makeWrapper(initialEntries: string[]) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, gcTime: 0 } }, }); return ( } /> }> } /> }> } /> ); } describe("BRIDGE platform routing", () => { beforeEach(() => { vi.clearAllMocks(); (apiClient.get as any).mockResolvedValue({ data: [] }); }); it("hub renders both module launcher cards with direct-launch buttons", () => { render(makeWrapper(["/"])); expect(screen.getAllByText(/BRIDGE/).length).toBeGreaterThan(0); expect(screen.getByRole("button", { name: /Launch Module E/i })).toBeTruthy(); expect(screen.getByRole("button", { name: /Launch Module S/i })).toBeTruthy(); expect(screen.getByText(/Direct URLs/i)).toBeTruthy(); }); it("direct URL load of /modules/e mounts the E shell with its launch guard", async () => { render(makeWrapper(["/modules/e"])); expect(screen.getByTestId("module-shell-e")).toBeTruthy(); expect(screen.getByTestId("module-launch-animation")).toBeTruthy(); // Real dashboard primitives assemble — StatCards carry real titles await waitFor(() => { expect(screen.getAllByText(/Total Leads/i).length).toBeGreaterThan(0); }); }); it("direct URL load of /modules/s mounts the S shell with the S campaign page", async () => { render(makeWrapper(["/modules/s/campaigns"])); expect(screen.getByTestId("module-shell-s")).toBeTruthy(); expect(screen.getByTestId("module-launch-animation")).toBeTruthy(); await waitFor(() => { expect(document.querySelector('[data-module="s"]')).toBeTruthy(); }); }); it("launch animation reveals the workspace when completed", async () => { vi.useFakeTimers({ shouldAdvanceTime: true }); try { render(makeWrapper(["/modules/e"])); expect(screen.getByTestId("module-launch-animation")).toBeTruthy(); // Watchdog completes the assembly (slow-motion budget ≈ 3.3s) await vi.advanceTimersByTimeAsync(4000); await waitFor(() => { expect(screen.queryByTestId("module-launch-animation")).toBeNull(); }); } finally { vi.useRealTimers(); } }); it("launching Module S from the hub routes to /modules/s", async () => { const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime }); vi.useFakeTimers({ shouldAdvanceTime: true }); try { render(makeWrapper(["/"])); await user.click(screen.getByRole("button", { name: /Launch Module S/i })); await vi.advanceTimersByTimeAsync(4000); await waitFor(() => { expect(screen.getByTestId("module-shell-s")).toBeTruthy(); }); } finally { vi.useRealTimers(); } }); });