Files
next-tjwater-frontend/src/features/workbench/components/scheduled-condition-detail-panel.test.tsx
T

169 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { ScheduledConditionRecord, ScheduledWorkOrderItem } from "../types";
import { ConditionDetailPanel, WorkOrderActivityPanel } from "./scheduled-condition-detail-panel";
import { createVisibleTickerCards } from "./agent-task-ticker-utils";
import { createConditionConversationPrompt } from "../utils/scheduled-condition-prompts";
const baseCondition: ScheduledConditionRecord = {
id: "schedule-run-1",
kind: "condition",
taskId: "backend-schedule",
dataSource: "scheduled_tasks",
sessionId: "scheduled-condition-schedule-run-1",
title: "演示 低压调查",
summary: "后端调查运行",
status: "error",
riskLevel: "critical",
scheduledAt: "2026-09-17T02:10:00Z",
updatedAt: Date.parse("2026-09-17T02:20:00Z"),
detail: "调查执行状态:异常。",
recommendation: "请检查调查任务的输入参数与服务端执行日志。",
evidence: ["运行 ID:schedule-run-1", "运行状态:failed"],
modelName: "TJWater scheduler"
};
it("does not infer water-quality progress or conversation steps from elapsed time", () => {
const condition: ScheduledConditionRecord = { ...baseCondition, taskId: "water-quality-complaint", dataSource: "mock", status: "running" };
const [card] = createVisibleTickerCards([condition], 0, Date.now());
expect(card.view.progressValue).toBeUndefined();
expect(card.view.currentStep?.title).toBe("Agent 执行计划");
expect(createConditionConversationPrompt(condition)).not.toContain("工作流步骤");
});
describe("scheduled condition backend boundaries", () => {
afterEach(cleanup);
it("shows a flat work order with its recorded activity", () => {
const workOrder: ScheduledWorkOrderItem = {
id: "demo-work-order",
kind: "work_order",
code: "WO-DEMO",
scheduledAt: "2026-09-23T10:00:00Z",
title: "演示预约维修",
summary: "验证中文时间标签",
status: "pending",
riskLevel: "normal",
updatedAt: Date.parse("2026-09-23T10:00:00Z"),
source: "演示数据",
dispatcher: "调度岗",
priority: "normal",
dataSource: "mock",
location: "测试点",
assignee: "维修班组",
feedbackRequirements: ["回填处理结果"],
activity: [{ sequence: 1, occurredAt: "2026-09-23T09:00:00Z", actor: "调度岗",
kind: "created", title: "工单创建", detail: "确认预约窗口。" }]
};
render(<WorkOrderActivityPanel condition={workOrder} />);
expect(screen.getByText("工单创建")).toBeVisible();
expect(screen.getByText("回填处理结果")).toBeVisible();
expect(screen.queryByText("子任务")).not.toBeInTheDocument();
});
it("shows only persisted evidence for a failed backend condition", () => {
render(
<ConditionDetailPanel
condition={baseCondition}
dataSource="scheduled_tasks"
workOrderDataSource="backend"
onContinueConversation={vi.fn()}
/>
);
expect(screen.getByText("后端持久化工况")).toBeVisible();
expect(screen.getByText("运行 ID:schedule-run-1")).toBeVisible();
expect(screen.getByText("正式工单边界")).toBeVisible();
expect(screen.getByText(/只有后端同步的工单才会显示/)).toBeVisible();
expect(screen.queryByText("演示异常判断")).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "生成演示工单草稿" })).not.toBeInTheDocument();
});
it("does not synthesize workflow progress for a running backend condition", () => {
render(
<ConditionDetailPanel
condition={{ ...baseCondition, status: "running", riskLevel: "normal" }}
dataSource="scheduled_tasks"
onContinueConversation={vi.fn()}
/>
);
expect(screen.getByText("后端运行状态")).toBeVisible();
expect(screen.getByText(/不按经过时间推算百分比/)).toBeVisible();
expect(screen.queryByText(/演示执行流程/)).not.toBeInTheDocument();
expect(screen.queryByText("演示进度")).not.toBeInTheDocument();
});
it("does not expose operational-task model, session or duration metadata", () => {
render(
<ConditionDetailPanel
condition={{
...baseCondition,
dataSource: "operational_tasks",
modelName: "TJWater operational task",
sessionId: "browser-session-1"
}}
dataSource="operational_tasks"
onContinueConversation={vi.fn()}
/>
);
expect(screen.queryByText("TJWater operational task")).not.toBeInTheDocument();
expect(screen.queryByText("browser-session-1")).not.toBeInTheDocument();
expect(screen.queryByText("未记录")).not.toBeInTheDocument();
});
it("keeps the mock work-order interaction but labels it as a local demo draft", () => {
render(
<ConditionDetailPanel
condition={{
...baseCondition,
id: "mock-scada-error",
taskId: "scada-diagnosis",
dataSource: "mock",
title: "SCADA 数据诊断",
modelName: "供水时序诊断"
}}
dataSource="mock"
onContinueConversation={vi.fn()}
/>
);
expect(screen.getByText("演示异常判断")).toBeVisible();
expect(screen.getByText("演示处置方案")).toBeVisible();
fireEvent.click(screen.getByRole("button", { name: "生成演示工单草稿" }));
expect(screen.getByRole("button", { name: "演示草稿已生成" })).toBeDisabled();
expect(screen.getByText(/只保存在当前页面/)).toBeVisible();
expect(screen.queryByText("系统工单已提交")).not.toBeInTheDocument();
});
it("does not expose the removed mock Agent execution path", () => {
const onContinueConversation = vi.fn();
render(
<ConditionDetailPanel
condition={{
...baseCondition,
id: "peripheral-water-quality-order-1",
taskId: "water-quality-complaint",
dataSource: "mock",
sessionId: "agent-session-water-quality",
title: "水质投诉调查",
status: "running",
riskLevel: "attention",
scheduledAt: new Date().toISOString(),
durationMinutes: 15,
evidence: ["来源工单:order-1", "投诉位置:演示小区"]
}}
dataSource="mock"
onContinueConversation={onContinueConversation}
/>
);
expect(screen.getByText("后端运行状态")).toBeVisible();
expect(screen.queryByText(/演示执行流程/)).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "与 Agent 协同" })).not.toBeInTheDocument();
expect(onContinueConversation).not.toHaveBeenCalled();
});
});