合并yy与远程qyqy_develop并保留业务优先级
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -221,9 +221,13 @@ def test_overview_uses_success_envelope(monkeypatch) -> None:
|
||||
def test_alert_and_detail_routes_bind_parameters(monkeypatch) -> None:
|
||||
with authenticated_client(monkeypatch) as client:
|
||||
alerts = client.get("/api/v1/risk/alerts?limit=5&risk_level=高")
|
||||
alerts_ten = client.get("/api/v1/risk/alerts?limit=10")
|
||||
invalid = client.get("/api/v1/risk/alerts?limit=11")
|
||||
detail = client.get("/api/v1/risk/alerts/ALERT-001")
|
||||
|
||||
assert alerts.status_code == 200
|
||||
assert alerts_ten.status_code == 200
|
||||
assert invalid.status_code == 422
|
||||
assert alerts.json()["data"][0]["alert_no"] == "ALERT-001"
|
||||
assert detail.status_code == 200
|
||||
assert detail.json()["data"]["alert"]["alert_no"] == "ALERT-001"
|
||||
|
||||
@@ -103,9 +103,10 @@ def test_cursor_round_trip_and_invalid_values() -> None:
|
||||
|
||||
def test_query_schema_enforces_business_page_sizes() -> None:
|
||||
assert RiskAlertPageQuery(limit=5).limit == 5
|
||||
assert RiskAlertPageQuery(limit=10).limit == 10
|
||||
assert RiskEvidencePageQuery(limit=10).limit == 10
|
||||
with pytest.raises(ValueError):
|
||||
RiskAlertPageQuery(limit=6)
|
||||
RiskAlertPageQuery(limit=11)
|
||||
with pytest.raises(ValueError):
|
||||
RiskEvidencePageQuery(limit=11)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user