"""chat.html 静态面前缀守卫(spec 2026-10-19 §4):页面级 __BASE_PATH__ 引导。 chat 是页面而非嵌入脚本(与 widget.js 的脚本地址自推导不同),由 chat.html head 内联引导脚本按 location.pathname 推导 basePath 并动态装载 css/js/ avatar;Host 模式(根路径 "/")推导为空串,所有引用零变化。守卫四点: 引导脚本在场且走正则白名单 match、静态标签不再绝对引用、引导块零 innerHTML(拼接安全防线 §2/§3)、chat.js 端点构造全部经 __BASE_PATH__。 """ from pathlib import Path STATIC = Path(__file__).resolve().parent.parent / "static" def read(rel): return (STATIC / rel).read_text(encoding="utf-8") def test_引导脚本存在且定义_BASE_PATH(): src = read("chat.html") assert "__BASE_PATH__" in src # 代码锚(非注释):base 推导必须走正则白名单 match assert "location.pathname.match(" in src def test_不再有静态绝对引用标签(): src = read("chat.html") assert 'href="/static/' not in src assert 'src="/static/js/' not in src assert 'src="/api/public/avatar"' not in src def test_引导脚本零innerHTML_拼接安全防线(): # 安全防线 §2/§3:base 只做 URL 属性赋值,绝不拼 HTML—— # 断言首个内联 块(引导脚本)内无 innerHTML src = read("chat.html") boot = src.split("", 1)[0] assert "innerHTML" not in boot def test_chatjs_端点全部走_BASE_PATH(): src = read("js/chat.js") assert "__BASE_PATH__" in src assert 'fetch("/api/' not in src