"""真实PG规则版本与诊断报告;当前正文、候选预览和不可变历史分别验证。""" from copy import deepcopy from dataclasses import replace import pytest from psycopg import OperationalError from muse.作品规划.接口 import 档案保存 from muse.审校修订.接口 import 审校错误, 读取内置规则 from muse.正文写作.接口 import 文本节点, 正文草稿, 段落 pytestmark = pytest.mark.数据库 @pytest.fixture def 诊断环境(章后环境): app, 身份 = 章后环境["装配"], 章后环境["作者"] svc = app.要求作品() 结构 = svc.新档案结构(身份, "diagnosis-work", "work_core", 1) svc.保存档案( 身份, "diagnosis-work", 档案保存("diagnosis-work", 0, {"名称": "合成诊断作品"}, 结构) ) svc.添加章节(身份, "diagnosis-ch", "diagnosis-work", "diagnosis-ch", "诊断章", 预期目录版本=0) app.要求正文().保存人工( 身份, "diag-text", "diagnosis-ch", 0, 正文草稿((段落("p1", (文本节点("值得注意的是,窗外正在下雨。"),)),)), ) doc = app.要求正文().读取正文(身份, "diagnosis-ch") target = { "work_id": "diagnosis-work", "chapter_id": "diagnosis-ch", "revision": doc["revision"], "document_hash": doc["document_hash"], "branch_id": "main", } return app, 身份, target @pytest.mark.case_id( "NC-w22-229001", environment="隔离PG与合成提供方", given="规则候选幂等新版追加与旧版拒绝覆盖", when="经B06公共用例及真实声明环境执行", then=["规则候选幂等新版追加与旧版拒绝覆盖"], contract="docs/系统架构/新版设计/模块设计/B06-审校修订.md", ) def test_规则候选幂等新版追加与旧版拒绝覆盖__229001(诊断环境): app, 身份, _ = 诊断环境 svc = app.要求审校() 预览 = svc.导入规则候选(身份, 预览=True) assert not 预览["persisted"] and svc.读取规则库(身份, 预览候选=True)["rules"] == {} 一 = svc.导入规则候选(身份) 二 = svc.导入规则候选(身份) assert len(一["results"]) == 26 and all(r["duplicate"] for r in 二["results"]) assert svc.读取规则库(身份)["rules"] == {} assert svc.读取规则库(身份, 预览候选=True)["fingerprint"] == 读取内置规则()["fingerprint"] 库 = deepcopy(读取内置规则()) 库["rules"]["l002"]["fix_hint"] = "保持并询问功能" with pytest.raises(审校错误, match="递增版本"): svc.导入规则候选(身份, 规则库=库) 库["rules"]["l002"]["version"] += 1 svc.导入规则候选(身份, 规则库=库) assert svc.读取规则库(身份, 预览候选=True)["rules"]["l002"]["version"] == 2 with app.要求数据库().连接(只读=True) as conn: assert conn.execute("SELECT count(*) FROM muse_rule_version").fetchone()[0] == 27 @pytest.mark.case_id( "NC-w22-229002", environment="隔离PG与合成提供方", given="正式零命中与候选预览真实报告及过期", when="经B06公共用例及真实声明环境执行", then=["正式零命中与候选预览真实报告及过期"], contract="docs/系统架构/新版设计/模块设计/B06-审校修订.md", ) def test_正式零命中与候选预览真实报告及过期__229002(诊断环境): app, 身份, target = 诊断环境 svc = app.要求审校() svc.导入规则候选(身份) 报告 = svc.生成诊断(身份, target) assert 报告["report"]["findings"] == [] and 报告["report"]["mode"] == "active" assert 报告 == svc.生成诊断(身份, target) 预览 = svc.生成诊断(身份, target, 预览候选=True) assert 预览["report"]["findings"] and 预览["report"]["mode"] == "candidate_preview" assert not svc.读取诊断(身份, 预览["diagnosis_id"])["stale"] app.要求正文().保存人工( 身份, "diag-text-new", "diagnosis-ch", 1, 正文草稿((段落("p1", (文本节点("雨停了。"),)),)) ) 历史 = svc.读取诊断(身份, 预览["diagnosis_id"]) assert 历史["stale"] and 历史["report"] == 预览["report"] with pytest.raises(审校错误): svc.生成诊断(身份, target, 预览候选=True) with pytest.raises(审校错误): svc.读取诊断(replace(身份, 作者="另一作者"), 预览["diagnosis_id"]) assert app.要求正文().读取正文(身份, "diagnosis-ch")["visible_text"] == "雨停了。" @pytest.mark.case_id( "NC-w22-229003", environment="隔离PG与合成提供方", given="数据库缺规则或篡改不退回种子", when="经B06公共用例及真实声明环境执行", then=["数据库缺规则或篡改不退回种子"], contract="docs/系统架构/新版设计/模块设计/B06-审校修订.md", ) def test_数据库缺规则或篡改不退回种子__229003(诊断环境, monkeypatch): app, 身份, target = 诊断环境 svc = app.要求审校() assert svc.生成诊断(身份, target, 预览候选=True)["report"]["executed_rules"] == [] def 断库(*args, **kwargs): raise OperationalError("合成数据库不可用") monkeypatch.setattr(type(svc.数据库), "连接", 断库) with pytest.raises(OperationalError): svc.读取规则库(身份, 预览候选=True)