被多个 Skill 或看板消费的连接、模型、嵌入、Claude 运行时与声音账入口 各只保留一份实现;Skill 只留 CLI/落库,看板只读 muse-db,门禁锁死跨域注入。 Co-authored-by: Cursor <cursoragent@cursor.com>
162 lines
7.3 KiB
Python
162 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
||
"""看板展示层的中文语义与编码合同测试,不连接数据库。"""
|
||
import pathlib
|
||
import sys
|
||
import unittest
|
||
|
||
|
||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
||
import server # noqa: E402
|
||
|
||
|
||
class DashboardDisplayTest(unittest.TestCase):
|
||
def test已知枚举显示中文语义和字符串编码(self):
|
||
text = server.enum_text("character", "entity_type")
|
||
self.assertIn("人物", text)
|
||
self.assertIn("<code>character</code>", text)
|
||
self.assertNotEqual(text, "character")
|
||
|
||
def test未知英文枚举不裸露(self):
|
||
text = server.enum_text("future_state", "status")
|
||
self.assertIn("未登记", text)
|
||
self.assertIn("<code>future_state</code>", text)
|
||
|
||
def test状态标签显示中文和编码(self):
|
||
text = server.chip("pending")
|
||
self.assertIn("待确认", text)
|
||
self.assertIn("<code>pending</code>", text)
|
||
|
||
def test字段标题使用中文并保留协议字段编码(self):
|
||
text = server.field_label("运行编号", "run_id")
|
||
self.assertIn("运行编号", text)
|
||
self.assertIn("<code class='field-code'>run_id</code>", text)
|
||
|
||
def test工具名称使用中文并保留_cli编码(self):
|
||
text = server._fmt_tools(["Read", "Grep"])
|
||
self.assertIn("读取", text)
|
||
self.assertIn("文本搜索", text)
|
||
self.assertIn("<code>Read</code>", text)
|
||
self.assertIn("<code>Grep</code>", text)
|
||
|
||
def test自由文本技术术语显示中文语义和编码(self):
|
||
text = server.annotated_text("writer sandbox + writer + Claude CLI + MiniMax + semantic detector + asOf")
|
||
self.assertIn("写手隔离环境", text)
|
||
self.assertIn("写手 <span", text)
|
||
self.assertIn("模型命令行客户端", text)
|
||
self.assertIn("模型服务", text)
|
||
self.assertIn("语义检测器", text)
|
||
self.assertIn("截至章", text)
|
||
self.assertIn("<code>writer sandbox</code>", text)
|
||
|
||
def test说明截断不会切断编码或误改_postgresql(self):
|
||
text = server.annotated_text(server.short_text("场景 scenario: fine_outline_replay/校验", 20))
|
||
self.assertNotIn("fine_outl", text)
|
||
self.assertNotIn("Postgre数据库", server.annotated_text("PostgreSQL 查询"))
|
||
|
||
def test详情自由文本中的运行时编码也有中文语义(self):
|
||
text = server.annotated_text(
|
||
"Claude CLI fresh/sandbox + revision journal (file_cas) + raw vault; "
|
||
"被 detect/quality-gate/continuation/replay-eval 复用"
|
||
)
|
||
self.assertIn("模型命令行客户端", text)
|
||
self.assertIn("修订日志", text)
|
||
self.assertIn("原始证据仓", text)
|
||
self.assertIn("语义检测", text)
|
||
self.assertIn("质量门", text)
|
||
self.assertIn("实验库", server.annotated_text("muse-example"))
|
||
self.assertIn("正文块", server.annotated_text("正文 block"))
|
||
self.assertIn("<code>file_cas</code>", text)
|
||
|
||
def test卡片下钻地址保留筛选条件(self):
|
||
href = server._query_href(
|
||
"/works/12", {"q": ["薄雾号"], "type": ["location"], "status": ["pending"]}, card=25438
|
||
)
|
||
self.assertIn("q=", href)
|
||
self.assertIn("type=location", href)
|
||
self.assertIn("status=pending", href)
|
||
self.assertIn("card=25438", href)
|
||
|
||
def test章节展示中文标题并保留主键编码(self):
|
||
text = server._chapter_text(17474, 2, "称量")
|
||
self.assertIn("第2章《称量》", text)
|
||
self.assertIn("<code>chapter_id=17474</code>", text)
|
||
|
||
def test运行描述包含用途角色和章节(self):
|
||
text = server._run_description(
|
||
("run-prod-work12-ch2", 12, "深渊机神", 2, "user", "completed", "时间",
|
||
17474, 2, "称量", "writer", "generation", "production", "writer", "production_generation")
|
||
)
|
||
self.assertIn("正文生产", text)
|
||
self.assertIn("写手", text)
|
||
self.assertIn("第2章《称量》", text)
|
||
|
||
def test原始_JSON_错误信息可读(self):
|
||
text = server._content_text('{"failureType":"InvalidTextRepresentation"}')
|
||
self.assertIn('"failureType": "InvalidTextRepresentation"', text)
|
||
|
||
def test规划标题和摘要从载荷提取(self):
|
||
payload = {"chapterGoal": "林深被隔离审讯", "chapterEndHook": "茧准备出击"}
|
||
self.assertEqual(server._planning_title(payload, "fine_outline", 2), "第2章目标")
|
||
self.assertEqual(server._planning_summary(payload), "林深被隔离审讯")
|
||
|
||
def test数据库AI味页面展示正式库汇总(self):
|
||
text = server.view_ai_flavor({})
|
||
self.assertIn("AI 味案例", text)
|
||
self.assertIn("788", text)
|
||
self.assertIn("8", text)
|
||
self.assertIn("PostgreSQL muse-example 正式库", text)
|
||
self.assertIn("原文片段未保存", text)
|
||
self.assertIn("不是人工确认的 AI 味结论", text)
|
||
self.assertIn("来源已验证", text)
|
||
self.assertIn("788/788", text)
|
||
self.assertIn("batch_id=", text)
|
||
|
||
def test数据库AI味页面支持作品分页与卡片详情(self):
|
||
filtered = server.view_ai_flavor({"work": ["ref:机破星河_当年离歌"], "page": ["2"]})
|
||
self.assertIn("当前第 2/6 页", filtered)
|
||
self.assertIn("ref:机破星河_当年离歌", filtered)
|
||
detail = server.view_ai_flavor({"card": ["case-0b9ed3af70a7dbf315fc"]})
|
||
self.assertIn("全文 SHA-256", detail)
|
||
self.assertIn("原文片段未保存", detail)
|
||
self.assertIn("来源已验证", detail)
|
||
|
||
def test数据库案例详情显示用途和作用域边界(self):
|
||
detail = server.view_ai_flavor({"card": ["case-0b9ed3af70a7dbf315fc"]})
|
||
self.assertIn("当前用途", detail)
|
||
self.assertIn("仅供本卡/本作品人工复核", detail)
|
||
self.assertIn("backfill", detail)
|
||
|
||
def test数据库案例页面按当前数据库作品数动态渲染(self):
|
||
original_bundle = server._ai_db_bundle
|
||
try:
|
||
report, revalidation, error = original_bundle()
|
||
report = dict(report)
|
||
report["works"] = list(report["works"][:1])
|
||
report["totals"] = dict(report.get("totals") or {})
|
||
report["totals"]["books"] = 1
|
||
report["cards"] = list(report["cards"][:1])
|
||
report["totals"]["cards"] = 1
|
||
server._ai_db_bundle = lambda: (report, revalidation, error)
|
||
text = server.view_ai_flavor({})
|
||
finally:
|
||
server._ai_db_bundle = original_bundle
|
||
self.assertIn("按作品汇总(1 本)", text)
|
||
self.assertNotIn("按作品汇总(8 本)", text)
|
||
|
||
def test随包发布的离线回退夹具可被回退加载器解析(self):
|
||
"""离线回退夹具归看板自己所有;夹具坏了要在这里暴露,不能到断库时才发现。"""
|
||
report, error = server._load_ai_flavor_report()
|
||
self.assertIsNone(error)
|
||
self.assertEqual("ai-flavor-inventory-v1", report["schema_version"])
|
||
revalidation, error = server._load_ai_flavor_revalidation_report()
|
||
self.assertIsNone(error)
|
||
self.assertTrue(revalidation["usable"])
|
||
self.assertEqual(
|
||
{"cards": 788, "verified": 788, "stale": 0, "unavailable": 0, "card_mismatch": 0},
|
||
revalidation["totals"],
|
||
)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|