import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { ApprovalDialog } from "../src/components/approvals/ApprovalDialog.js"; import { AdsMetricsTool } from "../src/components/tools/AdsMetricsTool.js"; import { ToolFallback } from "../src/components/tools/ToolFallback.js"; import type { ClientApproval } from "../src/store/reducer.js"; const pendingApproval: ClientApproval = { approvalId: "ap_1", toolCallId: "tool_1", toolName: "save_report_draft", arguments: { title: "周报", body: "内容" }, riskLevel: "medium", expiresAt: "2026-09-07T09:00:00.000Z", status: "pending", }; describe("tool and approval UI", () => { it("shows registered representative frames but never external frame URLs or a fake final pass", () => { render(); expect(screen.getAllByRole("img")).toHaveLength(1); expect(screen.getByRole("img")).toHaveAttribute("src", "/api/sessions/ses_1/editor/job_known/frames/frame_known"); expect(screen.getByText(/尚未完成剧情验证/)).toBeVisible(); expect(screen.getByText("job_known")).toBeVisible(); }); it.each([ ["prepare_drama_sources", "允许下载所选分集并在本机抽帧吗?", "批准本次下载"], ["read_drama_frames", "允许将字幕和代表帧发送给当前模型吗?", "批准本次分析"], ["render_editor_preview", "允许生成 10 秒 REVIEW 预览吗?", "批准本次渲染"], ])("explains the media boundary for %s", (toolName, title, button) => { render(); expect(screen.getByRole("dialog", { name: title })).toBeVisible(); expect(screen.getByRole("button", { name: button })).toBeVisible(); expect(screen.getByText(/job_authorized/)).toBeVisible(); expect(screen.queryByText("report.md")).not.toBeInTheDocument(); }); it("identifies licensed CMS content reads and their model destination", () => { render(); expect(screen.getByRole("dialog", { name: "允许读取 CMS 内容并交给模型吗?" })).toBeVisible(); expect(screen.getByText(/fixture-drama/)).toBeVisible(); expect(screen.queryByText("report.md")).not.toBeInTheDocument(); }); it("offers only Session report download links and exposes PDF generation failures", () => { render(); expect(screen.getByRole("link", { name: "下载 HTML" })).toHaveAttribute("href", "/api/sessions/ses_1/reports/rpt_1/html"); expect(screen.queryByRole("link", { name: "下载 PDF" })).not.toBeInTheDocument(); expect(screen.getByText("PDF 未生成")).toBeVisible(); }); it("shows actual analytics scope and destination rather than pretending the action only saves a file", () => { render(); expect(screen.getByRole("dialog", { name: "允许查询真实经营数据吗?" })).toBeVisible(); expect(screen.getByText(/2026-09-08/)).toBeVisible(); expect(screen.getByText(/test-account/)).toBeVisible(); expect(screen.getByRole("button", { name: "批准本次查询" })).toBeVisible(); expect(screen.queryByText("report.md")).not.toBeInTheDocument(); }); it("disables both decisions after submitting approval", async () => { const user = userEvent.setup(); let resolveApproval: (() => void) | undefined; const approve = vi.fn(() => new Promise((resolve) => { resolveApproval = resolve; })); render(); await user.click(screen.getByRole("button", { name: "批准并保存" })); expect(screen.getByRole("button", { name: "批准并保存" })).toBeDisabled(); expect(screen.getByRole("button", { name: "拒绝" })).toBeDisabled(); expect(approve).toHaveBeenCalledTimes(1); resolveApproval?.(); }); it("renders safe ads metrics fields", () => { render(); expect(screen.getByText("demo-account")).toBeVisible(); expect(screen.getByText("3.01")).toBeVisible(); }); });