Files
Aislo/resources/tester/test_m02_precombo_folders.py
T
eomsangdonandClaude Opus 5.5 ceec2a99da feat(716-4): 서고 나무 폴더 — 종류 인자 · 안에 든 것째 지움 · 쓰는 곳 409 · 여럿 · 복사 붙여넣기
- 서버 `M02_Precombo_Folders` — 종류 인자(precombo · sangeun · 자리 파일 `{종류}_폴더.json`) · 폴더 지우기 = 안의 문서 파일째(모두 검사 뒤 한 번에 · 바깥에서 쓰면 409 + 그 이름 · 지우는 것끼리 참조는 됨) · 문서 지우기 · `대상` 여럿 옮기기 · 지우기 · 붙여넣기(새 키 · 본뜬 = 원본 · 같은 폴더 이름 「(1)」)
- 길 `M02_Labor_Router` — `/layers/{층}/{종류}-tree` GET · POST · `/paste`(옛 precombo-tree 주소 그대로)
- 화면 새 `UI_Side_Library.ts` — 일위대가 · 단가산출 두 칸이 같이 쓰는 서고 칸(Ctrl · Shift 고름 · 오른쪽 클릭 · Ctrl+C · Ctrl+V · Delete · 지우기 확인 창 · 끌어 옮기기 여럿) · `UI_Side_Precombo.ts` = 일위대가 몫만 넘김
- `Api_Fetch` — 나무 부르기 종류 인자 · `pasteLibraryTree` · `newLibrary` 종류 sangeun
- 시험 — 새 `test_716_4_library_folders.py`(임시 storage) · 낡은 것 고침: `test_m02_precombo_folders`(빈 폴더만 지움 → 안에 든 것째 · 「없는 사전조합」 → 「없는 문서」 · FILE → file_of) · `test_m02_precombo_scope` + helper(나무 짜기 · 서고 길 글이 Library.ts 로 옮김)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 15:35:23 +09:00

155 lines
7.6 KiB
Python

"""일위대가 사전조합 나무 = 자유 폴더(PLAN 158-1 · `M02_Precombo_Folders`) — 임시 storage.
새 폴더(깊이 자유) · 문서 옮기기(파일은 제자리 · 자리만) · 폴더 이름 바꾸기 ·
옮기기(아래 자리 따라감) · 지우기(안에 든 문서째 · 716-4) · 판 409 ·
층(마스터 · 회사 · 개인)마다 따로 · 문서 수(양식 목록) 그대로 · 쓰기 권한 = 층 규칙(마스터 403).
"""
from pathlib import Path
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from common_util.common_util_auth import verify_session
from config import config_system
from M02_MasterTemplete import M02_Labor_Router as labor_router
from M02_MasterTemplete import M02_MasterTemplete_Router_Layers as layers_router
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Precombo_Folders as pre
from M02_MasterTemplete import M02_Template_Layers as layers
from resources.tester.test_m02_structure import write_sample_table
TREE = "/api/m02/layers/{}/precombo-tree"
@pytest.fixture()
def client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> TestClient:
system = tmp_path / "system"
system.mkdir()
write_sample_table(system)
monkeypatch.setattr(store, "FOLDER", system)
monkeypatch.setattr(layers, "SYSTEM_ROOT", system)
(tmp_path / "storage").mkdir()
monkeypatch.setattr(config_system, "STORAGE_BASE_DIR", str(tmp_path / "storage"))
app = FastAPI()
app.include_router(labor_router.router)
app.include_router(layers_router.router)
app.dependency_overrides[verify_session] = lambda: {
"user_id": 42,
"company_id": 7,
"role": "USER",
"is_master": False,
}
got = TestClient(app)
for name in ("가", "나", "다"): # 개인 층 문서 셋 — SC-000001~3
body = {"문서": {"이름": name, "구분": "C 사면안정", "상세구분": "옹벽", "담은로직": []}}
assert got.post("/api/m02/layers/personal/library/precombo", json=body).status_code == 200
return got
class Tree:
def __init__(self, client: TestClient, layer: str = "personal"):
self.client, self.url = client, TREE.format(layer)
self.now = client.get(self.url).json()
def do(self, want: int = 200, **body) -> dict:
res = self.client.post(self.url, json={"판": self.now["판"], **body})
assert res.status_code == want, res.text
if want == 200:
self.now = res.json()
assert self.now == {**self.client.get(self.url).json(), "알림": self.now["알림"]}
return res.json()
def _docs(client: TestClient, layer: str = "personal") -> list[str]:
rows = client.get(f"/api/m02/layers/{layer}/templates").json()["양식"]
return [r["이름"] for r in rows if r["종류"] == "precombo"]
def test_처음은_모두_뿌리_새_폴더_깊이_자유(client: TestClient):
t = Tree(client)
assert t.now == {"판": "", "폴더": [], "자리": {}} # 문서 셋 = 뿌리
t.do(op="add-folder", 경로=[], 이름="옹벽")
t.do(op="add-folder", 경로=["옹벽"], 이름="찰쌓기")
t.do(op="add-folder", 경로=["옹벽", "찰쌓기"], 이름="높이 3m")
assert t.now["폴더"] == [["옹벽"], ["옹벽", "찰쌓기"], ["옹벽", "찰쌓기", "높이 3m"]]
assert t.do(409, op="add-folder", 경로=[], 이름="옹벽")["detail"].startswith("이미 있는 폴더")
assert t.do(404, op="add-folder", 경로=["없음"], 이름="x")["detail"].startswith("없는 폴더")
assert t.do(422, op="add-folder", 경로=[], 이름=" ") # 빈 이름
def test_문서_옮기기는_자리만_파일과_문서_수_그대로(client: TestClient, tmp_path: Path):
t = Tree(client)
t.do(op="add-folder", 경로=[], 이름="옹벽")
t.do(op="add-folder", 경로=["옹벽"], 이름="찰쌓기")
t.do(op="move", 키="SC-000001", 새경로=["옹벽", "찰쌓기"])
t.do(op="move", 키="SC-000002", 새경로=["옹벽"])
assert t.now["자리"] == {"SC-000001": ["옹벽", "찰쌓기"], "SC-000002": ["옹벽"]}
t.do(op="move", 키="SC-000002", 새경로=[]) # 뿌리로 = 자리 지움
assert t.now["자리"] == {"SC-000001": ["옹벽", "찰쌓기"]}
assert t.do(404, op="move", 키="SC-000009", 새경로=[])["detail"].startswith("없는 문서")
assert t.do(404, op="move", 키="SC-000001", 새경로=["없음"])
personal = layers.personal_dir(7, 42)
assert sorted(p.name for p in (personal / "precombo").iterdir()) == [
"SC-000001.json",
"SC-000002.json",
"SC-000003.json",
]
assert _docs(client) == ["SC-000001", "SC-000002", "SC-000003"] # 자리 파일은 목록에 안 섞임
assert (personal / pre.file_of("precombo")).is_file()
def test_폴더_이름_바꾸기_옮기기는_아래_자리가_따라감(client: TestClient):
t = Tree(client)
for parent, name in (([], "가"), (["가"], "나"), ([], "다")):
t.do(op="add-folder", 경로=parent, 이름=name)
t.do(op="move", 키="SC-000001", 새경로=["가", "나"])
t.do(op="rename", 경로=["가"], 이름="라")
assert t.now["폴더"] == [["라"], ["라", "나"], ["다"]]
assert t.now["자리"] == {"SC-000001": ["라", "나"]}
assert t.do(409, op="rename", 경로=["라"], 이름="다")
t.do(op="move", 경로=["라", "나"], 새경로=["다"])
assert t.now["자리"] == {"SC-000001": ["다", "나"]} and ["라", "나"] not in t.now["폴더"]
assert t.do(422, op="move", 경로=["다"], 새경로=["다", "나"])["detail"].startswith("폴더를 제")
t.do(op="add-folder", 경로=[], 이름="나")
t.do(op="move", 경로=["다", "나"], 새경로=[]) # 같은 이름 = 「나(1)」
assert t.now["알림"]["바뀐이름"] == ["나(1)"] and t.now["자리"]["SC-000001"] == ["나(1)"]
def test_지우기는_안에_든_문서째(client: TestClient):
t = Tree(client)
t.do(op="add-folder", 경로=[], 이름="가")
t.do(op="add-folder", 경로=["가"], 이름="나")
t.do(op="add-folder", 경로=["가", "나"], 이름="다")
t.do(op="move", 키="SC-000003", 새경로=["가", "나", "다"])
got = t.do(op="delete", 경로=["가"]) # 아래 폴더 · 문서까지(716-4)
assert got["알림"]["지운문서"] == ["SC-000003"]
assert t.now["폴더"] == [] and t.now["자리"] == {}
assert _docs(client) == ["SC-000001", "SC-000002"]
def test_판이_다르면_409_고침_안_함(client: TestClient):
t = Tree(client)
t.do(op="add-folder", 경로=[], 이름="가")
old = t.now["판"]
t.do(op="add-folder", 경로=[], 이름="나")
res = client.post(TREE.format("personal"), json={"판": old, "op": "delete", "경로": ["가"]})
assert res.status_code == 409 and ["가"] in client.get(TREE.format("personal")).json()["폴더"]
def test_층마다_따로_마스터_쓰기는_층_규칙(client: TestClient):
Tree(client).do(op="add-folder", 경로=[], 이름="내 폴더")
company = Tree(client, "company")
assert company.now["폴더"] == [] and Tree(client, "system").now["폴더"] == []
assert Tree(client, "system").do(403, op="add-folder", 경로=[], 이름="x")
assert client.get(TREE.format("personal")).json()["폴더"] == [["내 폴더"]]
def test_지운_문서_자리는_안_보임():
doc = {"폴더": [["가"]], "자리": {"SC-000001": ["가"], "SC-000002": ["가", "나"]}}
got = pre.view_of(doc, "v", {"SC-000001"})
assert got == {"판": "v", "폴더": [["가"]], "자리": {"SC-000001": ["가"]}}
out, _ = pre.apply(doc, {"op": "add-folder", "경로": [], "이름": "다"}, {"SC-000001"})
assert out["자리"] == {"SC-000001": ["가"]} # 고칠 때 걷힘