# -*- coding: utf-8 -*- """B05/B06 좌측 패널 「집계 항목」 회귀검증 — PLAN 21-4 (2026-09-29). 폼 옵션 보이기(`visible`) · [수정] 옵션 보존(안 그린 칸 · 상세 칸) · 집계 항목 줄(이름 · 고르기 · 해제) · 관 계열 merge · 목록 줄 색(`.is-assigned`) + 툴팁을 본다. 화면 그릇은 Node 헬퍼가 흉내낸다(`helper_b05_structures_form_summary.cjs` — TS 를 그 자리에서 트랜스파일). 실제 화면 조작은 ORCA(자체 확인)로 따로 본다. """ import json import os import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) A_KEY = "SS000007" @pytest.fixture(scope="module") def out(): proc = subprocess.run( ["node", os.path.join(HERE, "helper_b05_structures_form_summary.cjs")], capture_output=True, text=True, timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_visible_false_만_숨김(out): assert out["visible"] == [True, True, False] def test_visible_false_옵션은_폼에_안_그림_정의는_그대로(out): assert out["drawB05"] == { "keys": ["height_m"], "hidden": False, } # 길이 숨김 · 상세는 B05 에 없음 assert out["drawB06"]["keys"] == ["height_m", "stone_kind"] # B06 은 상세까지 · 숨김은 여기도 assert out["definitionKept"] == ["height_m", "length_m", "stone_kind", "back_len_cm"] def test_수정은_안_그린_칸을_보존(out): # 폼이 그린 H · stone_kind 는 갈아 끼우고, 안 그린 상세 칸 · 숨긴 칸은 옛 값 그대로 assert out["mergeSame"] == {"back_length_m": 0.6, "memo_only": "x", "H": 3} def test_그린_칸을_비우면_지워짐(out): assert out["mergeCleared"] == {"back_length_m": 0.6, "memo_only": "x"} def test_종류를_바꾸면_통째로_새_값(out): assert out["mergeTypeChange"] == {"H": 1} assert out["mergeNoPrev"] == {"H": 9} assert out["mergePrevNoOptions"] == {"H": 9} def test_참조_모양_검사(out): assert out["isItem"] == [True, False, False, False] assert out["readItem"] == [A_KEY, None] assert out["same"] == [True, False, True, False] # 이름만 바뀌면 같음 def test_키는_앞에_안_내세움_툴팁에만(out): assert out["label"] == ["미지정", "돌기슭막이 메쌓기 1.2m"] assert A_KEY not in out["label"][1] assert A_KEY in out["tip"][1] and "개인용" in out["tip"][1] assert out["rowSet"]["nameShowsKey"] is False def test_집계_항목_줄(out): empty = out["rowEmpty"] assert (empty["name"], empty["assigned"], empty["clearDisabled"], empty["get"]) == ( "미지정", False, True, None, ) assert (empty["label"], empty["pick"], empty["clear"]) == ("집계 항목", "고르기", "해제") row = out["rowSet"] assert row["assigned"] is True and row["clearDisabled"] is False assert row["name"] == "돌기슭막이 메쌓기 1.2m" and A_KEY in row["title"] assert out["clicks"] == ["pick", "clear"] assert out["rowCleared"] == {"name": "미지정", "clearDisabled": True} def test_관_계열_merge_가_집계_항목을_잇고_지움(out): assert out["pipeKeep"]["key"] == A_KEY # 다음 값에 칸이 없으면 옛 지정을 이음 assert out["pipeClear"] is None # 폼이 null 을 보내면 해제 assert out["pipeSet"] == "SS000004" # 다른 항목으로 바꿈 def test_목록_줄_색과_툴팁(out): rows = out["list"] # 측점 순: 구조물(지정) · 구조물(미지정) · 관(지정) · 관(미지정) assert [r["assigned"] for r in rows] == [True, False, True, False] assert A_KEY in rows[0]["title"] and "SS000004" in rows[2]["title"] assert rows[1]["title"] == "" and rows[3]["title"] == "" # 미지정은 지금 그대로 def test_저장_기록에_집계_항목이_실리고_해제하면_칸이_빠짐(out): # 새 구조물(미지정) — 칸을 아예 안 실음(서버가 모르는 칸을 거절하는 동안에도 저장이 안 깨짐) assert out["commitNew"] == {"hasKey": False, "options": {"H": 3}} # 지정돼 있던 것을 해제 — 옛 지정이 살아오지 않음 · 안 그린 칸은 보존 assert out["commitCleared"]["hasKey"] is False assert out["commitCleared"]["options"] == {"hidden_cost_key": "keep", "detail_only": 9, "H": 3} # 지정 유지 · 바꿈 assert out["commitKept"] == { "key": A_KEY, "options": {"hidden_cost_key": "keep", "detail_only": 9, "H": 3}, } assert out["commitSwapped"] == "SS000004"