Files
Aislo/resources/tester/test_b06_save_fills_empty_design.py
T
eomsangdonandClaude Opus 5.5 857b2d89d4 fix(445 B06 저장 patch): 바탕 = 캐시 설계 사용자 칸 + 세션 얹음 · 되돌림 null · 옮긴 측점 입력 · 집수정 범위 · 버린 수
- H3 — 횡단 patch 바탕을 캐시 설계 사용자 칸(측점마다 통째)으로 · 세션 고침은 벽 · 단 · 쪽 열쇠마다 합침(mergeCrossPatches)
- M2 — 벽 ↺ · 연동 풂 = 세션 null(안쪽 열쇠 지움) · 추가 벽 0 · 빈 전체 폭 0 을 세션에 남김 · 새 탭 − 가 저장분 단 수에서 출발
- H2 — 옮긴 관 · 구조물(정본 행 없음) = 지반 등 입력(CARRY_INPUT_KEYS)까지 실음 · 화면도 들고 감 · 서버 기본 설계가 그 입력으로 섬
- H5 — 노선 바꾼 [저장] 본문에 카드 선택 · 암선 · 암 경사 · 표준 횡단면 · 풍선 자리
- M1 — 집수정 내공 화면 범위 = 서버 1.0~2.0
- M5 — /save · /confirm 응답에 버린 patch 측점 · 기본 설계 실패 · 측점 맞춤 실패 · 화면 알림
- M7 — kindreset 을 측점 옮김 · 노선 저장에 따라 옮김
- 시험 test_445_save_patch · 기존 시험 꼴 맞춤(318 · 384 · 428 · 429 · fills_empty)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013QyNXY2TUKXCFMwAca2APG
2026-10-18 18:55:25 +09:00

121 lines
4.4 KiB
Python

"""[저장]이 「행은 있는데 설계가 빈 측점」을 채우는지 (2026-09-09).
재생성이 `cross_sections` 행을 지우고 다시 쓰면 `data.design` 에 면적 4키만 남는다.
`get_cross_section_designs` 는 `ground_type` 있는 줄만 담으므로 그 상태는 「설계 없음」이고,
B08 토적표가 통째로 0 이 됐다(창 셋에서 같은 증상). 예전에는 체인이 뒤이어 부르는 [확정]이
그 자리를 채워 가려져 있었다.
⚠ **값이 있는 행은 안 건드린다**가 이 시험의 핵심이다 — 사용자 조작값·이월분이 거기 있다.
"""
from __future__ import annotations
import asyncio
import sys
from pathlib import Path
from typing import Any
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
import B06_Section.B06_Section_Router_Confirm as confirm # noqa: E402
class _Conn:
async def begin(self) -> None:
return None
async def commit(self) -> None:
return None
async def rollback(self) -> None:
return None
class _Acquire:
async def __aenter__(self) -> _Conn:
return _Conn()
async def __aexit__(self, *_: Any) -> None:
return None
class _Pool:
def acquire(self) -> _Acquire:
return _Acquire()
def _async(value: Any):
async def _inner(*_: Any, **__: Any) -> Any:
return value
return _inner
def _run_save(monkeypatch: pytest.MonkeyPatch, missing: list[float]) -> list[float]:
"""`save_sections` 를 돌리고 **기본 설계를 계산하라고 넘긴 측점 목록**을 돌려준다."""
seen: list[float] = []
monkeypatch.setattr(confirm, "get_db_pool", lambda: _Pool())
monkeypatch.setattr(
confirm, "get_longitudinal_section", _async({"longitudinal_file_path": "long.json"})
)
monkeypatch.setattr(confirm, "get_project_storage_relative_path", _async("1/3/proj"))
# 화면이 쥔 노선 = 최신 노선(옛 노선 저장 거절은 `test_76_stale_route_save`).
monkeypatch.setattr(confirm, "get_workflow_route_context", _async({"route_id": 184}))
monkeypatch.setattr(confirm, "get_cross_section_chainages", _async([0.0, 20.0, 40.0]))
monkeypatch.setattr(confirm, "get_cross_sections_missing_design_chainages", _async(missing))
monkeypatch.setattr(confirm, "resolve_stored_project_path", lambda _p: str(PROJECT_ROOT))
# 행 자체가 없는 측점은 이 시험의 관심사가 아니다 — 빈 목록으로 고정한다.
monkeypatch.setattr(confirm, "_rowless_station_chainages", lambda *_a, **_k: [])
def _spy(_root, _path, chainages, _standard, _carried=None):
seen.extend(chainages)
return [(value, {"ground_type": "soil"}) for value in chainages]
monkeypatch.setattr(confirm, "_compute_default_designs", _spy)
monkeypatch.setattr(confirm, "_apply_section_edits", _async(None))
monkeypatch.setattr(confirm, "_recompute_stored_designs", _async(True)) # 388-2 recomputed
from uuid import UUID
response = asyncio.run(
confirm.save_sections(
project_id=UUID("fa76c162-71c7-46e5-a95d-fb3930665a45"), route_id=184, request=None
)
)
assert getattr(response, "confirmed", None) is False, response
return seen
def test_설계가_빈_측점을_채운다(monkeypatch: pytest.MonkeyPatch) -> None:
seen = _run_save(monkeypatch, [20.0, 40.0])
assert sorted(seen) == [20.0, 40.0]
def test_값이_있는_행은_안_건드린다(monkeypatch: pytest.MonkeyPatch) -> None:
"""빈 측점이 없으면 기본 설계를 아예 계산하지 않는다 — 덮어쓸 일이 없다."""
seen = _run_save(monkeypatch, [])
assert seen == []
def test_빈_설계의_뜻이_ground_type_없음이다() -> None:
"""판정은 `get_cross_sections_missing_design_chainages` 한 곳에서만 한다."""
import inspect
from B06_Section.B06_Section_Repository import get_cross_sections_missing_design_chainages
source = inspect.getsource(get_cross_sections_missing_design_chainages)
assert 'design.get("ground_type")' in source
def test_저장도_확정과_같은_판정을_쓴다() -> None:
"""두 갈래가 같은 조회를 써야 「저장했는데 확정과 다르다」가 안 생긴다."""
import inspect
source = inspect.getsource(confirm.save_sections)
assert "get_cross_sections_missing_design_chainages" in source