import { describe, expect, it } from "vitest"; import { generateDailyReport } from "../src/agent/report"; import type { MarketDataProvider, WatchStock } from "../src/shared/types"; const watchlist: WatchStock[] = [ { id: "AAPL", symbol: "AAPL", display: "AAPL", market: "US", name: "Apple", addedAt: "2026-05-11T00:00:00.000Z" }, { id: "00700.HK", symbol: "00700", display: "00700.HK", market: "HK", name: "Tencent", addedAt: "2026-05-11T00:00:00.000Z" } ]; const provider: MarketDataProvider = { async snapshot(stock) { if (stock.display === "AAPL") { return { price: 100, currency: "USD", pe: 12, forwardPe: 11, revenueGrowth: 0.08, profitGrowth: 0.05, nextEarningsDate: "2026-05-13", peers: [ { display: "MSFT", pe: 28 }, { display: "GOOGL", pe: 24 } ], news: [{ title: "Apple supplier raises shipment guidance", url: "https://example.test/aapl" }] }; } return { price: 380, currency: "HKD", pe: 22, forwardPe: 20, revenueGrowth: 0.02, profitGrowth: -0.01, nextEarningsDate: "2026-06-30", peers: [{ display: "9988.HK", pe: 18 }], news: [] }; } }; describe("generateDailyReport", () => { it("ranks earnings, related news, valuation mismatch, and buy advice across markets", async () => { const report = await generateDailyReport(watchlist, provider, new Date("2026-05-11T00:00:00.000Z")); expect(report.generatedAt).toBe("2026-05-11T00:00:00.000Z"); expect(report.items).toHaveLength(2); expect(report.summary).toContain("US: 1"); expect(report.summary).toContain("HK: 1"); const apple = report.items.find((item) => item.stock.display === "AAPL"); expect(apple?.earnings.status).toBe("soon"); expect(apple?.valuation.label).toBe("discount"); expect(apple?.recommendation.action).toBe("buy_watch"); expect(apple?.news[0]?.title).toContain("supplier"); const tencent = report.items.find((item) => item.stock.display === "00700.HK"); expect(tencent?.valuation.label).toBe("premium"); expect(tencent?.recommendation.action).toBe("hold"); }); });