Files
Aislo/resources/tester/test_743_1_hopyo_forget.py
T
eomsangdonandClaude Opus 5.5 82037faeaa feat(743-1): 불러오기 엑셀 보관 안 함 — 그 불러오기 동안만 · 끝내기 · 화면 떠남 · 하루 지남 지움 · 같은 엑셀 다시 올림 · 만든 문서 엑셀 사본 걷음
- 끝냄 한 길 M02_Hopyo_Forget.finish — HP · 격자 · 맞춤셈 캐시 지움 · 만든 SC · SK 본뜬 = 출처(파일 · 때 · 누가 + 전국자재 · 복사원본)만 · SC 줄 메모 「실무 …」 걷음 · 실무수량 = 저장 수량.손 과 같을 때만 걷음(742 전 저장본은 남김 = 금액 그대로) · SK 또 = 그 HP 몫만
- 같은 엑셀 다시 올림 409 걷음(끝낸 기록 지문 안 씀 · 키 번은 그대로 이어감)
- 하루 지난 HP = 목록 숨김 · 올림 때 끝냄 · 붙여넣기 만듦 뒤 실무자료 끝냄
- 마법사 떠남(다른 화면 · 페이지 닫음) = 이 화면이 쥔 파일 지움(keepalive DELETE)
- 뒤 셈이 끝낸 HP 캐시를 다시 쓰지 않음(Fit._put) · 끝냄은 HP 먼저 지우고 캐시
- 옛 파일 정리 tidy(미리 보기 표 · --apply) — 옛 HP · 지문 기록 · HP 없는 문서 사본
- 본뜬 곳 칸 = 끝낸 실무자료는 「실무자료 파일」(originText)
- 시험: 718-1 「끝낸 같은 엑셀 409」 → 「다시 올림 새 키」 · 705-2 붙여넣기 실무자료 「남음」 → 「지움」(요구 584-2 로 뜻 바뀜) · 372-2 화면 시험 onDeleted 꼴 바뀜

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 20:22:42 +09:00

158 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""불러오기 엑셀 보관 안 함(PLAN 743-1 · 요구 582-3 · 584-2 · `M02_Hopyo_Forget`).
[끝내기] = 남는 파일 0 · 만든 일위대가 · 단가산출 = 출처(파일 · 때 · 누가)만 · 금액 그대로 ·
엑셀 사본(본뜬 키 · 원본 · 확인 · 품셈 · 줄 메모 「실무 …」) 걷음 ·
실무수량 = 저장 수량과 같을 때만 걷음 · SK 또 = 그 HP 몫만 ·
하루 지난 HP = 목록 숨김 → 올림 때 지움 · 옛 파일 정리 미리 보기(쓰기 0) → 고침.
층 = 임시 폴더.
"""
import json
from datetime import datetime, timedelta, timezone
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_Hopyo_Fit as fit
from M02_MasterTemplete import M02_Hopyo_Forget as forget
from M02_MasterTemplete import M02_Hopyo_Store as hs
from M02_MasterTemplete import M02_Labor_Ref as refs
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Template_Layers as layers
from resources.tester.test_m02_hopyo_excel import URL, _post, client # noqa: F401
ALL = "/api/m02/layers/personal/hopyo-build-all"
SK_URL = URL.format("personal") + "/HP-000001/sangeun"
def _files(folder):
return sorted(p.name for p in (folder / hs.DIRNAME).rglob("HP-*.json"))
def _sums(folder):
"""문서마다 1 단위 기준 계 — 끝내기 전후 같아야 함."""
whole = refs.Expand(m01.loaded()[1])
out = {}
with store.at(folder):
for kind in ("precombo", "sangeun"):
for p in sorted((folder / kind).glob("*.json")):
out[p.stem] = refs.summary(folder, kind, p.stem, whole).get("기준금액")
return out
def _docs(folder, kind):
return {p.stem: json.loads(p.read_bytes()) for p in sorted((folder / kind).glob("*.json"))}
# ── 순수 ──────────────────────────────────────────────────────────────
SURE = {"누가": {"id": 42, "이름": "갑"}, "때": "2026-11-02T00:00:00Z"}
HEAD = {"층": "실무자료", "주인": None, "키": "HP-000003 제2호표", "파일": "가.xls"}
def test_SC_사본_걷음_출처만_실무수량은_저장_수량과_같을_때만():
lines = [
{"로직": "L1", "메모": "실무 0.3㎥ × 1 · 규격", "수량": {"손": 0.3}, "별칭": "엑셀 품"},
{"로직": "L2", "메모": "사용자 메모", "수량": {"손": 2}},
]
doc = {
"이름": "가",
"담은로직": lines,
"자재": [{"코드": "MT1", "수량": {"손": 5}}],
"본뜬": {**HEAD, "원본": ["personal", "7/42"], "확인": SURE, "품셈": [0],
"전국자재": [{"이름": "모래"}], "실무수량": {"줄": {"0": 0.3, "1": 2},
"자재": {"MT1": 5}}},
} # fmt: skip
got = forget.strip_sc(doc)
assert got["본뜬"] == {
"층": "실무자료",
"파일": "가.xls",
"전국자재": [{"이름": "모래"}],
"때": SURE["때"],
"누가": SURE["누가"],
}
assert "메모" not in got["담은로직"][0] and got["담은로직"][1]["메모"] == "사용자 메모"
assert got["담은로직"][0]["별칭"] == "엑셀 품" and got["담은로직"][0]["수량"] == {"손": 0.3}
assert got["자재"] == doc["자재"]
# 742 전 저장본(수량 null) = 실무수량이 셈 근거 → 남김
old = {**doc, "담은로직": [{**x, "수량": None} for x in lines]}
assert forget.strip_sc(old)["본뜬"]["실무수량"] == doc["본뜬"]["실무수량"]
def test_SK_또_그_HP_몫만_걷음():
other = {"키": "HP-000004 단산1", "원본": None, "갈래": "SK", "엑셀품": {}, "이름": "나"}
doc = {"본뜬": {**HEAD, "키": "HP-000003 단산1", "확인": SURE, "갈래": "기초", "엑셀품": {},
"못옮김": [], "또": [other]}} # fmt: skip
got = forget.strip_sk(doc, lambda x: str(x.get("키")).startswith("HP-000003 "))
assert got["본뜬"] == {**{"층": "실무자료", "파일": "가.xls"}, **SURE, "또": [other]}
both = forget.strip_sk(doc, lambda x: True)
assert "또" not in both["본뜬"] and "키" not in both["본뜬"]
# ── 길 ───────────────────────────────────────────────────────────────
def test_끝내기_남는_파일_0_금액_그대로_출처만_다시_올림(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001"
fit.run_job(folder, "HP-000001")
assert client.post(SK_URL).status_code == 200
made = client.post(ALL, json={"층": "personal", "키": "HP-000001"}).json()
assert made["만듦"]
before = _sums(folder) # 모두 고정 = 메모 없음(메모 걷음은 순수 시험)
cache = fit.cache_path(folder, "HP-000001")
assert cache.is_file()
res = client.delete(URL.format("personal") + "/HP-000001")
assert res.status_code == 200
assert _files(folder) == [] and not cache.exists() # HP · 격자 · 맞춤셈 캐시 0
assert _sums(folder) == before # 금액 그대로
for kind in ("precombo", "sangeun"):
for key, doc in _docs(folder, kind).items():
got = doc["본뜬"]
assert got["층"] == "실무자료" and got["파일"] and got["때"], key
assert not {"키", "원본", "확인", "품셈", "갈래", "엑셀품", "못옮김", "또"} & set(got)
lines = doc.get("담은로직") or []
assert not any(str(x.get("메모", "")).startswith("실무 ") for x in lines)
assert hs.done(folder)["지문"] == {} # 끝낸 기록 없음
again = _post(client) # 같은 엑셀 다시 올림 = 새 키(409 없음)
assert again.status_code == 200 and again.json()["키"] == "HP-000002"
def test_하루_지난_HP_목록_숨김_올림_때_지움(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001"
path = folder / hs.DIRNAME / "HP-000001.json"
doc = json.loads(path.read_bytes())
old = datetime.now(timezone.utc) - timedelta(days=1, minutes=1)
doc["올린때"] = old.replace(microsecond=0).isoformat().replace("+00:00", "Z")
path.write_text(json.dumps(doc, ensure_ascii=False), encoding="utf-8")
assert client.get(URL.format("personal")).json()["줄"] == [] # 숨김
assert forget.expired(folder) == ["HP-000001"]
got = _post(client).json() # 같은 엑셀이어도 지난 것 = 지우고 새로(이어서 아님)
assert got["키"] == "HP-000002" and not got.get("이어서")
assert _files(folder) == ["HP-000002.json", "HP-000002.json"] # 이번 것 + 격자
def test_옛_파일_정리_미리_보기_쓰기_0_고침(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001" # 작업 중 — 그대로
home = folder / hs.DIRNAME
(home / "HP-000007.json").write_text(json.dumps({"키": "HP-000007", "호표": []}), "utf-8")
hs._put_done(folder, {"번": 7, "지문": {"ab": {"파일": "옛.xls", "만든": ["SC-000001"]}}})
(folder / "precombo").mkdir(exist_ok=True)
gone = {"이름": "옛", "단위": "개", "담은로직": [{"로직": "L", "메모": "실무 1개 × 1"}],
"본뜬": {**HEAD, "키": "HP-000005 제1호표", "확인": SURE}} # fmt: skip
live = {**gone, "본뜬": {**HEAD, "키": "HP-000001 제1호표", "확인": SURE}}
for key, doc in (("SC-000001", gone), ("SC-000002", live)):
text = json.dumps(doc, ensure_ascii=False)
(folder / "precombo" / f"{key}.json").write_text(text, "utf-8")
snap = {p: p.read_bytes() for p in folder.rglob("*.json")}
rows = forget.tidy(folder)
assert [r["대상"] for r in rows] == ["실무자료/HP-000007", "불러옴.json", "SC-000001"]
assert {p: p.read_bytes() for p in folder.rglob("*.json")} == snap # 미리 보기 = 쓰기 0
assert forget.tidy(folder, apply=True) == rows
assert _files(folder) == ["HP-000001.json", "HP-000001.json"]
assert hs.done(folder) == {"번": 7, "지문": {}}
docs = _docs(folder, "precombo")
assert "키" not in docs["SC-000001"]["본뜬"] and "메모" not in docs["SC-000001"]["담은로직"][0]
assert docs["SC-000002"] == live # 작업 중 HP 것 그대로
assert forget.tidy(folder) == [] # 두 번째 = 할 일 없음