"""PLAN 323-9 ② — 정의 판 알림 되풀이: 구조물을 안 고치고 [저장]하면 정본이 안 나가 옛 판 그대로였음. 정본이 옛 정의 판이면 [저장]이 고침 없어도 정본을 다시 써 지금 판 도장 → 다시 열면 알림 없음. B06 기본 창구(`flushPendingStructures`) · B05 보기 창구(`saveStructuresIfDirty`) 같은 길. Node 헬퍼 = `helper_323_9_definition_stamp.cjs`(가짜 서버 · 진짜 API 모듈). """ from __future__ import annotations import json import subprocess from pathlib import Path import pytest HERE = Path(__file__).parent ROOT = HERE.parent.parent pytestmark = pytest.mark.skipif( not (ROOT / "config" / "node_modules").is_dir(), reason="프론트엔드 의존성 미설치" ) @pytest.fixture(scope="module") def out() -> dict: run = subprocess.run( ["node", str(HERE / "helper_323_9_definition_stamp.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=120, check=True, ) return json.loads(run.stdout) def test_old_version_save_without_edits_stamps_current(out: dict) -> None: assert out["notice"] == "구조물 정의가 판 21 으로 바뀜 — 저장하면 반영" assert out["staleOnOpen"] is True assert out["afterSave"] == {"version": 21, "puts": [1]} assert out["structures"][0]["structure_id"] == "s1" # 정본 그대로 def test_reopen_has_no_notice_and_no_more_puts(out: dict) -> None: assert out["again"] is None and out["staleAfter"] is False assert out["putsAfterSecond"] == 1 def test_b05_view_save_uses_same_stamp() -> None: page = (ROOT / "B05_Profile" / "B05_Profile_UI_Page_Structures.ts").read_text("utf-8") body = page[page.index("async function saveStructuresIfDirty") :] assert "readPending() === null && !definitionStale(deps.projectId)" in body[:400] assert "persistStructures(readPending() ?? ownStructures)" in body[:900]