"""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