muse-agent-example/web/tests/编辑/保存冲突.test.tsx
zizi 98530437f2 W11 编辑器、动态表单与人审工作台:编辑器、动态表单与人审工作台(确认前正文不落正式库)。
按 R2 串行阶段整理提交;包内文件为该阶段交付(含后续小增量),状态以工作包清单为准。
2026-09-10 19:25:41 +08:00

102 lines
3.2 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 { expect, it, vi } from "vitest";
import { 创建编辑会话 } from "../../src/功能/正文写作/编辑会话";
import { 接口错误 } from "../../src/接口/传输";
import type {
正文草稿,
正文记录,
保存请求,
} from "../../src/功能/正文写作/数据";
const draft = (text: string): 正文草稿 => ({
format_version: 1,
paragraphs: [
{ paragraph_id: "p1", content: [{ type: "text", text, marks: [] }] },
],
});
const record: 正文记录 = {
work_id: "w",
document_id: "doc",
chapter_id: "c",
branch_id: "main",
revision: 1,
state: "saved",
document: draft("原稿"),
visible_text: "原稿",
document_hash: "hash1",
visible_text_hash: "text1",
};
const scope = {
author_id: "a",
work_id: "w",
chapter_id: "c",
branch_id: "main",
};
it("NC-editor-save-generation:保存中的新输入保留,迟到回执只更新原会话", async () => {
let finish!: (v: {
revision: number;
document_hash: string;
receipt_id: string;
}) => void;
const save = vi.fn(
() =>
new Promise<{
revision: number;
document_hash: string;
receipt_id: string;
}>((r) => (finish = r)),
);
const buffer = { write: vi.fn(), clear: vi.fn() };
const session = 创建编辑会话(scope, record, save, buffer);
session.change(draft("第一稿"));
const request = session.save();
session.change(draft("第一稿和新输入"));
finish({ revision: 2, document_hash: "hash2", receipt_id: "receipt" });
await request;
expect(session.snapshot().draft).toEqual(draft("第一稿和新输入"));
expect(session.snapshot().base_revision).toBe(2);
expect(session.snapshot().status).toBe("dirty");
expect(buffer.clear).not.toHaveBeenCalled();
session.dispose();
await session.save();
expect(save).toHaveBeenCalledTimes(1);
});
it("NC-editor-save-conflict:版本冲突保留本地稿且不会自动换基线提交", async () => {
const save = vi.fn(async () => {
throw new 接口错误("REVISION_CONFLICT", "正文已更新", 409);
});
const session = 创建编辑会话(scope, record, save, {
write: vi.fn(),
clear: vi.fn(),
});
session.change(draft("我的稿"));
await session.save();
await session.save();
expect(session.snapshot().status).toBe("conflict");
expect(session.snapshot().draft).toEqual(draft("我的稿"));
expect(session.snapshot().base_revision).toBe(1);
expect(save).toHaveBeenCalledTimes(1);
});
it("NC-editor-save-retry:未知结果重试原命令,后续输入不改变在途载荷", async () => {
const requests: 保存请求[] = [];
const save = vi.fn(async (r: 保存请求) => {
requests.push(r);
if (requests.length === 1)
throw new 接口错误("NETWORK_UNAVAILABLE", "连接中断", 0);
return { revision: 2, document_hash: "hash2", receipt_id: "receipt" };
});
const session = 创建编辑会话(scope, record, save, {
write: vi.fn(),
clear: vi.fn(),
});
session.change(draft("发送稿"));
await session.save();
session.change(draft("新增内容"));
await session.save();
expect(requests[1]).toEqual(requests[0]);
expect(session.snapshot().draft).toEqual(draft("新增内容"));
expect(session.snapshot().status).toBe("dirty");
});