- 서버 GET /api/m02/structure-frame — B07 시스템 양식 00_template_A1 을 frame_entities(fit=False)로 1:1 배치 · 외곽 좌하단 (0,0) 으로 옮김 · 잠금 층 m02-structure-frame「도각(보기)」(마스터 양식 json 그대로) - 화면 mountDrawingTemplate frame 갈래 — 실을 때 도각 엔티티 · 층 덧붙임 · getDoc 에서 그 층 통째로 뺌(구조물 엔티티 · 저장 본문에 안 섞임) - 층 없는 빈 구조물 문서는 기본 층을 채움 — 잠금 도각 층만 남아 새 그림이 도각 층에 떨어지는 것 막음 - 불러온 DXF 층(b08-frame)과 층 id 갈라 둠 - 시험 test_m02_router_drawing 도각 원점 · 층 · 원본 양식 불변 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
"""M02 도면 양식 서버 길 — 자리표 키 목록 · 도각 파일 불러오기 (PLAN 10-3)."""
|
|
|
|
import io
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
from M02_MasterTemplete.M02_MasterTemplete_Router_Drawing import DRAWING_FIELDS, router
|
|
|
|
app = FastAPI()
|
|
app.include_router(router)
|
|
client = TestClient(app)
|
|
|
|
|
|
def test_fields_cover_system_placeholders():
|
|
# 시스템 도면 양식에 박힌 자리표는 전부 키 목록에 있다 — 없으면 화면이 모르는 칸이 생긴다.
|
|
keys = {key for key, _, _ in DRAWING_FIELDS}
|
|
used = set()
|
|
for path in Path("resources/master_template/drawing").glob("00_*.json"):
|
|
text = json.dumps(json.loads(path.read_text(encoding="utf-8")), ensure_ascii=False)
|
|
used |= {match.strip() for match in re.findall(r"\{\{\s*([^}]+?)\s*\}\}", text)}
|
|
assert used and used <= keys, used - keys
|
|
|
|
|
|
def test_fields_without_project():
|
|
response = client.get("/api/m02/drawing-fields")
|
|
assert response.status_code == 200
|
|
body = response.json()
|
|
assert [item["key"] for item in body["fields"]] == [key for key, _, _ in DRAWING_FIELDS]
|
|
assert body["values"] == {}
|
|
|
|
|
|
def test_import_rejects_other_files():
|
|
response = client.post(
|
|
"/api/m02/drawing-import", files={"file": ("a.txt", b"hello", "text/plain")}
|
|
)
|
|
assert response.status_code == 400
|
|
assert "DXF" in response.json()["message"]
|
|
|
|
|
|
def test_import_dxf():
|
|
import ezdxf
|
|
|
|
document = ezdxf.new()
|
|
document.modelspace().add_line((0, 0), (100, 50))
|
|
stream = io.StringIO()
|
|
document.write(stream)
|
|
response = client.post(
|
|
"/api/m02/drawing-import",
|
|
files={"file": ("frame.dxf", stream.getvalue().encode("utf-8"), "application/dxf")},
|
|
)
|
|
assert response.status_code == 200, response.text
|
|
body = response.json()
|
|
assert body["entity_count"] == 1
|
|
assert body["drawing"]["entities"][0]["type"] == "Line"
|
|
|
|
|
|
def test_import_garbage_is_400_not_500():
|
|
for data in (b"garbage\x00\xff", b"", b"0\nSECTION\n2\nENTITIES\n0\nLINE\n10\nabc\n"):
|
|
response = client.post(
|
|
"/api/m02/drawing-import", files={"file": ("bad.dxf", data, "application/dxf")}
|
|
)
|
|
assert response.status_code == 400, (data, response.text)
|
|
assert response.json()["message"]
|
|
|
|
|
|
def test_structure_frame_origin_at_zero():
|
|
# 56장 — 구조물 도면에 얹는 도각: 외곽 좌하단 (0,0) · 잠금 도각 층 · 원본 양식은 그대로
|
|
from B07_DesignDetail.B07_DesignDetail_Engine_Template import entities_bbox, template_entities
|
|
|
|
before = entities_bbox(template_entities())
|
|
body = client.get("/api/m02/structure-frame").json()
|
|
x0, y0, x1, y1 = entities_bbox(body["entities"])
|
|
assert abs(x0) < 1e-9 and abs(y0) < 1e-9
|
|
assert abs((x1 - x0) - (before[2] - before[0])) < 1e-6
|
|
assert body["layer"]["isLocked"] is True
|
|
assert {e["layerId"] for e in body["entities"]} == {"m02-structure-frame"}
|
|
assert body["layer"]["id"] == "m02-structure-frame" # 불러온 DXF 층(b08-frame)과 갈림
|
|
assert entities_bbox(template_entities()) == before
|