"""703-3 B09 [업데이트] 한 곳 — 단가 책 다시 굳힘 + 원본이 바뀐 구조물 사본 재적용. - 미리 보기 수(`Refresh.preview`) = 적용 뒤 책 견줌(`Prices.book_diff`) 수 · 노임 판 전 → 후 · 고친 칸 수 - 재적용 = 연결된 사본 중 원본이 바뀐 것만 · 하나가 막혀도 나머지 · 덮개(사용자 값) 안 건드림 """ import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from B09_Estimation import B09_Estimation_Prices as prices # noqa: E402 from B09_Estimation import B09_Estimation_Refresh as refresh # noqa: E402 from B09_Estimation import B09_Estimation_Store as store # noqa: E402 KEYS = ["LB000001", "LB000033"] # 작업반장(건설업) · 석공 def test_책_견줌_미리보기_수_적용_수_같음(tmp_path, monkeypatch): monkeypatch.setattr(refresh, "changed_copies", lambda root: []) new = prices.refresh_book(KEYS) assert new["labor_edition"] == prices.labor_editions(KEYS) and new["labor_edition"] old = json.loads(json.dumps(new)) old["rows"]["LB000001"] = {**old["rows"]["LB000001"], "price": 1} # 옛 판 값 del old["rows"]["LB000033"] # 새 줄 old["labor_edition"] = {"건설업": "2025-09-01"} cover = { "S:a": {"x#0": {"qty": 1, "labor": 2}}, "K:b": {"@copy": {"from": "S:a"}, "y#0": {"qty": 3}}, } got = refresh.preview(tmp_path, old, KEYS, cover) after = prices.refresh_book(KEYS, old) diff = prices.book_diff(old, after) assert (got["새줄"], got["바뀐줄"]) == (diff["new"], diff["changed"]) == (1, 1) assert got["단가줄"] == 2 and got["고친칸"] == 3 and got["사본"] == [] assert got["노임판"]["전"] == "건설업 2025-09" assert got["노임판"]["후"].startswith("건설업 2026") old.pop("labor_edition") assert refresh.preview(tmp_path, old, KEYS, None)["노임판"]["전"].startswith("굳힌 날 ") assert prices.book_diff(after, prices.refresh_book(KEYS, after)) == { "new": 0, "changed": 0, "factor": False, "fx": False, } assert prices.book_stale(after, KEYS) is None def test_재적용_원본_바뀐_사본만_막혀도_나머지_덮개_그대로(tmp_path, monkeypatch): cover = {"S:a": {"x#0": {"qty": 0.3}}} store.write_user(tmp_path, {"daega_cover": cover}) monkeypatch.setattr( refresh, "linked_snapshots", lambda root: {"p1": {"폴더": "a"}, "p2": {"폴더": "b"}, "p3": {"폴더": "c"}}, ) items = [ {"폴더": "a", "이름": "가", "마스터바뀜": True}, {"폴더": "b", "이름": "나", "마스터바뀜": False}, # 원본 그대로 = 안 함 {"폴더": "c", "이름": "다", "마스터바뀜": True}, {"폴더": "z", "이름": "끊김", "마스터바뀜": True}, # 연결 안 됨 = 안 함 ] monkeypatch.setattr(refresh.item_copy, "list_items", lambda root: items) calls = [] def fake(root, folder, who=None): calls.append(folder) if folder == "c": raise LookupError("원본 층 없음") monkeypatch.setattr(refresh.item_copy, "reapply", fake) assert [c["이름"] for c in refresh.changed_copies(tmp_path)] == ["가", "다"] got = refresh.reapply_changed(tmp_path) assert calls == ["a", "c"] assert got == {"다시": ["가"], "막힘": ["다 — 원본 층 없음"]} assert store.read_user(tmp_path)["daega_cover"] == cover