"""387-1(384 단계 1) 세션 열쇠 — 설계 화면은 세션을 등록부(`b_page_state`)로만 · 프로젝트 없는 열쇠 0. · design · B05/B06 UI_* 파일 코드(주석 뺌)에 직접 sessionStorage 0 · 등록부 초안 · 결과 칸 옛 키는 모두 프로젝트를 품음 · `b05:pipes` 글 0 · `projectStateKeys` = 그 통 · 그 프로젝트 키만(노선 칸 포함 · 다른 프로젝트 · 다른 통 · 옛 키 밖) ./venv/Scripts/python.exe -m pytest resources/tester/test_384_1_session_keys.py -q """ from __future__ import annotations import json import re import subprocess from pathlib import Path ROOT = Path(__file__).resolve().parents[2] LOADER = Path(__file__).resolve().parent / "helper_ts_cjs_load.cjs" def _code(path: Path) -> str: text = path.read_text(encoding="utf-8") text = re.sub(r"/\*.*?\*/", "", text, flags=re.S) return re.sub(r"(?m)^\s*//.*$|\s//\s.*$", "", text) def _screen_files() -> list[Path]: files = list((ROOT / "A00_Common" / "design").rglob("*.ts")) files += (ROOT / "B05_Profile").glob("B05_Profile_UI_*.ts") files += (ROOT / "B06_Section").glob("B06_Section_UI_*.ts") return sorted(files) def test_화면_파일에_직접_세션_0() -> None: files = _screen_files() assert len(files) > 100 hits = [str(p.relative_to(ROOT)) for p in files if "sessionStorage" in _code(p)] assert hits == [] def test_프로젝트_없는_열쇠_0() -> None: hits = [str(p.relative_to(ROOT)) for p in _screen_files() if '"b05:pipes"' in _code(p)] assert hits == [] DRIVER = r""" const data = new Map(); const fake = { get length() { return data.size; }, key: (i) => [...data.keys()][i] ?? null, getItem: (k) => (data.has(k) ? data.get(k) : null), setItem: (k, v) => data.set(k, String(v)), removeItem: (k) => data.delete(k), }; globalThis.window = { sessionStorage: fake, localStorage: fake }; const { loadTs } = require(process.argv[1]); const s = loadTs(process.argv[2]); const legacy = Object.entries(s.STATE_REGISTRY) .filter(([, e]) => e.bucket !== "pref" && e.legacy) .map(([name, e]) => [name, e.legacy("PX", "RX")]); for (const k of [ "aislo:draft:crossw:p1:7", "aislo:draft:pipes:p1", "aislo:draft:pipes:p10", "aislo:draft:crossw:p2:7", "aislo:result:latest:p1", "b05:pipes", "b06:crossw:p1:7", ]) fake.setItem(k, "1"); process.stdout.write(JSON.stringify({ legacy, keys: s.projectStateKeys("draft", "p1").sort() })); """ def test_등록부_옛_키는_프로젝트_품음_사진_칸은_그_프로젝트만() -> None: run = subprocess.run( # noqa: S603 — 고정 실행 파일 ["node", "-e", DRIVER, str(LOADER), str(ROOT / "A00_Common" / "b_page_state.ts")], capture_output=True, text=True, encoding="utf-8", cwd=str(ROOT), ) # fmt: skip assert run.returncode == 0, run.stderr out = json.loads(run.stdout) assert out["legacy"] and all("PX" in key for _, key in out["legacy"]) assert out["keys"] == ["aislo:draft:crossw:p1:7", "aislo:draft:pipes:p1"]