- 侧边栏 Logo 改为导入根目录 logo_square.png,favicon 也切换为 /logo_square.png,并让前端服务显式提供该根目录图片。 - 头颈部CT分割默认模板分类名改为纯中文,去掉括号英文翻译,颜色和 maskid 保持用户给定顺序。 - 增加旧版头颈部CT英文括号 label 的窄迁移,启动 seed 时自动把旧默认系统模板更新为纯中文默认。 - 更新前端 Logo 测试、后端默认模板和恢复出厂设置测试,覆盖纯中文分类和根目录方形 Logo。 - 更新 AGENTS、README、前端审计、需求冻结和测试计划文档,记录根目录 Logo 和头颈部CT纯中文默认分类。
121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
def test_template_crud_packs_and_unpacks_mapping_rules(client):
|
|
payload = {
|
|
"name": "Template",
|
|
"color": "#06b6d4",
|
|
"z_index": 0,
|
|
"classes": [{"id": "c1", "name": "胆囊", "color": "#ff0000", "zIndex": 10}],
|
|
"rules": [{"id": "r1", "name": "rule"}],
|
|
}
|
|
|
|
created = client.post("/api/templates", json=payload)
|
|
assert created.status_code == 201
|
|
template_id = created.json()["id"]
|
|
assert created.json()["classes"][0]["name"] == "胆囊"
|
|
assert created.json()["rules"][0]["id"] == "r1"
|
|
|
|
listing = client.get("/api/templates")
|
|
assert listing.status_code == 200
|
|
assert listing.json()[0]["classes"][0]["name"] == "胆囊"
|
|
|
|
detail = client.get(f"/api/templates/{template_id}")
|
|
assert detail.status_code == 200
|
|
assert detail.json()["name"] == "Template"
|
|
|
|
updated = client.patch(f"/api/templates/{template_id}", json={
|
|
"classes": [{"id": "c2", "name": "肝脏", "color": "#00ff00", "zIndex": 20}],
|
|
"rules": [],
|
|
})
|
|
assert updated.status_code == 200
|
|
assert updated.json()["classes"][0]["name"] == "肝脏"
|
|
|
|
deleted = client.delete(f"/api/templates/{template_id}")
|
|
assert deleted.status_code == 204
|
|
assert client.get(f"/api/templates/{template_id}").status_code == 404
|
|
|
|
|
|
def test_template_404s(client):
|
|
assert client.get("/api/templates/999").status_code == 404
|
|
assert client.patch("/api/templates/999", json={"name": "x"}).status_code == 404
|
|
assert client.delete("/api/templates/999").status_code == 404
|
|
|
|
|
|
def test_default_head_neck_ct_template_is_seeded_and_visible(client, db_session):
|
|
from main import ensure_default_templates
|
|
from models import Template
|
|
|
|
ensure_default_templates(db_session)
|
|
ensure_default_templates(db_session)
|
|
|
|
templates = db_session.query(Template).filter(Template.owner_user_id.is_(None)).all()
|
|
names = [template.name for template in templates]
|
|
assert names.count("头颈部CT分割") == 1
|
|
|
|
listing = client.get("/api/templates")
|
|
assert listing.status_code == 200
|
|
head_neck = next(template for template in listing.json() if template["name"] == "头颈部CT分割")
|
|
assert head_neck["description"] == "头颈部CT分割"
|
|
expected_names = [
|
|
"肿瘤/结节",
|
|
"下颌骨",
|
|
"甲状腺",
|
|
"气管",
|
|
"颈椎",
|
|
"颈动脉",
|
|
"颈静脉",
|
|
"腮腺",
|
|
"下颌下腺",
|
|
"舌骨",
|
|
"待分类",
|
|
]
|
|
expected_colors = [
|
|
"#ff0000",
|
|
"#00ff00",
|
|
"#0000ff",
|
|
"#ffff00",
|
|
"#ff00ff",
|
|
"#00ffff",
|
|
"#ff8000",
|
|
"#800080",
|
|
"#008080",
|
|
"#808000",
|
|
"#000000",
|
|
]
|
|
actual_names = [item["name"] for item in head_neck["classes"]]
|
|
actual_colors = [item["color"] for item in head_neck["classes"]]
|
|
actual_mask_ids = [item["maskId"] for item in head_neck["classes"]]
|
|
if actual_names != expected_names:
|
|
raise AssertionError(f"Unexpected head-neck classes: {actual_names}")
|
|
if actual_colors != expected_colors:
|
|
raise AssertionError(f"Unexpected head-neck colors: {actual_colors}")
|
|
if actual_mask_ids != [*list(range(1, 11)), 0]:
|
|
raise AssertionError(f"Unexpected head-neck mask IDs: {actual_mask_ids}")
|
|
|
|
|
|
def test_default_head_neck_ct_template_migrates_legacy_english_labels(db_session):
|
|
from main import ensure_default_templates
|
|
from models import Template
|
|
|
|
db_session.add(Template(
|
|
name="头颈部CT分割",
|
|
description="legacy",
|
|
color="#ef4444",
|
|
z_index=10,
|
|
owner_user_id=None,
|
|
mapping_rules={
|
|
"classes": [
|
|
{"id": "old-1", "name": "肿瘤/结节 (Tumor/Nodule)", "color": "#ff0000", "zIndex": 10, "maskId": 1},
|
|
{"id": "reserved-unclassified", "name": "待分类", "color": "#000000", "zIndex": 0, "maskId": 0},
|
|
],
|
|
"rules": [],
|
|
},
|
|
))
|
|
db_session.commit()
|
|
|
|
ensure_default_templates(db_session)
|
|
|
|
templates = db_session.query(Template).filter(Template.name == "头颈部CT分割").all()
|
|
assert len(templates) == 1
|
|
classes = templates[0].mapping_rules["classes"]
|
|
assert classes[0]["name"] == "肿瘤/结节"
|
|
assert all("(" not in item["name"] for item in classes)
|