"""「전국」 자재 줄(PLAN 361-2 · `M02_MasterTemplete_Labor_National`) — 사전조합 `본뜬.전국자재` 를 상세 자재목록 아래 보기 전용 표로(있으면 줄 · 없으면 안 보임 · 단추 없음 · 금액 칸 비움 · 글 명사형) · 읽기 길(사전조합 GET 의 `layers.read_template`)이 `본뜬.전국자재` 를 그대로 줌 · 확인 창 세 칸 = 만들기에 적힐 값(`세칸`). 층은 임시 폴더. """ import json import os import re import subprocess from pathlib import Path # 올리기 길 시험의 `client` 마당을 같이 씀 # ruff: noqa: F811 from resources.tester.test_m02_hopyo_build import _build from resources.tester.test_m02_hopyo_excel import URL, _post, client # noqa: F401 HERE = os.path.dirname(os.path.abspath(__file__)) M02 = Path(HERE).parents[1] / "M02_MasterTemplete" REMICON = { "이름": "레미콘(전국)-관급", "규격": "25-21-120", "단위": "㎥", "수량": {"손": 2.5}, "별도계상": "별도계상", "자재구분": "관급", } def _rows(origins: list) -> list: proc = subprocess.run( ["node", os.path.join(HERE, "helper_m02_labor_national.cjs")], input=json.dumps({"origins": origins}, ensure_ascii=False), capture_output=True, text=True, encoding="utf-8", check=False, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_전국_자재_줄_있는_것_없는_것(): have, plain, empty, none = _rows( [ {"층": "personal", "주인": "7/42", "키": "HP-000001 제1호표", "전국자재": [REMICON]}, {"층": "personal", "주인": "7/42", "키": "HP-000001 제3호표"}, {"층": "personal", "주인": None, "키": "k", "전국자재": []}, None, ] ) assert have["title"] == "전국 자재 — 지역은 프로젝트에서 · 금액 없음(보기만)" assert have["heads"] == [ "코드", "이름", "규격", "수량산출", "단위", "자재구분", "별도계상", "운반비", "반영 금액", ] assert have["rows"] == [ [ "전국", "레미콘(전국)-관급 지역은 프로젝트에서", "25-21-120", "2.5", "㎥", "관급", "별도계상", "포함", # 빈 칸 = 기본값 글 "—", # 금액 칸 비움 ] ] assert have["buttons"] == 0 # 고침 · 삭제 없음(보기만) assert plain["count"] == empty["count"] == none["count"] == 0 # 없으면 안 보임 def test_소스_보기만_명사형_자리(): code = (M02 / "M02_MasterTemplete_Labor_National.ts").read_text(encoding="utf-8") words = re.findall(r'"([^"]*[가-힣][^"]*)"', code) assert words and not [w for w in words if re.search(r"(합니다|해요|한다|하세요)", w)] assert "createButton" not in code and "fetch" not in code and "sessionStorage" not in code detail = (M02 / "M02_MasterTemplete_Labor_Detail.ts").read_text(encoding="utf-8") assert "...nationalRows(cur.본뜬)" in detail and len(detail.splitlines()) <= 700 api = (M02 / "M02_MasterTemplete_Labor_Api.ts").read_text(encoding="utf-8") assert "전국자재?: NationalMat[]" in api def test_만든_사전조합_읽기_길에_전국자재(client): from M02_MasterTemplete import M02_Template_Layers as layers assert _post(client).status_code == 200 got = _build(client, 1, [{"차례": 0, "대상": [{"전국": True, "배": 1}]}]) key = got["참조"]["키"] found = layers.read_template(layers.personal_dir(7, 42), "precombo", key) doc = found.get("문서") or found assert doc["본뜬"]["전국자재"][0] | {"수량": None} == REMICON | {"수량": None} assert doc["자재"] == [] # 자재 칸(M01 키만)엔 없음 — 셈 · 문서 꼴 그대로 def test_확인_창_세_칸_만들기_값(client): from M02_MasterTemplete import M02_Hopyo_Fit as fit from M02_MasterTemplete import M02_Template_Layers as layers assert _post(client).status_code == 200 fit.run_job(layers.personal_dir(7, 42), "HP-000001") lines = client.get(f"{URL.format('personal')}/HP-000001/1").json()["호표"]["줄"] at = next(x["차례"] for x in lines if x["이름"] == "레미콘(25-21-120)") mat = lines[at]["맞춤"]["대상"][0] assert mat["세칸"] == { "별도계상": "별도계상", "자재구분": "관급", } # 전국-관급 = 관급(옛 「사급」) path = f"{URL.format('personal')}/HP-000001/1/guess" seoul = client.post(path, json={"차례": at, "대상": [{"자재": "MT004258", "배": 1}]}).json() assert seoul["대상"][0]["세칸"]["자재구분"] == "사급" # 고른 자재 이름(-사급) 먼저 rows = (M02 / "M02_MasterTemplete_Hopyo_CheckRows.ts").read_text(encoding="utf-8") assert "...markCells(p?.세칸 ??" in rows