# -*- coding: utf-8 -*- """498-2 노선 바뀐 [저장] 계획고 — 브라우저는 손댐(입력)만 · 서버가 자기 옮김 위에 한 번. - 브라우저(`B05_Profile_Pipeline_Grade` follow `touch` · `gradeTouch`) — 노선만 끌었으면 손댐 0 · 끈 뒤 ▲ = 그 열쇠만 · 끄는 중 ▲ = 그 열쇠 포함 묶음 값 그대로 · 지운 열쇠 = `cleared` · 첫 기준 없으면 null(옛 길 · 0 칸 통째). - 서버(`B06_Section_Router_DesignSave_Route.overlay_edits` · `touched_alignment`) — 손대지 않은 옮김 열쇠는 서버 측점 그대로 · 고친 · 지운 열쇠 자리(0.006 m 안)만 걷고 손댐 값을 얹음 · 브라우저 측점 열쇠로 서버 열쇠를 덮지 않음(옛 흠 = 두 쪽 측점이 다르면 어긋난 편집을 지움). """ import asyncio import json import subprocess from pathlib import Path import pytest from B06_Section import B06_Section_Router_DesignSave_Route as moving HERE = Path(__file__).resolve().parent @pytest.fixture(scope="module") def ts() -> dict: proc = subprocess.run( ["node", str(HERE / "helper_498_2_grade_touch.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def _empty(touch: dict) -> bool: return not any(touch["edits"].values()) and not any(touch["cleared"].values()) def test_노선만_끌면_손댐_0(ts): assert ts["plain"]["now"]["station_offsets"], "옮긴 편집이 있어야 시험이 뜻을 가짐" assert _empty(ts["plain"]["touch"]) def test_끈_뒤_올림은_그_열쇠만(ts): touch = ts["lateBump"]["touch"] assert touch["edits"]["station_offsets"] == {"60.000": 0.3} assert not any(touch["cleared"].values()) def test_끄는_중_올림은_묶음_값_그대로(ts): now, touch = ts["midBump"]["now"], ts["midBump"]["touch"] assert touch["edits"]["station_offsets"]["40.000"] == pytest.approx(0.2) for key, value in touch["edits"]["station_offsets"].items(): assert now["station_offsets"][key] == value def test_지운_열쇠는_cleared(ts): touch = ts["removed"]["touch"] assert touch["cleared"]["station_offsets"] == ["200.000"] assert not any(touch["edits"].values()) def test_첫_기준_없으면_null_옛_길(ts): assert ts["noFirst"] is None def test_gradeTouch_순수(ts): assert ts["pure"] == { "edits": {"station_offsets": {"20.000": 2.5}, "curve_radii": {"30.000": 80}}, "cleared": {"station_offsets": ["40.000"], "curve_radii": []}, } def test_서버_옮김_위에_손댐만(): carried = { "station_offsets": {"960.000": 0.005, "970.000": 0.64, "980.000": 0.014}, "curve_radii": {"500.000": 120.0}, } touch = {"station_offsets": {"970.003": 0.7, "1000.000": 0.2}, "curve_radii": {}} cleared = moving.AlignmentCleared(station_offsets=["980.000"], curve_radii=["500.004"]) assert moving.overlay_edits(carried, touch, cleared) == { # 960 = 손 안 댐(서버 값) · 970 = 0.006 m 안 손댐이 갈음 · 980 지움 · 1000 새 손댐 "station_offsets": {"960.000": 0.005, "970.003": 0.7, "1000.000": 0.2}, "curve_radii": {}, } def test_손댐_0이면_서버_옮김_그대로(): carried = {"station_offsets": {"960.000": 0.005, "970.000": 0.64}, "curve_radii": {}} out = moving.overlay_edits(carried, {}, moving.AlignmentCleared()) assert out == {"station_offsets": carried["station_offsets"], "curve_radii": {}} def test_계획고_본문은_새_종단_편집에서(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): from B03_FileInput import B03_FileInput_Repository as files from B05_Profile.B05_Profile_Schema import ProfileAlignmentSaveRequest from B06_Section import B06_Section_Repository as repo from common_util import common_util_storage as storage from config import config_db (tmp_path / "long.json").write_text( json.dumps({"profile_alignment": {"edits": {"station_offsets": {"970.000": 0.64}}}}), encoding="utf-8", ) class Pool: def acquire(self): return self async def __aenter__(self): return None async def __aexit__(self, *_): return False async def longitudinal(_connection, _project, route_id): assert route_id == 820, "새 노선 번호로 읽어야 함" return {"longitudinal_file_path": "long.json"} async def stored(_connection, _project): return "p" monkeypatch.setattr(config_db, "get_db_pool", lambda: Pool()) monkeypatch.setattr(repo, "get_longitudinal_section", longitudinal) monkeypatch.setattr(files, "get_project_storage_relative_path", stored) monkeypatch.setattr(storage, "resolve_stored_project_path", lambda _p: str(tmp_path)) touch = ProfileAlignmentSaveRequest(route_id=819, station_offsets={"1000.000": 0.2}) body = asyncio.run(moving.touched_alignment("pid", 820, touch, moving.AlignmentCleared())) assert body.route_id == 820 assert body.station_offsets == {"970.000": 0.64, "1000.000": 0.2}