#!/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("character", text) self.assertNotEqual(text, "character") def test未知英文枚举不裸露(self): text = server.enum_text("future_state", "status") self.assertIn("未登记", text) self.assertIn("future_state", text) def test状态标签显示中文和编码(self): text = server.chip("pending") self.assertIn("待确认", text) self.assertIn("pending", text) def test字段标题使用中文并保留协议字段编码(self): text = server.field_label("运行编号", "run_id") self.assertIn("运行编号", text) self.assertIn("run_id", text) def test工具名称使用中文并保留_cli编码(self): text = server._fmt_tools(["Read", "Grep"]) self.assertIn("读取", text) self.assertIn("文本搜索", text) self.assertIn("Read", text) self.assertIn("Grep", text) def test自由文本技术术语显示中文语义和编码(self): text = server.annotated_text("writer sandbox + writer + Claude CLI + MiniMax + semantic detector + asOf") self.assertIn("写手隔离环境", text) self.assertIn("写手 writer sandbox", 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("file_cas", 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("chapter_id=17474", 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) if __name__ == "__main__": unittest.main()