"""PLAN 626-1 — 노선 추천 미리보기 · [적용] 걷음 · 지형 바꿈 = 지형 칩(요구 530 · 결정 D1 · D2 · D7 · D8). - 옛 추천 모달 · 좌측 「노선 추천」 칸 · [적용](`as_initial`) 화면 부름 없음(서버 길 · 시험은 남김). - 미리보기 = 저장본 넷(영선 · 토공 · 기울기 · 비중) 하나만 · 끔 · 다시 셈(`recompute`) 없음. - 지형 칩 → `POST /route/design-terrain` — 노선 그대로(옛 = 새 선) · 초기값 폴더 안 씀 · 같은 지형 = 그대로. """ import asyncio import re from pathlib import Path from types import SimpleNamespace from uuid import uuid4 from B05_Profile import B05_Profile_Router_Replan as replan from B05_Profile import B05_Profile_Router_TerrainSwitch as switch from B06_Section import B06_Section_Router_DesignSave as design_save from common_util import common_util_save_guard as guard ROOT = Path(__file__).resolve().parents[2] B05 = ROOT / "B05_Profile" read = lambda path: path.read_text(encoding="utf-8") # noqa: E731 def test_옛_추천_모달_칸_적용_걷음() -> None: for name in ( "B05_Profile_UI_RouteEdit_Recommend.ts", "B05_Profile_UI_RouteEdit_Recommend_Help.ts", "B05_Profile_UI_RouteEdit_Recommend_Map.ts", "B05_Profile_UI_Panel_Recommend.ts", "B05_Profile_UI_Style_RouteRecommend.css", ): assert not (B05 / name).exists(), name assert "route-recommend" not in read(B05 / "B05_Profile_UI_Panel_Sections.ts") assert "recommend" not in read(ROOT / "A00_Common" / "design" / "design_view_profile.ts") # 화면 어디서도 as_initial 을 안 부름(서버 길은 남김) for path in B05.glob("B05_Profile_UI_*.ts"): assert "as_initial" not in read(path).replace("`as_initial`", ""), path.name assert "as_initial" in read(B05 / "B05_Profile_Router_Replan.py") def test_미리보기_넷_하나만_저장본만() -> None: src = read(B05 / "B05_Profile_UI_RouteEdit_RecPreview.ts") modes = re.search(r"const MODES = \[(.*?)\]", src, re.S).group(1) assert re.findall(r'"(\w+)"', modes) == ["gradeline", "earthwork", "gentle", "weighted"] assert "recompute" not in src and "createRoutePreviewMenu({" in src shared = read(ROOT / "A00_Common" / "map" / "map_route_preview.ts") # 636-2 공용 메뉴 · 그리기 assert "createPickMenu({" in shared and "multi: true" in shared and "offLabel" not in shared assert "terrain: opts.terrain()" in src # 지금 설계 지형 저장본(D7) chrome = read(B05 / "B05_Profile_UI_RouteEdit_Chrome.ts") assert "recommend: preview.root" in chrome and "terrain: terrain.root" in chrome menu = read(ROOT / "ui_template" / "ui_template_context_menu.ts") assert "export function createPickMenu(" in menu and "aria-checked" in menu def test_지형_칩_확인창_새_길() -> None: src = read(B05 / "B05_Profile_UI_RouteEdit_Terrain.ts") assert "askConfirm({" in src and "/route/design-terrain" in src assert "chip.set(toChip(design))" in src # 취소 · 실패 = 되돌림 assert "rebuildAfterRouteSave(projectId)" in src def _run(monkeypatch, now: str, want: str): calls: dict = {} line = [[0.0, 0.0], [10.0, 0.0]] async def paths(_pid): return Path("root"), "stored" async def recompute(*args): calls["args"] = args return {"route_id": 7} async def rows(*_a, **_k): return {} async def restore(*_a): calls["restored"] = True class Pool: def acquire(self): class Ctx: async def __aenter__(self): return object() async def __aexit__(self, *_): return False return Ctx() async def params(*_a): return {} def storage(root, scope): calls["scope"] = scope return SimpleNamespace(discard=lambda: None) monkeypatch.setattr(replan, "_project_paths", paths) monkeypatch.setattr(replan, "_planned_line", lambda _root: line) monkeypatch.setattr(replan, "_recompute", recompute) monkeypatch.setattr(design_save, "_restore", restore) monkeypatch.setattr(guard, "snapshot_rows", rows) monkeypatch.setattr(guard, "snapshot_storage", storage) monkeypatch.setattr(switch, "get_db_pool", lambda: Pool()) monkeypatch.setattr(switch, "get_surface_confirmation_params", params) monkeypatch.setattr(switch, "design_terrain", lambda _p: now) body = switch.DesignTerrainRequest(terrain=want) result = asyncio.run(switch.switch_route_design_terrain(uuid4(), body)) return result, calls, line def test_지형_바꿈_노선_그대로_초기값_안씀(monkeypatch) -> None: result, calls, line = _run(monkeypatch, "las", "sheet") assert result["changed"] is True and result["design"] == "sheet" _pid, _root, _stored, balanced, terrain, lines, initial = calls["args"] assert balanced is None and terrain == "sheet" and initial is False assert lines == (line, line) # 계획고 옮김 없음 · 노선 안 씀 assert guard.INITIAL_SCOPE[0] not in calls["scope"] assert "restored" not in calls def test_같은_지형이면_그대로(monkeypatch) -> None: result, calls, _ = _run(monkeypatch, "sheet", "sheet") assert result == {"status": "success", "design": "sheet", "changed": False} assert "args" not in calls and "scope" not in calls