- 上下文清单、任务列表与详情、恢复控制、运行观察、创作对话与消息流、正式变更决策面板、正文写作与候选审阅、资料研究等页面同步本轮后端能力。 - 事件标签表补齐后端事件类型;查询键与生成客户端随 HTTP 契约重新生成。 - 依赖调整后 lockfile 同步;交互用例与浏览器旅程 spec 一并更新。 - 证据:make 前端检查(lint + typecheck + Pi 工具桥 tsc)exit 0;make 前端测试 37 文件 / 120 用例通过。
85 lines
3.8 KiB
TypeScript
85 lines
3.8 KiB
TypeScript
import { afterEach, expect, it, vi } from "vitest";
|
||
import {
|
||
cleanup,
|
||
fireEvent,
|
||
render,
|
||
screen,
|
||
waitFor,
|
||
} from "@testing-library/react";
|
||
import { Ui规则启用 } from "../../src/功能/审校修订/规则启用";
|
||
|
||
const api = vi.hoisted(() => ({ GET: vi.fn(), POST: vi.fn() }));
|
||
vi.mock("../../src/接口/生成/客户端", () => ({ 客户端: api }));
|
||
afterEach(() => {
|
||
cleanup();
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
// @muse-case {"case_id":"NC-rule-activation-review","environment":"离线","given":"固定请求、来源与作者;按用例环境准备独立测试输入","when":"通过实际公开入口执行并核对拒绝、状态及持久结果","then":["NC-rule-activation-review:读取和打开审阅都不代作者启用,同次决定可重试"],"contract":"docs/系统架构/新版设计/模块设计/B10-效果评测.md"}
|
||
it("NC-rule-activation-review:读取和打开审阅都不代作者启用,同次决定可重试", async () => {
|
||
api.GET.mockResolvedValue({
|
||
data: { rule_id: "l002", current: null, consumable: false, reason: null },
|
||
});
|
||
api.POST.mockResolvedValue({
|
||
data: { review_id: "review-1", review_hash: "a".repeat(64) },
|
||
});
|
||
render(<Ui规则启用 ruleId="l002" version={2} />);
|
||
expect(api.GET).not.toHaveBeenCalled();
|
||
fireEvent.click(screen.getByRole("button", { name: "核对规则启用状态" }));
|
||
await screen.findByText(/当前没有生效规则/);
|
||
fireEvent.change(screen.getByLabelText("规则验证凭据编号"), {
|
||
target: { value: "proof-1" },
|
||
});
|
||
fireEvent.click(
|
||
screen.getByRole("button", { name: "核对凭据并打开启用审阅" }),
|
||
);
|
||
await screen.findByRole("button", { name: "确认启用此版本" });
|
||
expect(api.POST).toHaveBeenCalledTimes(1);
|
||
api.POST.mockRejectedValueOnce(new Error("响应中断"));
|
||
fireEvent.click(screen.getByRole("button", { name: "确认启用此版本" }));
|
||
await screen.findByText("响应中断");
|
||
const first = api.POST.mock.calls[1][1].body;
|
||
api.POST.mockResolvedValueOnce({ data: { status: "committed" } });
|
||
api.GET.mockResolvedValueOnce({
|
||
data: {
|
||
rule_id: "l002",
|
||
current: { state: "active", activation_revision: 1, rule_version: 2 },
|
||
consumable: true,
|
||
reason: null,
|
||
},
|
||
});
|
||
fireEvent.click(screen.getByRole("button", { name: "确认启用此版本" }));
|
||
await screen.findByText(/已启用第 2 版/);
|
||
expect(api.POST.mock.calls[2][1].body).toEqual(first);
|
||
});
|
||
|
||
// @muse-case {"case_id":"NC-rule-activation-old-version","environment":"离线","given":"固定请求、来源与作者;按用例环境准备独立测试输入","when":"通过实际公开入口执行并核对拒绝、状态及持久结果","then":["NC-rule-activation-old-version:候选已更新时停用请求仍点名实际生效旧版"],"contract":"docs/系统架构/新版设计/模块设计/B10-效果评测.md"}
|
||
it("NC-rule-activation-old-version:候选已更新时停用请求仍点名实际生效旧版", async () => {
|
||
api.GET.mockResolvedValue({
|
||
data: {
|
||
rule_id: "l002",
|
||
current: { state: "active", activation_revision: 3, rule_version: 1 },
|
||
consumable: false,
|
||
reason: "凭据已停止",
|
||
},
|
||
});
|
||
api.POST.mockResolvedValue({
|
||
data: { review_id: "review-2", review_hash: "b".repeat(64) },
|
||
});
|
||
render(<Ui规则启用 ruleId="l002" version={2} />);
|
||
fireEvent.click(screen.getByRole("button", { name: "核对规则启用状态" }));
|
||
await screen.findByText(/已启用第 1 版/);
|
||
fireEvent.click(screen.getByRole("button", { name: "核对停用依据" }));
|
||
await screen.findByRole("button", { name: "确认停用此版本" });
|
||
await waitFor(() => expect(api.POST).toHaveBeenCalledTimes(1));
|
||
expect(api.POST.mock.calls[0][1].body).toEqual({
|
||
request: {
|
||
rule_id: "l002",
|
||
version: 1,
|
||
action: "disable",
|
||
expected_activation_revision: 3,
|
||
credential_id: "",
|
||
},
|
||
});
|
||
});
|