Files
Aislo/resources/tester/test_529_3_plan_points.py
T

138 lines
4.7 KiB
Python

"""D02 기준 지정(PLAN 529-3 · 560-2) — 경위도 ↔ TM 변환 · 전체 두 점 정본 API · 옛 연도 행 접기
· 연도 잇기(D03 [저장]이 씀).
./venv/Scripts/python.exe -m pytest resources/tester/test_529_3_plan_points.py -q
"""
import json
import pytest
from fastapi import FastAPI, HTTPException
from fastapi.testclient import TestClient
from common_util.common_util_auth import require_company
from common_util.common_util_crs import lonlat_to_tm, tm_epsg_for_lon, tm_to_lonlat
from D02_PlanBase import D02_PlanBase_Router as router_mod
PID = "12953f5a-5ba1-42ad-a427-8ac857a58bc2"
URL = f"/api/projects/{PID}/plan/points"
# --- 좌표 변환 ---
@pytest.mark.parametrize("epsg, lon0", [(5185, 125.0), (5186, 127.0), (5187, 129.0)])
def test_origin_is_false_origin(epsg, lon0) -> None:
x, y = lonlat_to_tm(lon0, 38.0, epsg) # 원점 = (200 000, 600 000)
assert abs(x - 200000.0) < 0.001 and abs(y - 600000.0) < 0.001
@pytest.mark.parametrize("lon, lat", [(127.3851, 36.3504), (125.7, 34.1), (129.36, 36.02)])
def test_round_trip_within_1mm(lon, lat) -> None:
epsg = tm_epsg_for_lon(lon)
x, y = lonlat_to_tm(lon, lat, epsg)
back = lonlat_to_tm(*tm_to_lonlat(x, y, epsg), epsg)
assert abs(back[0] - x) < 0.001 and abs(back[1] - y) < 0.001
def test_belt_by_longitude() -> None:
assert [tm_epsg_for_lon(v) for v in (124.5, 125.999, 126.0, 127.999, 128.0, 131.8)] == [
5185,
5185,
5186,
5186,
5187,
5187,
]
# --- 지점 정본 API ---
A, B, C = (
{"lon": 127.10, "lat": 37.50},
{"lon": 127.12, "lat": 37.51},
{"lon": 127.15, "lat": 37.52},
)
@pytest.fixture
def api(monkeypatch):
state = {
"project": {"project_kind": "PLAN", "project_year": 2026, "project_year_end": 2027},
"rows": {},
"session": {"role": "USER", "email": "kim@forest.go.kr", "company_id": 1},
}
async def load(project_id):
return state["project"], {y: dict(r) for y, r in state["rows"].items()}
async def store_base(project_id, base):
state["project"] = {**state["project"], "plan_base_json": json.dumps(base)}
monkeypatch.setattr(router_mod, "_load", load)
monkeypatch.setattr(router_mod, "_store_base", store_base)
app = FastAPI()
app.include_router(router_mod.router)
app.dependency_overrides[require_company] = lambda: state["session"]
client = TestClient(app)
client.state = state
return client
def test_put_two_points(api) -> None:
got = api.put(URL, json={"start": A, "end": C})
assert got.status_code == 200
data = got.json()
assert data["epsg"] == 5186
assert (data["start"]["x"], data["start"]["y"]) == pytest.approx(
lonlat_to_tm(127.10, 37.50, 5186)
)
assert abs(data["end"]["lon"] - C["lon"]) < 1e-8 and abs(data["end"]["lat"] - C["lat"]) < 1e-8
stored = json.loads(api.state["project"]["plan_base_json"])
assert set(stored) == {"epsg", "start", "end"} and set(stored["start"]) == {"x", "y"}
assert api.state["rows"] == {} # 연도 행은 D02 가 안 만듦
def test_put_one_point_and_empty(api) -> None:
data = api.put(URL, json={"start": A}).json()
assert data["start"] and data["end"] is None and data["epsg"] == 5186
data = api.put(URL, json={}).json()
assert data == {"status": "success", "epsg": None, "start": None, "end": None}
def test_put_forest_only(api) -> None:
api.state["session"] = {"role": "USER", "email": "lee@company.com", "company_id": 1}
assert api.put(URL, json={"start": A, "end": B}).status_code == 403
api.state["session"] = {"role": "SYSTEM_ADMIN", "email": "admin@x.com", "company_id": None}
assert api.put(URL, json={"start": A, "end": B}).status_code == 200
def test_get_folds_old_year_rows(api) -> None:
epsg = 5186
a, b, c = (lonlat_to_tm(p["lon"], p["lat"], epsg) for p in (A, B, C))
for year, s, e in ((2026, a, b), (2027, b, c)):
api.state["rows"][year] = {
"year": year,
**{"start_x": s[0], "start_y": s[1], "end_x": e[0], "end_y": e[1]},
"epsg": epsg,
}
data = api.get(URL).json()
assert data["epsg"] == epsg
assert (data["start"]["x"], data["end"]["x"]) == pytest.approx((a[0], c[0]))
def test_get_empty_new_project(api) -> None:
assert api.get(URL).json() == {"status": "success", "epsg": None, "start": None, "end": None}
def test_chain_years_for_d03() -> None:
items = [
router_mod.YearPoints(year=2026, start=A, end=B),
router_mod.YearPoints(year=2027, start=A, end=C),
]
rows = router_mod.chain_years(2026, 2027, items)
assert rows[1]["start"].lon == B["lon"] # 시점 = 직전 종점
with pytest.raises(HTTPException):
router_mod.chain_years(2026, 2027, items[:1])