50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
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 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("disables both decisions after submitting approval", async () => {
|
|
const user = userEvent.setup();
|
|
let resolveApproval: (() => void) | undefined;
|
|
const approve = vi.fn(() => new Promise<void>((resolve) => { resolveApproval = resolve; }));
|
|
render(<ApprovalDialog request={pendingApproval} onApprove={approve} onDeny={vi.fn()} />);
|
|
|
|
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(<AdsMetricsTool
|
|
type="tool-call"
|
|
toolName="mock_ads_metrics"
|
|
toolCallId="tool_1"
|
|
args={{ account: "demo-account", days: 7 }}
|
|
argsText=""
|
|
result={{ spend: 1024.5, revenue: 3088.2, roas: 3.01 }}
|
|
status={{ type: "complete" }}
|
|
addResult={vi.fn()}
|
|
resume={vi.fn()}
|
|
respondToApproval={vi.fn()}
|
|
/>);
|
|
expect(screen.getByText("demo-account")).toBeVisible();
|
|
expect(screen.getByText("3.01")).toBeVisible();
|
|
});
|
|
});
|