Files
Pier_v1/Code/교각모델링앱/tools/test_templates.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

68 lines
4.2 KiB
Python

"""Protected template test (2026-10-13): save / list / create from template / protection. No Rhino.
Uses its own data root 검증/template_test_data (recreated) with copies of the two real templates."""
import json
import os
import shutil
import sys
from pathlib import Path
APP = Path(__file__).resolve().parents[1]
TD = APP / "검증" / "template_test_data"
if TD.exists():
shutil.rmtree(TD)
shutil.copytree(APP / "data" / "_템플릿", TD / "_템플릿", ignore=shutil.ignore_patterns("_이전"))
shutil.copytree(APP / "data" / "운곡교P1", TD / "원본", ignore=shutil.ignore_patterns("runs", "backup", "drawings"))
os.environ["PIERAPP_DATA"] = str(TD)
sys.path.insert(0, str(APP / "web"))
import app as webapp # noqa: E402
import store # noqa: E402
ok = True
def check(name, cond, detail=""):
global ok
ok &= bool(cond)
print("PASS" if cond else "FAIL", name, str(detail)[:200], flush=True)
c = webapp.app.test_client()
names = [t["name"] for t in store.templates()]
# 2026-10-13: + Ramp-A교P1형 (third form)
check("templates listed", names == ["Ramp-A교P1형", "산외교울산P1형", "산외교울산P2형", "새재1교P1형", "옥성교P1형", "운곡교P1형"], names) # + 옥성교P1형 2026-10-14, + 산외교울산P2형 2026-10-15
check("templates are not piers", store.piers() == ["원본"], store.piers())
h = c.get("/").get_data(as_text=True)
check("index shows protected group and table", 'label="보호 템플릿"' in h and 'value="tpl:산외교울산P1형"' in h
and "직접기초(말뚝 없음)" in h and 'label="기존 교각 복사"' in h)
r = c.post("/pier/new", data={"name": "울산형새교각", "type": "T형", "template": "tpl:산외교울산P1형"}, follow_redirects=True)
d = TD / "울산형새교각"
same = all((d / f).read_bytes() == (TD / "_템플릿" / "산외교울산P1형" / f).read_bytes() for f in ("params.json", "expected.json"))
info = json.loads((d / "pier.json").read_text(encoding="utf-8"))
check("pier from protected template", r.status_code == 200 and same and info["template"] == "템플릿: 산외교울산P1형", info)
p = store.Pier("울산형새교각")
check("new pier has the Ulsan scope and needs confirmation", p.scope() == ["G1", "G2", "G3", "G4", "G5"]
and webapp.unconfirmed(p), len(webapp.unconfirmed(p)))
check("pier page renders", c.get("/pier/울산형새교각").status_code == 200)
# editing / deleting the new pier leaves the template unchanged
p.set_section("params", "pier_id", "변경")
before = (TD / "_템플릿" / "산외교울산P1형" / "params.json").read_bytes()
c.post("/pier/울산형새교각/delete", data={"confirm_name": "울산형새교각"})
check("template unchanged after edit + delete", (TD / "_템플릿" / "산외교울산P1형" / "params.json").read_bytes() == before
and json.loads(before)["pier_id"] == "P1")
# copy of an existing pier still works (plain name)
r = c.post("/pier/new", data={"name": "복사본", "type": "T형", "template": "원본"}, follow_redirects=True)
check("copy of an existing pier", (TD / "복사본" / "params.json").exists()
and json.loads((TD / "복사본" / "pier.json").read_text(encoding="utf-8"))["template"] == "원본")
# refusals
r = c.post("/pier/new", data={"name": "_템플릿", "type": "T형", "template": "원본"}, follow_redirects=True)
check("reserved name refused", "앱이 쓰는 폴더 이름" in r.get_data(as_text=True) and not (TD / "_템플릿" / "pier.json").exists())
r = c.post("/pier/new", data={"name": "없는템플릿", "type": "T형", "template": "tpl:없음"}, follow_redirects=True)
check("missing template refused", "템플릿이 없습니다" in r.get_data(as_text=True) and not (TD / "없는템플릿").exists())
check("template folder cannot be deleted as a pier", c.post("/pier/_템플릿/delete", data={"confirm_name": "_템플릿"}).status_code == 404)
# re-save keeps the old snapshot
store.save_template("원본", "운곡교P1형", "재저장 시험")
old = list((TD / "_템플릿" / "_이전").glob("운곡교P1형_*"))
check("re-save keeps old snapshot, _이전 not listed", len(old) == 1 and [t["name"] for t in store.templates()] == names,
[t["name"] for t in store.templates()])
sys.exit(0 if ok else 1)