"""M02 구조물 도면(structure) — 새로 · 도번 자동 · 409 · 저장 · 지운 뒤 번호 · 프로젝트 복사.""" import shutil import pytest from fastapi import FastAPI from fastapi.testclient import TestClient from M02_MasterTemplete import M02_MasterTemplete_Store as store from M02_MasterTemplete import M02_Template_Layers as layers from M02_MasterTemplete.M02_MasterTemplete_Router import router REAL = store.FOLDER @pytest.fixture() def client(tmp_path, monkeypatch): for kind in store.KINDS: (tmp_path / kind).mkdir() shutil.copy(REAL / "table/구조물집계표.json", tmp_path / "table") shutil.copy(REAL / "drawing/00_template_A1.json", tmp_path / "drawing") monkeypatch.setattr(store, "FOLDER", tmp_path) app = FastAPI() app.include_router(router) return TestClient(app) def test_새로_도번_자동_409_없는_열(client): made = client.post("/api/m02/structures/pp_len") assert made.status_code == 200 doc = made.json()["문서"] assert (doc["양식"], doc["종류"], doc["열"], doc["도번"]) == ( "구조물도면", "structure", "pp_len", "구-01", ) assert ( doc["도면"]["entities"] and doc["도면"] == store.read("drawing", "00_template_A1")["문서"] ) basis = doc["산출근거"] assert [c["머리"][0] for c in basis["열"]] == ["공종", "규격", "산출 내역", "단위", "수량(m당)"] assert basis["줄"] == [] and basis["종류"] == "표" assert client.post("/api/m02/structures/rv").json()["문서"]["도번"] == "구-02" assert client.post("/api/m02/structures/pp_len").status_code == 409 assert client.post("/api/m02/structures/없는열").status_code == 404 assert client.get("/api/m02/structures/numbers").json() == {"pp_len": "구-01", "rv": "구-02"} rows = client.get("/api/m02/templates").json() assert {(r["종류"], r["이름"]) for r in rows if r["종류"] == "structure"} == { ("structure", "pp_len"), ("structure", "rv"), } def test_저장_뼈대_거름(client): got = client.post("/api/m02/structures/pp_len").json() doc = got["문서"] doc["산출근거"]["줄"] = [{"id": "r1", "값": {"work": "관 부설"}}] saved = client.put("/api/m02/templates/structure/pp_len", json={"판": got["판"], "문서": doc}) assert saved.status_code == 200 and saved.json()["판"] != got["판"] for bad in ({}, {**doc, "도면": {}}, {**doc, "산출근거": {"열": "x"}}, {**doc, "도면": []}): r = client.put( "/api/m02/templates/structure/pp_len", json={"판": saved.json()["판"], "문서": bad} ) assert r.status_code == 400 assert client.get("/api/m02/templates/structure/pp_len").json()["문서"] == doc def test_지워도_번호를_당기지_않음(client): for column in ("pp_len", "rv", "ms"): client.post(f"/api/m02/structures/{column}") assert client.delete("/api/m02/templates/structure/pp_len").status_code == 200 assert client.get("/api/m02/structures/numbers").json() == {"rv": "구-02", "ms": "구-03"} assert client.post("/api/m02/structures/fb").json()["문서"]["도번"] == "구-04" # 가장 큰 번호를 지우면 그 번호부터 다시(있는 것 중 가장 큰 번호 + 1) client.delete("/api/m02/templates/structure/fb") assert client.post("/api/m02/structures/ec").json()["문서"]["도번"] == "구-04" def test_프로젝트_복사와_층_저장에_실림(client, tmp_path, monkeypatch): doc = client.post("/api/m02/structures/pp_len").json()["문서"] monkeypatch.setattr(layers, "SYSTEM_ROOT", tmp_path) project = tmp_path / "project" copied = layers.seed_project(project) assert "structure/pp_len" in copied["작업본"] and "structure/pp_len" in copied["초기"] work = layers.project_dir(project) assert layers.read_template(work, "structure", "pp_len")["문서"] == doc assert layers.read_template(layers.initial_dir(project), "structure", "pp_len")["문서"] == doc assert ("structure", "pp_len") in {(r["종류"], r["이름"]) for r in layers.list_templates(work)} layers.check_skeleton("structure", doc) with pytest.raises(ValueError): layers.check_skeleton("structure", {**doc, "산출근거": None})