"""관급 단가 짝짓기 — 작은 견본 응답으로 레미콘 지역·규격 · 아스콘 · 값 갈림 보류 · 지역 불일치 미채움 (`resources/master_data/scripts/update_관급단가.py`).""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "master_data/scripts")) import update_관급단가 as up # noqa: E402 def raw_row( spec, region, price, corp="테스트조합", maker="조합공통품목", cond="", bgn="2026-06-01" ): return { "prdctSpecNm": spec, "prdctSplyRgnNm": region, "cntrctPrceAmt": str(price), "cntrctCorpNm": corp, "prdctMakrNm": maker, "prdctDlvryCndtnNm": cond, "cntrctBgnDate": bgn, "rgstDt": bgn, "cntrctMthdNm": "다수 공급자 계약", "vatAplDivNm": "포함", "prdctUnit": "㎥", } def item(key, name, spec): return {"키": key, "이름": name, "규격": spec, "관급": 1, "비고": "조달 26.7"} RAW = { "MASCntrct_레미콘": [ raw_row("조합공통품목, 25-18-080", "경기도 수원시", 100000), raw_row("조합공통품목, 25-18-080", "강원도 원주시", 90000), raw_row("조합공통품목, 25-21-080", "경기도 수원시", 105000), raw_row("삼표, 25-18-080", "경기도 수원시", 1, maker="삼표"), # 제조사 줄 — 조합공통 아님 ], "MASCntrct_아스팔트콘크리트": [ raw_row("아스팔트콘크리트 조합공통품목, WC-2, 가열, 3등급", "경기도 수원시", 70000), raw_row("순환 아스팔트콘크리트 조합공통품목, WC-2, 가열, 3등급", "경기도 수원시", 60000), ], "MASCntrct_봉강": [ raw_row("SD400, D10", "전지역(제주제외)", 827640, maker="가철강", cond="생산공장 상차도"), raw_row("SD400, D10", "전지역(제주제외)", 830000, maker="나철강", cond="생산공장 상차도"), ], } def fill(x): (r,) = up.refill([x], RAW) return r, up.decide(x, r, "2026-09-20") def test_레미콘_지역_규격_짝(): r, (val, note) = fill(item("a", "레미콘(관급)-경기 수원", "조합공통품목, 25-18-80")) # 80 = 080 assert val == 100000 and "조달청" in note r, (val, _) = fill(item("b", "레미콘(관급)-경기 수원", "조합공통품목, 25-21-080")) assert val == 105000 def test_레미콘_지역_불일치는_안_채움(): r, (val, note) = fill(item("c", "레미콘(관급)-울진", "조합공통품목, 25-18-080")) assert val is None and "지역 못 찾음" in note def test_레미콘_규격_없으면_안_채움(): r, (val, note) = fill(item("d", "레미콘(관급)-경기 수원", "조합공통품목, 30-24-150")) assert val is None and "강도 없음" in note def test_아스콘_순환_구분(): _, (val, _) = fill(item("e", "아스콘(관급)-경기 수원", "조합공통품목, WC-2, 가열, 3등급")) assert val == 70000 _, (val, _) = fill(item("f", "순환아스콘(관급)-경기 수원", "조합공통품목, WC-2, 가열, 3등급")) assert val == 60000 def test_제조사별_값_갈리면_보류(): _, (val, note) = fill(item("g", "이형철근(SD400)-관급", "HD=10mm 생산공장 상차도")) assert val is None and "갈림" in note def test_짝_없는_갈래는_안_채움(): _, (val, note) = fill(item("h", "벤치플륨(관급)", "300")) assert val is None and "짝짓기 없음" in note def test_호출_오류에_키_안_찍힘(monkeypatch): def boom(url, **kw): raise OSError(f"연결 실패 {url}") monkeypatch.setattr(up.cc, "fetch", boom) try: up.call("op", "SECRETKEY123", a=1) except RuntimeError as e: assert "SECRETKEY123" not in str(e) and "***" in str(e) else: raise AssertionError("예외가 나야 함")