- 옛 대피소 · 정차·작업장 · 차돌림곳 · 종단배수 6 · 계류사방 3(기슭막이 = pipe_points 정본 제외) = 12 건 - 저장 → 다시 열기 → 다시 저장 → 다시 열기 = 12 건 · 측점 · 옵션 같음 · 임시 storage - 랩탑_보조 7+5~8+0 대피소 = 52-7 화면 검증 seed 단계가 넣은 시험 건(memo 「52-7 옛 대피소」) · restore 단계가 원래 목록(6 건)으로 되돌림 = 데이터 잃음 아님 · 코드 원인 없음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""옛 종류 구조물 저장 왕복(PLAN 52-7c) — 저장 · 다시 열기 · 다시 저장 뒤에도 수 · 종류 그대로.
|
|
|
|
옛 대피소 · 정차·작업장 · 차돌림곳(52-7 고르기 목록 뺌) · 종단배수 · 계류사방(52-8 숨김) 모두.
|
|
임시 storage(tmp_path) · 라우터 PUT/GET.
|
|
"""
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
import B05_Profile.B05_Profile_Structures_Router as router_module
|
|
from B05_Profile.B05_Profile_Structures_Schema import structure_type_map
|
|
|
|
PROJECT_ID = "52700000-0000-0000-0000-00000000007c"
|
|
URL = f"/api/projects/{PROJECT_ID}/route/structures"
|
|
LEGACY = ("refuge", "work_yard", "turnaround")
|
|
|
|
|
|
def _client(tmp_path, monkeypatch):
|
|
async def project_root(project_id):
|
|
return str(tmp_path / "project")
|
|
|
|
async def invalidate(project_id):
|
|
return True
|
|
|
|
async def route_length(project_id):
|
|
return None
|
|
|
|
monkeypatch.setattr(router_module, "_project_root", project_root)
|
|
monkeypatch.setattr(router_module, "_invalidate_downstream", invalidate)
|
|
monkeypatch.setattr(router_module, "_route_length", route_length)
|
|
app = FastAPI()
|
|
app.include_router(router_module.router)
|
|
return TestClient(app)
|
|
|
|
|
|
def _record(type_, at):
|
|
options = {}
|
|
for o in type_.options:
|
|
if o.default not in (None, ""):
|
|
options[o.key] = o.default
|
|
elif o.required:
|
|
options[o.key] = o.choices[0] if o.choices else 1
|
|
record = {"type_id": type_.type_id, "placement": type_.placement, "options": options}
|
|
if type_.placement == "interval":
|
|
record.update(chainage_m=at, start_m=at, end_m=at + 10)
|
|
else:
|
|
record["chainage_m"] = at
|
|
return record
|
|
|
|
|
|
def _kinds(body):
|
|
return sorted((s["type_id"], s["chainage_m"]) for s in body["structures"])
|
|
|
|
|
|
def test_옛_종류_저장_왕복_수_그대로(tmp_path, monkeypatch):
|
|
types = structure_type_map()
|
|
ids = [*LEGACY, *(t for t, v in types.items() if v.group in ("B", "D") and not v.managed_by)]
|
|
assert len(ids) >= 3 + 6 + 3 # 기슭막이 = pipe_points 정본
|
|
records = [_record(types[t], 20.0 * (i + 1)) for i, t in enumerate(ids)]
|
|
client = _client(tmp_path, monkeypatch)
|
|
|
|
first = client.put(URL, json={"base_revision": 0, "structures": records})
|
|
assert first.status_code == 200, first.text
|
|
opened = client.get(URL).json()
|
|
assert len(opened["structures"]) == len(ids)
|
|
want = _kinds(opened)
|
|
assert sorted(t for t, _ in want) == sorted(ids)
|
|
|
|
# 다시 연 목록 그대로 저장 → 다시 열기
|
|
again = client.put(
|
|
URL, json={"base_revision": opened["revision"], "structures": opened["structures"]}
|
|
)
|
|
assert again.status_code == 200, again.text
|
|
reopened = client.get(URL).json()
|
|
assert _kinds(reopened) == want
|
|
by_id = {s["structure_id"]: s["options"] for s in opened["structures"]}
|
|
assert {s["structure_id"]: s["options"] for s in reopened["structures"]} == by_id
|