Files
Aislo/resources/tester/test_m02_structure.py
T
eomsangdonandClaude Opus 5.5 cd824aca25 feat(spreadsheet): F 서버 재계산 · 산출근거 따로 저장 · M02 끼우기 · 금빛 시험
- common_util_spreadsheet_node.ts · common_util_spreadsheet.py · build:spreadsheet — [저장] 때 화면과 같은 TS 엔진을 Node 로 돌려 계산값 정본(브라우저 값 버림 · 못 풀면 503)
- M02 새 종류 basis — resources/master_template/basis/<열 id>.json(구조물집계표 열마다) · 층 복사 · 뼈대 검사 · 옛 구조물 문서 산출근거 49 벌 옮김(migrate_basis) · 새 열도 같이 만듦
- 상세 산출근거 카드 = 새 스프레드시트(import() 로 늦게 받음) · basis 읽기 · 저장
- ⚠ 임시 [스프레드시트 시험] 단추 — 빈 통합문서(시트 셋) · 저장 자리 tmp/spreadsheet_trial.json · 1단계 검증 뒤 지움
- 시험 resources/tester/spreadsheet/ — 저장 · 서버 다리 · 크기 예산 · M02 만 늦게 불러옴 · 실무 구조도 xlsx 세 벌 수식 2,699 칸 엑셀 캐시값 대조(엔진 빈 몸이면 건너뜀)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168FQuoV7vDh5nhnSowW5cp
2026-09-27 20:12:39 +09:00

93 lines
4.2 KiB
Python

"""M02 구조물 도면(structure) — 새로 · 도번 자동 · 409 · 저장 · 지운 뒤 번호 · 프로젝트 복사.
산출근거는 따로 파일(basis) — `resources/tester/spreadsheet/test_spreadsheet_store.py`."""
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")
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["도면"] == {"format": 6, "entities": []}
# 산출근거는 구조물 문서 밖 — 같은 열 id 로 따로 한 통합문서
assert "산출근거" not in doc
assert client.get("/api/m02/templates/basis/pp_len").json()["문서"]["종류"] == "통합문서"
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["도면"]["entities"] = [{"type": "line"}]
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, "도면": {"entities": "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})