"""E2E 自检守卫:fixture 只能使用 seed 脚本真正创建的运营账号。 为什么需要它(本轮发现的真实缺陷): 库中 operator 账号**没有任何迁移种子**,`DemoDataSeeder` 也不创建运营账号 (只统计数量)。因此全新库(CI)里唯一的运营账号来源是 `tests/e2e/sql/seed_e2e_operators.sql`。 而 `conftest.py` 的 `admin_token` 曾写死 `username="admin"` —— 那是某台 开发机上手工创建的遗留账号。本机有它,所以本地跑绿;CI 全新库没有它, 该 fixture 必然 401 → **整个 E2E job 从未真正通过过**。 这类"依赖本机手工数据"的写法没有任何运行期提示,只能靠机械检查拦住。 """ from __future__ import annotations import re from pathlib import Path E2E_DIR = Path(__file__).resolve().parent CONFTEST = E2E_DIR / "conftest.py" SEED_SQL = E2E_DIR / "sql" / "seed_e2e_operators.sql" MIGRATION_DIR = E2E_DIR.parent.parent / "backend" / "src" / "main" / "resources" / "db" / "migration" def _seeded_usernames() -> set[str]: sql = SEED_SQL.read_text(encoding="utf-8") # seed 用的是 VALUES 行:('uuid', '名称', 'username', crypt(...), 'active') return set(re.findall(r"'([A-Za-z0-9_]+)',\s+crypt\(", sql)) def _usernames_used_in_conftest() -> set[str]: src = CONFTEST.read_text(encoding="utf-8") used = set(re.findall(r'"username"\s*:\s*"([A-Za-z0-9_]+)"', src)) used |= set(re.findall(r'ADMIN_USERNAME\s*=\s*"([A-Za-z0-9_]+)"', src)) return used def test_conftest_only_logs_in_with_seeded_accounts() -> None: seeded = _seeded_usernames() assert seeded, f"未能从 {SEED_SQL.name} 解析出任何账号,守卫已失效" used = _usernames_used_in_conftest() assert used, f"未能从 {CONFTEST.name} 解析出任何登录用户名,守卫已失效" unknown = sorted(used - seeded) assert not unknown, ( "conftest 使用了 seed 脚本未创建的运营账号:" f"{unknown}(seed 现有:{sorted(seeded)})。\n" "全新库(CI)里这些账号不存在,对应 fixture 会 401,E2E 必然失败。" "请改用 seed 中的账号,或在 seed 脚本中补上该账号。" ) def test_no_operator_account_is_seeded_by_migrations() -> None: """锁住上面那条推理的前提:迁移确实没有 operator 种子。 若将来有人在迁移里加了 admin 种子,本用例会变红——那时应重新评估 `admin_token` 的选择(迁移种子同样是自举的,可作为合法来源), 而不是继续凭本机的遗留账号。 """ hits: list[str] = [] for sql_file in MIGRATION_DIR.glob("*.sql"): text = sql_file.read_text(encoding="utf-8", errors="replace") if re.search(r"INSERT\s+INTO\s+operators\b", text, re.IGNORECASE): hits.append(sql_file.name) assert not hits, ( f"迁移中出现了 operator 种子:{hits}。" "本次 E2E fixture 的选型前提('运营账号只能来自 seed 脚本')已改变," "请重新评估 conftest 的 ADMIN_USERNAME 与本文档说明。" )