合并yy与远程qyqy_develop并保留业务优先级

This commit is contained in:
2026-09-14 18:16:33 +08:00
26 changed files with 4422 additions and 53 deletions
+53
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import re
import subprocess
import sys
from pathlib import Path
@@ -191,6 +192,39 @@ def test_advisor_dashboard_is_composed_from_feature_modules() -> None:
assert "ACTION_LABELS" in config
def test_no_portal_page_includes_the_same_script_twice() -> None:
"""同一个入口 JS 被引两次(哪怕 `?v=` 不同)会让页面出现两份顶部导航。
浏览器按**完整 URL** 去重:`x.js?v=A` 与 `x.js?v=B` 是两个模块、**各执行一次**。
入口里的 `mountShell()` 于是跑两遍,插入两份 header / footer ——
2026-09-14 `employee-console/workspace/index.html` 就这么写过:合并时
两个分支各自把同一行的版本号换成新的,两边都被保留,成了一条重复的 `<script>`。
"""
pattern = re.compile(r"<script[^>]*\ssrc=[\"']([^\"']+)[\"']", re.IGNORECASE)
duplicated: list[str] = []
for page in sorted(PORTAL.rglob("*.html")):
# 只比 `<script>`;站内绝对路径去掉 query 再归并
sources = [
url.split("?", 1)[0] if url.startswith("/") else url
for url in pattern.findall(page.read_text(encoding="utf-8"))
]
repeated = sorted({src for src in sources if sources.count(src) > 1})
if repeated:
duplicated.append(f"{page.relative_to(PORTAL)}: {repeated}")
assert not duplicated, f"同一入口脚本被引入多次:{duplicated}"
def test_mount_shell_is_idempotent() -> None:
"""`mountShell` 要自带「已经挂过就不再挂」的保护。
上一条测试守住 HTML,这一条守住代码 —— 两侧都挡一道,
因为这个 bug 的症状很难反推原因(页面看起来只是"多了一块"),
而以后加缓存版本号时很容易再犯。
"""
source = (PORTAL / "common" / "layout" / "app-shell.js").read_text(encoding="utf-8")
assert "if (document.querySelector('.site-header')) return;" in source
def test_portal_feature_modules_have_consistent_imports() -> None:
"""拆分前端模块时最容易漏 import:定义搬走了,使用处却留在原文件。
@@ -358,6 +392,14 @@ def test_risk_tables_show_page_and_total_summary() -> None:
assert "共 ${total} 条" in source
def test_risk_alert_queue_uses_ten_rows_per_page() -> None:
source = (
PORTAL / "employee-risk" / "dashboard" / "dashboard.js"
).read_text(encoding="utf-8")
assert "limit: 10" in source
assert "meta.page_size ?? 10" in source
def test_risk_alert_prompts_hide_until_alert_context_is_bound() -> None:
html = (PORTAL / "employee-risk" / "dashboard" / "index.html").read_text(encoding="utf-8")
css = (PORTAL / "employee-risk" / "dashboard" / "dashboard.css").read_text(encoding="utf-8")
@@ -375,6 +417,17 @@ def test_admin_workspace_is_not_an_identity_placeholder() -> None:
assert label in html
def test_admin_workspace_rule_submit_closes_before_next_function() -> None:
source = (
PORTAL / "employee-console" / "workspace" / "workspace.js"
).read_text(encoding="utf-8")
assert (
" } finally { submit.disabled = false; }\n"
" }\n\n"
" async function loadDriftReviews() {"
) in source
def test_frontend_has_no_remote_scripts_or_token_local_storage() -> None:
sources = "\n".join(
path.read_text(encoding="utf-8")