Merge remote-tracking branch 'origin/sub_laptop_4' into sub_laptop_2

This commit is contained in:
2026-10-04 18:28:32 +09:00
7 changed files with 119 additions and 24 deletions
+43
View File
@@ -176,3 +176,46 @@ def test_만든_자체_로직이_시험_계산에_돈다(client: TestClient) ->
assert got["ok"] is True and Decimal(str(got["sums"]["노무비"])) > 0
listed = _get(client, "/api/m01/logics", owner="공용")["logics"]
assert made["key"] in [x["키"] for x in listed]
def test_일위대가가_담은_로직은_못_지운다(client: TestClient, tmp_path: Path, monkeypatch) -> None:
"""39-1d — 로직 지우기 검사 = 모든 층(마스터 · 회사 · 개인) labor 담은로직 + 실무문서(마스터
일위대가 조합) · 쓰는 곳을 알림 · 다 빼면 지워짐(임시 storage · 임시 마스터)."""
import json
from config import config_system
from M02_MasterTemplete import M02_Template_Layers as layers
system, storage = tmp_path / "system", tmp_path / "storage"
monkeypatch.setattr(layers, "SYSTEM_ROOT", system)
monkeypatch.setattr(config_system, "STORAGE_BASE_DIR", str(storage))
made = _post(client, "/api/m01/logic/new", {"logic": _draft(), "owner": "현장"})
key = made["key"]
docs = {
"회사 3": storage / "3/templates/labor/item1.json",
"개인 3/15": storage / "3/15/templates/labor/item2.json",
"마스터": system / "labor/item3.json",
}
for at, path in enumerate(docs.values()):
path.parent.mkdir(parents=True)
doc = {"일위대가번": f"SU-00000{at}", "담은로직": [{"로직": SAMPLE}, {"로직": key}]}
path.write_text(json.dumps(doc, ensure_ascii=False), encoding="utf-8")
combos = store.FOLDER / store.mcb.FILE
raw = json.loads(combos.read_text(encoding="utf-8"))
raw["줄"].append({**raw["줄"][0], "키": "UA999999", "담은로직": [{"로직": key, "메모": None}]})
combos.write_text(json.dumps(raw, ensure_ascii=False), encoding="utf-8")
def delete(want: int) -> dict:
version = _get(client, "/api/m01/logic", key=key)["version"]
return _post(client, "/api/m01/logic/delete", {"key": key, "version": version}, want)
errors = " ".join(delete(422)["detail"]["errors"])
for where in docs:
assert f"일위대가 {where} 「SU-" in errors and key in errors # 어디서 쓰는지 알림
assert store.mcb.FILE in errors # 실무문서(마스터 일위대가 조합)
for path in docs.values(): # 일위대가에서 뺌 — 실무문서만 남음
path.write_text(json.dumps({"담은로직": [{"로직": SAMPLE}]}), encoding="utf-8")
assert "일위대가 " not in " ".join(delete(422)["detail"]["errors"])
raw["줄"].pop()
combos.write_text(json.dumps(raw, ensure_ascii=False), encoding="utf-8")
assert delete(200)["file"] == make.OWN # 쓰는 곳 0 = 지워짐
+4 -5
View File
@@ -60,7 +60,7 @@ def world(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> dict[str, Any]:
def test_조합_길은_시스템_관리자만(world):
"""39-6 — 일위대가 조합 = 실무문서 · 조합 길 전부 시스템 관리자만 · 담을 로직 읽기는 로그인만."""
"""39-6 — 일위대가 조합 = 실무문서 · 조합 길 전부 시스템 관리자만 · 담을 로직은 로그인만."""
world["client"].app.dependency_overrides.pop(combos_router._door)
for role in ("USER", "ADMIN"):
client = _as(world, role)
@@ -149,10 +149,9 @@ def test_검사_빈_조합_이름_겹침_본뜬키_판(world):
branched = _new(me, "personal", _combo("마스터 본뜸", 본뜬키=master_key))
assert branched["combo"]["본뜬키"] == master_key # 층을 넘는 계보
url = f"{URL.format('personal')}/{first['키']}"
assert me.put(url, json={"combo": _combo("원본 고침"), "판": "낡은판"}).status_code == 409
now = _list(me, "personal")["판"]
res = me.put(url, json={"combo": _combo("원본 고침", (B,)), "판": now})
assert res.status_code == 200 and res.json()["combo"]["담은로직"][0]["로직"] == B
assert (
me.put(url, json={"combo": _combo("원본 고침")}).status_code == 405
) # 조합 고치기 은퇴(39-1d)
# ── 나무 ─────────────────────────────────────────────────────────────
+1 -1
View File
@@ -160,7 +160,7 @@ def test_남의_층_첫_쓰기는_소속_확인_뒤_뼈대(world: dict[str, Any]
add["판"] = ""
assert client.post("/api/m02/layers/company/tree?owner=9", json=add).status_code == 409
assert (storage / "9/templates/table/구조물집계표.json").is_file()
assert [n[2] for n in world["notes"]] == ["7/44", "7/44", "9"]
assert [n[2] for n in world["notes"]] == ["7/44"] # 성공한 쓰기만(39-1d) · 409 · 403 은 안 남김
def test_남의_층_목록(world: dict[str, Any]):