Files
AgentLab/backend/tests/test_app_catalog.py
T
ThearchyHelios 277982ead3 普通用户建应用(后端):
- 蓝图:bp_* 操作和逐卡白名单、蓝图检查、留痕、按蓝图判权限;五个场景模板加自由形(骨架、关节、应用骨架、定时任务),实例化与骨架比对;BlueprintApplier / TemplateApplier(只收模板声明过的关节)与自查;look 新类别口径卡;蓝图对话和填关节两个流式接口,不同组的关节并行填、出错的组串行重试;模板列表
- 试运行与发布单:四种起点(对话、模板、问数据的一轮、已发布版本);试运行是探索运行,草稿应用按这次运行解析、印章写试运行,流程类派给自己、不触发升级;发布单九步、预检只读、每步留痕、停下后接着做、核对卡片指纹和应用管理权、启动时整理中断的单;白话层覆盖全部问题编号
- 记录表与文件:平台托管只追加的记录表、按高水位固定数据、连接上的临时视图做行级可见、写入走动作(records_append)、表版本在发布时切换、草稿不影响线上、记录列表遮敏感列;文件按哈希存、两步上传、提交时绑定运行、下载按读权限、清理、file_text、按配方导入一期(table_import_period)
- 个人应用:存成个人应用(问数据的约束)、刷新(遮罩、只读、每日上限)、只有拥有者看得见、提交审核与共享副本、开关下发到认人接口;页面编辑的候选;隐藏组件不下发;三条新检查
2026-10-15 12:09:29 +08:00

60 lines
3.3 KiB
Python

"""组件目录(app/apps/catalog.py)的 props 写给人看的中文名。
- 每个组件的每一项 props 都有 title,而且是中文:应用编辑的属性面板按它写属性名,不露 label、chart、sort 这些键名
- 枚举都有 x-enum-labels,和 enum 一一对应(同表单 agentlab.form/1 的写法),选项不露 line / bar
- title、description、x-enum-labels 只是注解:校验照旧,取值不对的照样报 app.props_invalid
"""
from __future__ import annotations
import re
from jsonschema import Draft202012Validator
from app.apps.catalog import BY_NAME, COMPONENTS, catalog_payload
_CJK = re.compile(r"[㐀-鿿]")
def test_every_prop_has_a_chinese_title():
missing = [(c["name"], key) for c in COMPONENTS for key, prop in c["props"]["properties"].items()
if not (isinstance(prop.get("title"), str) and _CJK.search(prop["title"]))]
assert missing == []
# 接口交出去的就是这一份
assert catalog_payload()["components"][0]["props"]["properties"]["title"]["title"] == "标题"
def test_enums_have_labels_in_the_same_order():
enums = [(c["name"], key, prop) for c in COMPONENTS for key, prop in c["props"]["properties"].items() if "enum" in prop]
assert enums, "目录里应当有枚举属性"
for name, key, prop in enums:
labels = prop.get("x-enum-labels")
assert isinstance(labels, list) and len(labels) == len(prop["enum"]), (name, key)
assert all(isinstance(t, str) and _CJK.search(t) for t in labels), (name, key)
assert BY_NAME["series"]["props"]["properties"]["chart"]["x-enum-labels"] == ["折线图", "柱状图"]
def test_annotations_do_not_change_validation():
schema = BY_NAME["notice"]["props"]
assert not list(Draft202012Validator(schema).iter_errors({"text": "说明", "tone": "warn"}))
errors = list(Draft202012Validator(schema).iter_errors({"tone": "提醒"}))
assert [list(e.absolute_path) for e in errors] == [["tone"]]
table = BY_NAME["table"]["props"]
assert not list(Draft202012Validator(table).iter_errors({"title": "门店", "sort": "-gmv", "limit": 20}))
assert list(Draft202012Validator(table).iter_errors({"limit": 0}))
assert list(Draft202012Validator(table).iter_errors({"unknown": 1}))
def test_text_props_are_marked_for_page_editing():
"""应用页上直接改的「改文字」(normal-user-apps N6)只改标了 x-text 的属性:给人看的标题、名称、说明。
列名、换算这类写给解析器的字符串不标,普通人改了会让组件取不到数。x-text 同样只是注解,不参与校验。"""
marked = {(c["name"], key) for c in COMPONENTS for key, prop in c["props"]["properties"].items()
if prop.get("x-text") is True}
assert {("metric", "label"), ("metric", "unit"), ("text", "markdown"), ("notice", "text"),
("section", "description"), ("entry_button", "label"), ("form", "submit_label")} <= marked
assert ("metric", "conv") not in marked and ("chart", "x") not in marked
# 只有字符串、不是枚举的才标
for name, key in marked:
prop = BY_NAME[name]["props"]["properties"][key]
assert prop["type"] == "string" and "enum" not in prop, (name, key)
assert not list(Draft202012Validator(BY_NAME["metric"]["props"]).iter_errors({"label": "销售额", "conv": "万"}))