"""分支来源、合并候选和S01复检使用真实隔离PG,支线不登记主线章后任务。""" from dataclasses import replace import pytest import test_正文候选与作者决定 as 候选测试 from muse.共享.调用身份 import 用途 from muse.共享.错误 import Muse错误 from muse.正文写作.接口 import 候选定位, 分支创建, 分支合并 pytestmark = pytest.mark.数据库 候选环境 = 候选测试.候选环境 def 开分支(env): svc, author, _ = env original = svc.读取正文(author, "chapter-candidate") req = 分支创建( "chapter-candidate", "main", original["revision"], original["document_hash"], "试写" ) receipt = svc.创建分支(author, "fork", req) return original, req, receipt def 合并请求(svc, author): compare = svc.比较分支(author, "chapter-candidate", "试写") return 分支合并( "chapter-candidate", "试写", compare["source_revision"], compare["source_hash"], compare["expected_revision"], compare["target_hash"], tuple(c["change_id"] for c in compare["changes"]), ) def test_分支固定历史起点独立保存回退且不派章后任务__234001(候选环境): svc, author, pools = 候选环境 with pools[用途.生产].连接(只读=True) as conn: before = conn.execute("SELECT count(*) FROM muse_task").fetchone()[0] original, req, receipt = 开分支(候选环境) assert svc.创建分支(author, "fork", req) == receipt svc.保存人工(author, "side-edit", req.chapter_id, 1, 候选测试.草稿("支线变化"), 分支="试写") svc.回退正文(author, "side-restore", req.chapter_id, 2, 1, 分支="试写") assert svc.读取正文(author, req.chapter_id) == original assert svc.读取正文(author, req.chapter_id, 分支="试写")["revision"] == 3 assert svc.读取正文(author, req.chapter_id, 分支="试写", 版本=2)["visible_text"].startswith( "支线变化" ) assert len(svc.列出分支(author, req.chapter_id)) == 2 with pools[用途.生产].连接(只读=True) as conn: assert conn.execute("SELECT count(*) FROM muse_task").fetchone()[0] == before with pytest.raises(Muse错误): svc.创建分支(author, "duplicate-name", req) with pytest.raises(Muse错误): svc.比较分支(replace(author, 作者="other"), req.chapter_id, "试写") def test_三方合并生成候选且独立主线修改在采纳后保持__234002(候选环境): svc, author, _ = 候选环境 开分支(候选环境) svc.保存人工(author, "side", "chapter-candidate", 1, 候选测试.草稿("支线首句"), 分支="试写") main = svc.保存人工( author, "main-change", "chapter-candidate", 1, 候选测试.草稿(尾句="作者新末段") ) req = 合并请求(svc, author) receipt = svc.合并分支(author, "merge", req) assert svc.合并分支(author, "merge", req) == receipt candidate = svc.读取候选(author, receipt["target_ref"]) assert candidate["visible_text"] == "支线首句\n\n作者新末段" assert candidate["decision"] == "undecided" assert svc.读取正文(author, "chapter-candidate")["revision"] == main["results"][0]["revision"] loc = 候选定位( candidate["candidate_id"], 1, candidate["candidate_hash"], candidate["document_id"], 2 ) review = svc.打开候选审阅(author, loc) 候选测试.决定(svc, author, "adopt-merge", loc, review) assert svc.读取正文(author, "chapter-candidate")["visible_text"] == candidate["visible_text"] assert svc.读取正文(author, "chapter-candidate", 分支="试写")["revision"] == 2 @pytest.mark.parametrize("changed", ["source", "target"]) def test_合并候选再编辑仍复检两端不覆盖新稿__234003(候选环境, changed): svc, author, _ = 候选环境 开分支(候选环境) svc.保存人工( author, "side", "chapter-candidate", 1, 候选测试.草稿("支线首句", "支线末句"), 分支="试写" ) receipt = svc.合并分支(author, "merge", 合并请求(svc, author)) candidate = svc.读取候选(author, receipt["target_ref"]) svc.编辑候选( author, "partial", candidate["candidate_id"], 1, candidate["candidate_hash"], 选择变更=(candidate["changes"][0]["change_id"],), ) latest = svc.读取候选(author, candidate["candidate_id"]) loc = 候选定位(latest["candidate_id"], 2, latest["candidate_hash"], latest["document_id"], 1) review = svc.打开候选审阅(author, loc) svc.保存人工( author, "advance", "chapter-candidate", 2 if changed == "source" else 1, 候选测试.草稿("后来保存的版本"), 分支="试写" if changed == "source" else "main", ) with pytest.raises(Muse错误): 候选测试.决定(svc, author, "stale-merge", loc, review) assert svc.读取候选(author, candidate["candidate_id"])["stale"] assert ( svc.读取候选(author, candidate["candidate_id"], 版本=1)["visible_text"] == candidate["visible_text"] ) def test_重叠冲突或过期合并请求不产生候选__234004(候选环境): svc, author, _ = 候选环境 开分支(候选环境) svc.保存人工(author, "side", "chapter-candidate", 1, 候选测试.草稿("支线首句"), 分支="试写") old_req = 合并请求(svc, author) svc.保存人工(author, "main", "chapter-candidate", 1, 候选测试.草稿("主线冲突首句")) for req in (old_req, 合并请求(svc, author)): with pytest.raises(Muse错误): svc.合并分支(author, "conflict", req) assert svc.列出候选(author, "chapter-candidate") == [] assert svc.读取正文(author, "chapter-candidate")["visible_text"].startswith("主线冲突首句")