"""test_editor.py —— 文档编辑(mock LLM,不连真 LLM)。""" from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[2])) import pytest # noqa: E402 from app.services.docgen import editor # noqa: E402 from app.services.docgen import llm as llm_mod # noqa: E402 from app.services.docgen.settings import DocgenPaths, set_paths # noqa: E402 def _run(coro): import anyio return anyio.run(lambda: coro) async def _fake_complete_text(system, user, **kwargs): return "# 修改后的文档\n\n新的正文内容。" async def _fail_complete_text(system, user, **kwargs): raise llm_mod.LLMError("fake down") def test_apply_edit_short_doc(monkeypatch): monkeypatch.setattr(llm_mod, "complete_text", _fake_complete_text) result = _run(editor.apply_edit("# 原标题\n\n旧正文。", "把标题改掉")) assert result["markdown"] == "# 修改后的文档\n\n新的正文内容。" def test_apply_edit_empty_instruction_returns_original(monkeypatch): md = "# 文档\n\n内容。" result = _run(editor.apply_edit(md, " ")) assert result["markdown"] == md def test_apply_edit_long_doc_chunked(monkeypatch): """长文档分段编辑:每段独立请求。""" calls = {"n": 0} async def _counting(system, user, **kwargs): calls["n"] += 1 return "编辑后的段落。" monkeypatch.setattr(llm_mod, "complete_text", _counting) long_md = "\n\n".join(f"第 {i} 段:" + "内容" * 200 for i in range(50)) result = _run(editor.apply_edit(long_md, "统一润色")) assert "编辑后的段落" in result["markdown"] assert calls["n"] >= 2 # 分多段调用 def test_apply_edit_chunk_failure_keeps_original(monkeypatch): monkeypatch.setattr(llm_mod, "complete_text", _fail_complete_text) long_md = "\n\n".join(f"第 {i} 段:" + "内容" * 200 for i in range(30)) result = _run(editor.apply_edit(long_md, "润色")) # 每段失败都保留原段 → 原文不丢 assert "第 0 段" in result["markdown"] def test_smart_export_docx(tmp_path, monkeypatch): set_paths(DocgenPaths(root=str(tmp_path / "docgen"))) out = editor.smart_export("# 标题\n\n正文。", "docx") assert out.exists() assert out.suffix == ".docx" def test_smart_export_pdf(tmp_path, monkeypatch): set_paths(DocgenPaths(root=str(tmp_path / "docgen"))) out = editor.smart_export("# 标题\n\n正文。", "pdf") assert out.exists() assert out.suffix == ".pdf"