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

103 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/** DOM组合事件与真实编辑器组件;不冒称操作系统原生输入法验收。 */
import { StrictMode } from "react";
import { afterEach, expect, it, vi } from "vitest";
import {
cleanup,
fireEvent,
render,
screen,
waitFor,
} from "@testing-library/react";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { Ui依赖装配 } from "../../src/应用/依赖装配";
import { Ui正文页 } from "../../src/功能/正文写作";
afterEach(() => {
cleanup();
vi.unstubAllGlobals();
localStorage.clear();
});
it("NC-editor-ime-save:StrictMode编辑会话在组合结束后保存完整中文", async () => {
const writes: unknown[] = [];
vi.stubGlobal(
"fetch",
vi.fn(async (request: Request) => {
const url = new URL(request.url);
let data: unknown;
if (url.pathname.endsWith("session")) data = { author_id: "author" };
else if (url.pathname.endsWith("chapters"))
data = {
work_id: "work",
revision: 1,
chapters: [{ chapter_id: "chapter", title: "第一章", position: 1 }],
};
else if (request.method === "POST") {
const body = await request.json();
writes.push(body);
data = {
receipt_id: "receipt",
results: [
{
chapter_id: "chapter",
branch_id: "main",
revision: 1,
document_hash: "hash1",
},
],
};
} else
data = {
work_id: "work",
document_id: "doc",
chapter_id: "chapter",
branch_id: "main",
revision: 0,
state: "unsaved",
document_hash: "hash0",
visible_text_hash: "text0",
visible_text: "",
document: {
format_version: 1,
paragraphs: [{ paragraph_id: "p0", content: [] }],
},
};
return new Response(JSON.stringify(data), {
headers: { "Content-Type": "application/json" },
});
}),
);
render(
<StrictMode>
<Ui依赖装配>
<MemoryRouter initialEntries={["/works/work/write/chapter"]}>
<Routes>
<Route
path="/works/:work_id/write/:chapter_id"
element={<Ui正文页 />}
/>
</Routes>
</MemoryRouter>
</Ui依赖装配>
</StrictMode>,
);
const editor = await screen.findByRole("textbox", { name: "章节正文" });
fireEvent.compositionStart(editor);
editor.querySelector("p")!.textContent = " “中文”e\u0301";
fireEvent.input(editor, {
inputType: "insertCompositionText",
data: " “中文”e\u0301",
isComposing: true,
});
await waitFor(() => expect(screen.getByText("正在输入…")).toBeTruthy());
fireEvent.click(screen.getByRole("button", { name: "立即保存" }));
expect(writes).toHaveLength(0);
fireEvent.compositionEnd(editor);
await waitFor(() => expect(writes).toHaveLength(1), { timeout: 3000 });
expect(writes[0]).toMatchObject({
chapter_id: "chapter",
expected_revision: 0,
document: { paragraphs: [{ content: [{ text: " “中文”e\u0301" }] }] },
});
expect(await screen.findByText("服务器已保存")).toBeTruthy();
});