- 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>
124 lines
4.3 KiB
Python
124 lines
4.3 KiB
Python
"""418 초기화 정리(요구 254-3 · 253-6).
|
|
|
|
- 「노선 추천」 칸 [초기화] 없음 · 그 단추만 쓰던 길(편집기 handler · `initial_route`) 없음
|
|
- 좌측 아래 [초기화] — 저장 안 한 B08 · B09 초안 남김 · B05 · B06 초안만 지움(진짜 TS)
|
|
- 추천 [적용] → 고쳐 저장 → 아래 [초기화] = [적용]한 노선(진짜 `refresh_initial_snapshot`)
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import subprocess
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
|
|
from common_util.common_util_initial_snapshot import (
|
|
restore_snapshot_files,
|
|
save_initial_snapshot,
|
|
)
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HELPER = Path(__file__).with_name("helper_418_reset_drafts.cjs")
|
|
|
|
|
|
def _read(rel: str) -> str:
|
|
return (ROOT / rel).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_노선_추천_칸에_초기화_단추_없음():
|
|
# 626-1 — 「노선 추천」 칸 통째 걷음
|
|
assert not (ROOT / "B05_Profile/B05_Profile_UI_Panel_Recommend.ts").exists()
|
|
initial = _read("B05_Profile/B05_Profile_UI_RouteEdit_Initial.ts")
|
|
assert "resetButton" not in initial and "initialRouteSnapshot" not in initial
|
|
assert "initial_route" not in _read("B05_Profile/B05_Profile_Api_Replan.ts")
|
|
replan = _read("B05_Profile/B05_Profile_Router_Replan.py")
|
|
assert '"initial_route"' not in replan and "_initial_shape" not in replan
|
|
|
|
|
|
def test_아래_초기화는_B08_B09_초안_남김():
|
|
out = json.loads(
|
|
subprocess.run(
|
|
["node", str(HELPER)], capture_output=True, text=True, encoding="utf-8", check=True
|
|
).stdout
|
|
)
|
|
seed, left = out["seed"], out["left"]
|
|
for name in ("b08-materials", "b08-hydro", "b08-options", "b08-milestone", "b09-estimation"):
|
|
assert left[name] == seed[name], name
|
|
# B05 · B06 초안(프로젝트 범위 · 노선 범위)은 지움
|
|
assert left["route-draft"] is None and left["std-cross"] is None
|
|
assert left["crossdesign"] is None
|
|
# 다른 프로젝트 초안은 안 건드림
|
|
assert out["other"] == seed
|
|
assert [c[0] for c in out["calls"]] == ["resetRouteDesign", "toast", "reload"]
|
|
|
|
|
|
class _Cursor:
|
|
def __init__(self):
|
|
self.lastrowid = 0
|
|
self._rows = []
|
|
|
|
async def __aenter__(self):
|
|
return self
|
|
|
|
async def __aexit__(self, *_):
|
|
return False
|
|
|
|
async def execute(self, sql, params=None):
|
|
self._rows = [{"id": 7, "project_id": "p1"}] if "FROM routes" in sql else []
|
|
|
|
async def fetchone(self):
|
|
return self._rows[0] if self._rows else None
|
|
|
|
async def fetchall(self):
|
|
return self._rows
|
|
|
|
|
|
class _Connection:
|
|
def cursor(self, *_args, **_kwargs):
|
|
return _Cursor()
|
|
|
|
|
|
class _Pool:
|
|
@asynccontextmanager
|
|
async def acquire(self):
|
|
yield _Connection()
|
|
|
|
|
|
@pytest.fixture
|
|
def project(tmp_path: Path) -> Path:
|
|
(tmp_path / "B05_Profile/route").mkdir(parents=True)
|
|
return tmp_path
|
|
|
|
|
|
def _write_route(root: Path, tag: str) -> None:
|
|
(root / "B05_Profile/route/planned_route.csv").write_text(f"x,y\n{tag}\n", encoding="utf-8")
|
|
|
|
|
|
def _route(root: Path) -> str:
|
|
return (root / "B05_Profile/route/planned_route.csv").read_text(encoding="utf-8")
|
|
|
|
|
|
def test_추천_적용_뒤_고쳐도_아래_초기화는_적용_노선(project, monkeypatch):
|
|
from B05_Profile import B05_Profile_Router_RouteInitial as initial_router
|
|
|
|
monkeypatch.setattr(initial_router, "get_db_pool", lambda: _Pool())
|
|
# ① 자동설계 체인 직후 초기값
|
|
_write_route(project, "auto")
|
|
asyncio.run(save_initial_snapshot(_Connection(), project, 7))
|
|
# ② 추천 [적용](as_initial) — 그 노선으로 초기값 다시 뜸
|
|
_write_route(project, "applied")
|
|
asyncio.run(initial_router.refresh_initial_snapshot(uuid4(), project, 7))
|
|
# ③ 손으로 고쳐 [저장] — 초기값 그대로(as_initial 아님 · 스냅샷 안 부름)
|
|
_write_route(project, "edited")
|
|
# ④ 아래 [초기화] = 초기값 파일 복원
|
|
restore_snapshot_files(project)
|
|
assert _route(project) == "x,y\napplied\n"
|
|
# ⑤ 다른 추천으로 바꿔 [적용] → 그것이 새 초기화 자리
|
|
_write_route(project, "applied2")
|
|
asyncio.run(initial_router.refresh_initial_snapshot(uuid4(), project, 7))
|
|
_write_route(project, "edited2")
|
|
restore_snapshot_files(project)
|
|
assert _route(project) == "x,y\napplied2\n"
|