feat(agent): render local interactive answers and fold completed process
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { AnswerUiView } from "./answer-ui-view";
|
||||
import { parseAnswerUiBlock } from "./contract";
|
||||
|
||||
function block(type: string, props: Record<string, unknown>) {
|
||||
const parsed = parseAnswerUiBlock({
|
||||
version: "answer-ui@1",
|
||||
block_id: "test",
|
||||
fallback_text: "演练",
|
||||
spec: { root: "node", elements: { node: { type, props, children: [] } } }
|
||||
});
|
||||
if (!parsed) throw new Error("invalid test fixture");
|
||||
return parsed;
|
||||
}
|
||||
describe("local interactive answer renderer", () => {
|
||||
it("renders through json-render and lets readers inspect exact chart data", () => {
|
||||
render(
|
||||
<AnswerUiView
|
||||
block={block("Chart", {
|
||||
title: "演练压力",
|
||||
chart_type: "line",
|
||||
source: "演练数据",
|
||||
x_data: ["08:00", "09:00"],
|
||||
series: [{ name: "压力", data: [0.3, 0.2] }]
|
||||
})}
|
||||
/>
|
||||
);
|
||||
fireEvent.click(screen.getByRole("button", { name: /^数据$/ }));
|
||||
expect(screen.getByRole("table")).toHaveTextContent("0.3");
|
||||
expect(screen.getByRole("table")).toHaveTextContent("09:00");
|
||||
expect(screen.getByRole("button", { name: /^数据$/ })).toHaveAttribute("aria-pressed", "true");
|
||||
});
|
||||
it("runs map location only after a user click and reports missing IDs", async () => {
|
||||
const locate = vi
|
||||
.fn()
|
||||
.mockResolvedValue({ located_ids: ["DEMO-P001"], missing_ids: ["DEMO-P002"] });
|
||||
render(
|
||||
<AnswerUiView
|
||||
block={block("MapLocation", {
|
||||
label: "定位演练监测点",
|
||||
layer: "scada",
|
||||
feature_ids: ["DEMO-P001", "DEMO-P002"],
|
||||
source: "演练数据"
|
||||
})}
|
||||
onLocate={locate}
|
||||
/>
|
||||
);
|
||||
expect(locate).not.toHaveBeenCalled();
|
||||
fireEvent.click(screen.getByRole("button", { name: "定位演练监测点" }));
|
||||
await waitFor(() => expect(screen.getByRole("status")).toHaveTextContent("另有 1 个未找到"));
|
||||
expect(locate).toHaveBeenCalledWith({
|
||||
layer: "scada",
|
||||
feature_ids: ["DEMO-P001", "DEMO-P002"]
|
||||
});
|
||||
});
|
||||
it("starts blank, requires input and sends one user message without claiming evidence is saved", async () => {
|
||||
let complete!: () => void;
|
||||
const submit = vi.fn(
|
||||
() =>
|
||||
new Promise<void>((resolve) => {
|
||||
complete = resolve;
|
||||
})
|
||||
);
|
||||
render(
|
||||
<AnswerUiView
|
||||
block={block("FollowUpForm", {
|
||||
title: "补充现场资料",
|
||||
description: "由用户提供",
|
||||
fields: [{ name: "location", label: "现场位置", kind: "text", required: true }]
|
||||
})}
|
||||
onSubmit={submit}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByLabelText("现场位置(必填)")).toHaveValue("");
|
||||
fireEvent.submit(screen.getByRole("form", { name: "补充现场资料" }));
|
||||
expect(submit).not.toHaveBeenCalled();
|
||||
expect(screen.getByRole("status")).toHaveTextContent("请填写必填资料");
|
||||
fireEvent.change(screen.getByLabelText("现场位置(必填)"), {
|
||||
target: { value: "用户指定位置" }
|
||||
});
|
||||
fireEvent.submit(screen.getByRole("form", { name: "补充现场资料" }));
|
||||
expect(submit).toHaveBeenCalledTimes(1);
|
||||
expect(submit.mock.calls[0]).toEqual([expect.stringContaining("现场位置:用户指定位置")]);
|
||||
expect(screen.getByRole("button", { name: "正在发送…" })).toBeDisabled();
|
||||
complete();
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole("status")).toHaveTextContent("资料已发送,请查看 Agent 回复")
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user