- 까닭: 확정 모델 행이 stage 1 params 와 어긋나면(검증_sub1 확정 = sheet · params = classification) terrain-sources 의 grid = null → 브라우저는 미교차 넓힘을 못 하고 ±20 m 에서 멈춤 · 서버 표본기 · Node /calc 는 params 를 따라 넓힘 → 소단 밀린 측점 화면 ≠ 저장
- 고침: `_confirmed_model` → `_design_model` — params 의 `dtm_{filter}.npz` DTM 행(확정 행 먼저) · 표본 폭 상수는 그대로(통째 격자가 이미 최대)
- 횡단 카드: 격자 없는(DTM 아닌) 지형에서 사면 미교차 = 부품 배지 「지형 범위 밖」(값은 [저장] 때 서버)
- 시험: test_344_1_terrain_grid_route 에 어긋난 확정 행 지킴 · test_133_1 · test_505_2 바뀐 이름
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
3.7 KiB
Python
102 lines
3.7 KiB
Python
"""PLAN 505-2 5d — 수치지형도 sheet 고르기 = DB 모델 있을 때만 · 없으면 [확인] 409 사유 한 줄.
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_505_2_terrain_sheet.py -q
|
|
|
|
고르기 목록(`/route/terrain-sources`)은 npz 파일 + DB 완료 모델을 함께 봄 — 모델 없는 sheet 는 숨김
|
|
(화면은 고르기가 숨으면 분석 지형을 안 실음). 바꿈(`switch_design_terrain`)이 모델을 못 찾으면
|
|
`_recompute` 가 `{error}` → 노선 되돌리고 409(전엔 LookupError 가 저장 통째 되돌림).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import sys
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
import B04_PreProcess.B04_PreProcess_Service as service # noqa: E402
|
|
import B05_Profile.B05_Profile_Router_Replan as replan # noqa: E402
|
|
import B05_Profile.B05_Profile_Router_Terrain as terrain # noqa: E402
|
|
from common_util.common_util_surface_confirmation import SHEET_ANALYSIS_FILTER # noqa: E402
|
|
|
|
LAS = {"source_filter": "classification", "method": "dtm", "smooth": True}
|
|
|
|
|
|
class _Pool:
|
|
@asynccontextmanager
|
|
async def acquire(self):
|
|
yield _Connection()
|
|
|
|
|
|
class _Connection:
|
|
async def begin(self):
|
|
pass
|
|
|
|
async def rollback(self):
|
|
_Connection.rolled = True
|
|
|
|
async def commit(self):
|
|
raise AssertionError("모델 없으면 확정하지 않음")
|
|
|
|
|
|
def _async(value):
|
|
async def inner(*args, **kwargs):
|
|
return value
|
|
|
|
return inner
|
|
|
|
|
|
def _model(source_filter: str) -> dict:
|
|
return {
|
|
"id": 7,
|
|
"status": "COMPLETE",
|
|
"model_type": "DTM",
|
|
"generation_params": {"source_filter": source_filter},
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sources(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
|
|
models = tmp_path / terrain._MODELS_SUBDIR
|
|
models.mkdir(parents=True)
|
|
(models / f"dtm_{SHEET_ANALYSIS_FILTER}.npz").write_bytes(b"") # sheet 파일은 있음
|
|
monkeypatch.setattr(terrain, "get_db_pool", lambda: _Pool())
|
|
monkeypatch.setattr(terrain, "get_project_storage_relative_path", _async("p"))
|
|
monkeypatch.setattr(terrain, "get_surface_confirmation_params", _async(dict(LAS)))
|
|
monkeypatch.setattr(terrain, "_design_model", _async(None))
|
|
monkeypatch.setattr(terrain, "resolve_stored_project_path", lambda stored: tmp_path)
|
|
monkeypatch.setattr(terrain, "_design_grid", lambda *args: None)
|
|
|
|
def run(models_in_db: list[dict]) -> list[str]:
|
|
monkeypatch.setattr(service, "list_surface_models", _async(models_in_db))
|
|
return asyncio.run(terrain.read_terrain_sources(uuid4()))["sources"]
|
|
|
|
return run
|
|
|
|
|
|
def test_모델_없는_sheet_고르기_숨김(sources) -> None:
|
|
assert sources([_model("classification")]) == ["las"]
|
|
|
|
|
|
def test_모델_있는_sheet_고르기_보임(sources) -> None:
|
|
assert sources([_model(SHEET_ANALYSIS_FILTER)]) == ["las", "sheet"]
|
|
|
|
|
|
def test_모델_없으면_재계산_409_사유(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
import common_util.common_util_surface_confirmation as surface
|
|
|
|
_Connection.rolled = False
|
|
monkeypatch.setattr(replan, "get_db_pool", lambda: _Pool())
|
|
monkeypatch.setattr(service, "get_surface_confirmation_params", _async(dict(LAS)))
|
|
monkeypatch.setattr(service, "list_surface_models", _async([_model("classification")]))
|
|
monkeypatch.setattr(surface, "get_surface_confirmation_params", _async(dict(LAS)))
|
|
got = asyncio.run(replan._recompute(uuid4(), tmp_path, "p", terrain="sheet"))
|
|
assert got == {"error": replan.TERRAIN_MODEL_MISSING} and _Connection.rolled
|