- 624-3 도구줄 = 공용 표 「b05」 · 아래 줄 = 공용 겹 줄(띠 · 올린 임도망도 숨김 · 처음 = 등고선 · 하천) · 범례 = 공용 legendRows(상태 글판 위) - 노선 띠 300 m 자르기 = B05 자기 칸(등고선 · 하천 · 1 m)만 · 그 밖 겹 = 안 자르는 둘째 GL 칸(맨 밑 · 켠 겹 있을 때만 · GL 만) · 등고선 끔 = 등고 글도 숨김 - 626-1 추천 보기 = 도구줄 아이콘 + 아래 판(영선 · 토공 최소 · 기울기 최소 · 비중 계산 · 끔) — route_recommend 저장본(지금 설계 지형) 선만 · 다시 셈 · 쓰기 없음 - 지형 칩 → 확인창 → 새 POST /route/design-terrain(설계 지형만 바꿈 · 노선 저장 체인 다시 · 노선 · 초기값 · 추천 저장본 그대로 · 잠금 · 실패 되돌림) - 걷음 — 추천 모달(_Recommend · _Help · _Map · CSS) · 좌측 「노선 추천」 칸 · saveRecommendedRoute · UI_RouteReset(서버 as_initial 길 · 시험은 남김) - 부품 상자 — createPickMenu(아이콘 고르기 메뉴 · 판 = body fixed · ✓) - 낡은 시험 고침 · 지움 — 모달 · 좌측 칸 · [적용] 화면 배선을 보던 시험(283 · 346_3 · 349 · 364_4 · 383_1 · 390_5 · 418 · 421 · 421_2 · 476_2 · 509_2 · 509_5 · 551_2 · 600_3 · b05_routeedit_initial · design_view_parity · modal_top · 133_1 · 133_2) · test_508_2 · helper_283 지움(모달 전용) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
123 lines
5.1 KiB
Python
123 lines
5.1 KiB
Python
"""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 "createPickMenu({" in src and 'offLabel: "끔"' in src
|
|
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
|