"""M02 구조물 라이브러리 여러 개 · 층 사이 붙여넣기(PLAN 30-2) — 임시 storage. ① 회사 항목 · 폴더를 일반 사용자 개인 층에 붙임 — 새 SP 키 · 본뜬 = 원본 · 세 파일 복사 · 폴더는 안의 것 · 빈 폴더까지 · 다시 붙이면 「이름 (2)」 · 고른 폴더 안의 것은 한 번만. ② 권한 — 쓰기 층만(일반 사용자 회사 층 403 · 남의 층 403) · 복사한 층은 읽기 권한(남의 회사 403). ③ 여러 개 옮기기 · 지우기 한 번에(하나라도 막히면 아무것도 안 바뀜). """ from __future__ import annotations import json from typing import Any from resources.tester import test_m02_tree as base from resources.tester.test_m02_tree import Tree, _as world = base.world # 같은 임시 storage 판 PASTE = "/api/m02/layers/{}/items/paste" def _company(world: dict[str, Any]) -> Tree: t = Tree(_as(world, "ADMIN"), "company") t.do(op="add-folder", 경로=[], 이름="배수") t.do(op="add-folder", 경로=["배수"], 이름="빈") t.do(op="add-item", 경로=["배수"], 이름="측구", 단위="m") t.do(op="add-item", 경로=[], 이름="옹벽", 단위="m") return t def test_회사_항목_폴더를_개인에_붙임_새_키_파일_이름2(world): company = _company(world) wall = company.item(["옹벽"])["key"] client = _as(world) # 일반 사용자 42 ditch = company.item(["배수", "측구"])["key"] body = { "from_layer": "company", "대상": [{"경로": ["배수"]}, {"경로": ["배수"], "키": ditch}, {"경로": [], "키": wall}], "경로": [], } res = client.post(PASTE.format("personal"), json=body) assert res.status_code == 200, res.text got = res.json() paths = [r["경로"] for r in got["items"]] assert paths == [["배수", "측구"], ["옹벽"]] # 폴더 안 측구는 한 번만 assert ["배수", "빈"] in got["폴더"] # 빈 폴더까지 assert all(r["key"].startswith("SP42-") for r in got["items"]) assert len(got["알림"]["열"]) == 2 root = world["storage"] / "7" / "42" / "templates" table = json.loads((root / "table/구조물집계표.json").read_bytes()) made = next(c for c in table["열"] if c.get("경로") == ["옹벽"]) assert made["본뜬"] == {"layer": "company", "owner": "7", "key": wall} for kind in ("structure", "area", "material"): assert (root / kind / f"{made['id']}.json").is_file() # 다시 붙이면 같은 이름 「(2)」 · 붙일 폴더 안으로 again = client.post(PASTE.format("personal"), json={**body, "경로": []}).json() assert ["배수 (2)", "측구"] in [r["경로"] for r in again["items"]] assert ["옹벽 (2)"] in [r["경로"] for r in again["items"]] inner = client.post(PASTE.format("personal"), json={**body, "대상": [body["대상"][2]], "경로": ["배수"]}).json() # fmt: skip assert ["배수", "옹벽"] in [r["경로"] for r in inner["items"]] def test_붙여넣기_권한(world): company = _company(world) body = {"from_layer": "company", "대상": [{"경로": ["배수"]}], "경로": []} client = _as(world) assert client.post(PASTE.format("company"), json=body).status_code == 403 # 일반 = 회사 읽기만 assert client.post(PASTE.format("personal") + "?owner=7/43", json=body).status_code == 403 far = {**body, "from_owner": "9"} assert client.post(PASTE.format("personal"), json=far).status_code == 403 # 남의 회사 읽기 막힘 missing = {**body, "대상": [{"경로": [], "키": "SC7-999999"}]} assert client.post(PASTE.format("personal"), json=missing).status_code == 404 # 회사 관리자 = 개인 → 회사 붙여넣기 admin = _as(world, "ADMIN") mine = Tree(admin, "personal") mine.do(op="add-item", 경로=[], 이름="내것", 단위="m") up = {"from_layer": "personal", "대상": [{"경로": [], "키": mine.item(["내것"])["key"]}]} res = admin.post(PASTE.format("company"), json={**up, "경로": ["배수"]}) assert res.status_code == 200, res.text assert ["배수", "내것"] in [r["경로"] for r in res.json()["items"]] assert company.client is admin def test_여러_개_옮기기_지우기_한_번에(world): t = Tree(_as(world), "personal") t.do(op="add-folder", 경로=[], 이름="가") t.do(op="add-folder", 경로=["가"], 이름="안") t.do(op="add-item", 경로=["가", "안"], 이름="깊은") t.do(op="add-item", 경로=[], 이름="하나") t.do(op="add-item", 경로=[], 이름="둘") t.do(op="add-folder", 경로=[], 이름="나") one, two = t.item(["하나"])["key"], t.item(["둘"])["key"] deep = t.item(["가", "안", "깊은"])["key"] moves = [ {"경로": [], "키": one}, {"경로": [], "키": two}, {"경로": ["가"]}, {"경로": ["가", "안"], "키": deep}, ] # fmt: skip — 가 안의 깊은 것은 폴더와 함께 t.do(op="move", 대상=moves, 새경로=["나"]) assert sorted(t.paths()) == [["나", "가", "안", "깊은"], ["나", "둘"], ["나", "하나"]] before = t.now["판"] t.do(422, op="move", 대상=[{"경로": ["나"], "키": one}, {"경로": ["나"]}], 새경로=["나"]) assert t.client.get(t.url).json()["판"] == before # 막히면 아무것도 안 씀 t.do(422, op="rename", 대상=[{"경로": ["나"]}], 이름="x") note = t.do(op="delete", 대상=[{"경로": ["나"], "키": one}, {"경로": ["나", "가"]}]) assert len(note["알림"]["지운항목"]) == 2 assert t.paths() == [["나", "둘"]]