diff --git a/app/components/__tests__/TradingViewChart.test.tsx b/app/components/__tests__/TradingViewChart.test.tsx index 888d244..acfb3d7 100644 --- a/app/components/__tests__/TradingViewChart.test.tsx +++ b/app/components/__tests__/TradingViewChart.test.tsx @@ -25,6 +25,7 @@ describe("TradingViewChart", () => { // Update the mock's setData to track calls const mockSeries = { setData: mockSetData }; mockCreateChart.mockReturnValue({ + timeScale: () => ({ applyOptions: vi.fn(), fitContent: vi.fn() }), addSeries: vi.fn(() => mockSeries), remove: vi.fn(), }); diff --git a/app/routes/__tests__/analyze.ticker.ui.test.tsx b/app/routes/__tests__/analyze.ticker.ui.test.tsx new file mode 100644 index 0000000..0d1c4cf --- /dev/null +++ b/app/routes/__tests__/analyze.ticker.ui.test.tsx @@ -0,0 +1,49 @@ +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(); + }); +});