import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import StockDetail from "../analyze.ticker"; vi.mock("react-router", async () => { const actual = await vi.importActual("react-router"); return { ...actual, useLoaderData: () => ({ ticker: "AAPL", position: null, orders: [], bars: [], timeframe: "1D", range: "1M", }), useNavigate: () => () => {}, useLocation: () => ({ pathname: `/analyze/AAPL`, search: "" }), }; }); describe("StockDetail UI - executionPlan", () => { beforeEach(() => { vi.stubGlobal("fetch", vi.fn((url: string, opts?: any) => { if (url === "/api/analyze") { return Promise.resolve({ ok: true, json: async () => ({ action: "sell", confidence: 0.9, reasoning: "Exit position", executionPlan: { amount: 25, riskManagement: { maxLossPercent: 2 }, takeProfit: 150 } }) }); } return Promise.resolve({ ok: true, json: async () => ({}) }); })); }); it("displays executionPlan when sell decision returned", async () => { render(); const runButton = screen.getByRole("button", { name: /Run Trading Graph Analysis/i }); fireEvent.click(runButton); await waitFor(() => expect(screen.getByText(/Execution Plan/i)).toBeInTheDocument()); expect(screen.getByText(/Amount:/i)).toBeInTheDocument(); expect(screen.getByText(/25 shares/i)).toBeInTheDocument(); expect(screen.getByText(/Take profit:/i)).toBeInTheDocument(); expect(screen.getByText(/\$150/)).toBeInTheDocument(); }); });