"""STMATE 재현 앱 화면 저장 요청(view_prj_boq.js buildSavePayload) — 고치지 않으면 저장해도 한 칸도 안 바뀜. 옛 요청은 2차 칸을 1차로, 3차(계약) 칸을 고정 낙찰율로 덮었음 — 이제 바뀐 칸만 나감을 실무 STC 7건으로 확인. """ import json import subprocess import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT / "tools/stmate-test")) import server # noqa: E402 from stc_save import _leaf, apply_save # noqa: E402 HELPER = Path(__file__).with_name("helper_stmate_file_payload.cjs") STCS = sorted((ROOT / "resources/knowledge/original/실무문서").rglob("*.STC")) IDS = [p.stem[:16] for p in STCS] def _payload(load, edit=None): raw = json.dumps({"load": load, "edit": edit}, default=str).encode() return json.loads(subprocess.check_output(["node", str(HELPER)], input=raw)) @pytest.mark.parametrize("stc", STCS, ids=IDS) def test_screen_payload_without_edits_changes_nothing(stc): load = server.api_load(server.LoadReq(source_path=str(stc))) p = _payload(load) by = {r["_recno"]: r for r in load["boq_rows"]} for u in p["boq_updates"]: # 2·3차 단가는 불러온 값 그대로(1차 복사·고정 낙찰율 아님) for k in ("MAMT2", "LAMT2", "MAMT3", "LAMT3", "SAMT3"): if k in u and u.get("_recno") in by: assert float(u[k] or 0) == float(by[u["_recno"]][k] or 0) files = server.read_project_files(str(stc)) out, log = apply_save(files, p) assert log == [] and all(out[k] is files[k] for k in files) @pytest.mark.parametrize("stc", STCS, ids=IDS) def test_screen_qty_edit_touches_slot1_only(stc): load = server.api_load(server.LoadReq(source_path=str(stc))) leaf = next( r for r in load["boq_rows"] if _leaf(r["BDCODE1"].strip()) and float(r["TAMT1"] or 0) > 0 and not r["UNIT1"].strip().endswith("%") ) q = float(leaf["QTY1"]) + 3 p = _payload(load, {"recno": leaf["_recno"], "qty": q}) files = server.read_project_files(str(stc)) _out, log = apply_save(files, p) fields = {(x["table"], x["field"]) for x in log} assert ("BOQ11.DBF", "QTY1") in fields assert all(f[1][-1] == "1" or f[1].startswith("COSTW") for f in fields), fields assert {x["recno"] for x in log if x["field"] == "QTY1"} == {leaf["_recno"]}