Files
Aislo/resources/tester/test_349_section_detail_inner.py
T
eomsangdonandClaude Opus 5.5 b8b4421ff0 fix(349): 횡단 상세 안쪽 호출 길 복구 — GET 처리기만 ETag · 조립 함수는 request 없이
343-2 ETag 가 get_section_detail 에 request 인자를 더해 [저장] 뒤 서버 재계산 · 3D 길 모형 서버
짓기 · B09 인쇄 도면 · B07 덧그림 범위가 TypeError 로 끊기던 흠. 처리기 = get_section_detail_route
(ETag · 304) · get_section_detail = 조립만(안쪽 호출 넷 그대로). 진짜 처리 길 시험 test_349.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
2026-10-16 13:21:55 +09:00

113 lines
4.3 KiB
Python

# -*- coding: utf-8 -*-
"""349 — 안쪽 호출이 진짜 `get_section_detail` 길로 종횡단 상세를 받는지(요구 231 · 232 흠).
343-2 ETag 가 GET 처리기에 `request` 를 더해 안쪽 호출([저장] 뒤 서버 재계산 · 3D 길 모형 서버
짓기 · B09 인쇄 도면)이 TypeError 로 끊겼음. 이 시험은 `get_section_detail` 을 갈음하지 않고 그 아래
DB · 파일 읽기만 가짜로 둠 — 안쪽 함수 모양이 다시 바뀌면 빨강.
"""
from __future__ import annotations
import asyncio
import copy
import sys
from pathlib import Path
from types import SimpleNamespace
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 B05_Profile.B05_Profile_Corridor_Prebuild as corridor # noqa: E402
import B06_Section.B06_Section_Router as b06_router # noqa: E402
import B06_Section.B06_Section_Router_Design as b06_design # noqa: E402
import B06_Section.B06_Section_Server_Calc_Prebuild as prebuild # noqa: E402
from B09_Estimation.draft.B09_Draft_Print_Drawings_Source import section_detail # noqa: E402
DETAIL = {
"longitudinal": {"length_m": 40.0, "stations": [{"chainage_m": 0.0}]},
"cross_sections": [
{"chainage_m": 0.0, "design": {"ground_type": "soil"}},
{"chainage_m": 20.0, "design": {"ground_type": "rock"}},
],
}
class _Stop(Exception):
"""상세를 받은 뒤 서버 재계산을 멈춤 — 그 뒤 길은 342-2 시험 몫."""
@pytest.fixture
def real_detail(monkeypatch, tmp_path):
"""`get_section_detail` 아래 읽기만 가짜 — 처리 함수 자체는 진짜."""
async def run_with(fn, *args):
if fn is b06_router.get_longitudinal_section:
return {"longitudinal_file_path": "longitudinal.json", "data": None}
if fn is b06_router.get_project_storage_relative_path:
return "p"
return [] # 횡단 설계 행
monkeypatch.setattr(b06_router, "run_with_connection", run_with)
monkeypatch.setattr(b06_router, "resolve_stored_project_path", lambda path: str(tmp_path))
monkeypatch.setattr(b06_router, "_read_section_detail", lambda *a: copy.deepcopy(DETAIL))
monkeypatch.setattr(b06_router, "_attach_default_designs", lambda *a: None)
return tmp_path
def test_corridor_prebuild_reads_detail(real_detail) -> None:
detail = asyncio.run(corridor._section_detail(uuid4(), 3))
assert detail is not None
assert [row["chainage_m"] for row in detail["cross_sections"]] == [0.0, 20.0]
def test_server_recompute_reads_detail(real_detail, monkeypatch) -> None:
seen: list = []
async def run_with(fn, *args):
if fn is prebuild.get_project_storage_relative_path:
return "p"
return {}
async def haul_inputs(project_id):
return {}
def enforce(longitudinal, sections, *rest):
seen.append(copy.deepcopy(sections))
raise _Stop
monkeypatch.setattr(prebuild, "run_with_connection", run_with)
monkeypatch.setattr(prebuild, "haul_inputs_for", haul_inputs)
monkeypatch.setattr(prebuild, "resolve_stored_project_path", lambda path: str(real_detail))
monkeypatch.setattr(prebuild, "get_db_pool", lambda: None)
monkeypatch.setattr(b06_design, "stored_standard_cross_section", lambda row: None)
monkeypatch.setattr(b06_design, "enforce_design_lines", enforce)
with pytest.raises(_Stop):
asyncio.run(prebuild.recompute_server_side(uuid4(), 3))
assert [row["chainage_m"] for row in seen[0]] == [0.0, 20.0]
def test_print_drawings_reads_detail(real_detail) -> None:
detail = asyncio.run(section_detail(uuid4(), 3))
assert detail is not None and len(detail["cross_sections"]) == 2
def test_route_handler_keeps_etag(real_detail) -> None:
def request(tag):
return SimpleNamespace(headers={"if-none-match": tag} if tag else {})
handler = next(
route.endpoint
for route in b06_router.router.routes
if getattr(route, "path", "").endswith("/sections/{route_id}/detail")
and "GET" in route.methods
)
first = asyncio.run(handler(uuid4(), 3, request(None)))
etag = first.headers["ETag"]
assert first.status_code == 200 and b"cross_sections" in first.body
assert asyncio.run(handler(uuid4(), 3, request(etag))).status_code == 304