Merge remote-tracking branch 'origin/sub_laptop_5' into main_laptop_1
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
임시 storage.
|
||||
|
||||
`/api/m02/layers/{층}/{종류}-tree` = 일위대가(precombo) · 단가산출(sangeun) 따로 ·
|
||||
폴더 지우기 = 안의 문서 파일째(모두 검사 뒤 한 번에 · 바깥에서 쓰면 409 + 그 이름 ·
|
||||
폴더 지우기 = 안의 문서 파일째(모두 검사 뒤 한 번에 · 바깥에서 쓰면 확인 없이는 409 + 목록 ·
|
||||
지우는 것끼리 참조는 됨) ·
|
||||
`대상` 여럿 옮기기 · 지우기 · `…-tree/paste` = 새 키 · 같은 폴더 이름 「(1)」 · 본뜬 = 원본.
|
||||
"""
|
||||
@@ -64,15 +64,20 @@ def test_폴더_지우기는_안에_든_것째_지우는_것끼리_참조는_됨
|
||||
assert _files("sangeun") == [] and sk.now["폴더"] == []
|
||||
|
||||
|
||||
def test_바깥에서_쓰면_409_그_이름_아무것도_안_지움(client: TestClient): # noqa: F811
|
||||
def test_바깥에서_쓰면_확인_없이는_409_목록_아무것도_안_지움(client: TestClient): # noqa: F811
|
||||
a = _sk(client, "바탕")
|
||||
body = {"문서": {"이름": "쓰는 일위대가", "단위": "㎡", "담은로직": [{"참조": {**MINE, "키": a}}]}}
|
||||
body = {
|
||||
"문서": {"이름": "쓰는 일위대가", "단위": "㎡", "담은로직": [{"참조": {**MINE, "키": a}}]}
|
||||
}
|
||||
assert client.post("/api/m02/layers/personal/library/precombo", json=body).status_code == 200
|
||||
sk = _sk_tree(client)
|
||||
sk.do(op="add-folder", 경로=[], 이름="묶음")
|
||||
sk.do(op="move", 키=a, 새경로=["묶음"])
|
||||
detail = sk.do(409, op="delete", 경로=["묶음"])["detail"]
|
||||
assert "쓰는 곳" in detail and "「쓰는 일위대가」" in detail and a in detail
|
||||
detail = sk.do(409, op="delete", 경로=["묶음"])["detail"] # 735-1 — 확인 뒤 그 줄째 지움
|
||||
assert "쓰는 곳" in detail["까닭"]
|
||||
assert [(r["이름"], r["키"], r["줄"]) for r in detail["쓰는곳"]] == [
|
||||
("쓰는 일위대가", a, "1째")
|
||||
]
|
||||
assert _files("sangeun") == [a] and client.get(sk.url).json()["폴더"] == [["묶음"]]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
|
||||
"""서고 나무 지우기 = 경고 뒤 지움 · 쓰는 곳 그 줄도 지움(PLAN 735-1 · 요구 574) — 임시 storage.
|
||||
|
||||
미리 보기(쓰는 줄 = 종류 · 이름 · 키 · 줄) · 확인 없으면 409 목록 · 확인 = 그 줄 지움
|
||||
(금액 다시 셈) + 문서 지움 + `_합친것/` 기록 · 되돌림(문서 · 자리 · 고친 문서 앞판 ·
|
||||
그새 고친 문서는 건너뜀) ·
|
||||
권한 밖 409(아무것도 안 바뀜) · 폴더 통째 = 한 기록 · 단가산출 바탕 · 더한줄 열쇠 당김(`strip`).
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from common_util.common_util_auth import verify_session
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
from M02_MasterTemplete import M02_Labor_Router as labor_router
|
||||
from M02_MasterTemplete import M02_Library_Delete as deleting
|
||||
from M02_MasterTemplete import M02_Library_Same_Router as same_router
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from resources.tester.test_m02_labor_ref import MINE, world # noqa: F401
|
||||
|
||||
USER = {"user_id": 42, "company_id": 7, "role": "USER", "is_master": False, "name": "갑"}
|
||||
TREE = "/api/m02/layers/personal/precombo-tree"
|
||||
SAME = "/api/m02/layers/personal/precombo-same"
|
||||
SK_TREE = "/api/m02/layers/personal/sangeun-tree"
|
||||
SK_SAME = "/api/m02/layers/personal/sangeun-same"
|
||||
FIX = {"고정": {"이름": "운반", "단위": "식", "단가": {"경비": 5000}}, "수량": {"손": 1}}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def api(world):
|
||||
app = FastAPI()
|
||||
app.include_router(labor_router.router)
|
||||
app.include_router(same_router.router)
|
||||
app.dependency_overrides[verify_session] = lambda: USER
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def _sc(folder, name, lines):
|
||||
with store.at(folder):
|
||||
return refs.create("precombo", {"이름": name, "단위": "m", "담은로직": lines})["이름"]
|
||||
|
||||
|
||||
def _labor(folder, lines):
|
||||
with store.at(folder):
|
||||
store.write("labor", "x1", "", {"열": "x1", "담은로직": lines, "자재": []})
|
||||
|
||||
|
||||
def _read(folder, kind, key):
|
||||
with store.at(folder):
|
||||
return store.read(kind, key)["문서"]
|
||||
|
||||
|
||||
def _sum(folder):
|
||||
return _read(folder, "labor", "x1")["계산값"]["반영합"]["계"]
|
||||
|
||||
|
||||
def _tree(api, url=TREE, **body):
|
||||
판 = api.get(url).json()["판"]
|
||||
return api.post(url, json={"판": 판, **body})
|
||||
|
||||
|
||||
def _world(world):
|
||||
"""단가산출 하나(운반 3000 · 1 단위)를 구조물 조합 x1(2 단위) · 일위대가가 물게."""
|
||||
me = world["personal"]
|
||||
line = {"고정": {"이름": "운반", "단위": "식", "단가": {"경비": 3000}}, "수량": 1}
|
||||
with store.at(me):
|
||||
doc = {"이름": "임시 단가산출", "단위": "m", "바탕": None, "더한줄": [line]}
|
||||
sk = refs.create("sangeun", doc)["이름"]
|
||||
top = _sc(me, "위 일위대가", [{"참조": {**MINE, "키": sk}}, FIX])
|
||||
_labor(me, [{"참조": {**MINE, "키": sk}, "수량": {"손": 2}}, FIX])
|
||||
return me, sk, top
|
||||
|
||||
|
||||
def test_미리보기_확인없으면_409_확인하면_그줄_지움_금액_다시셈_되돌림(api, world):
|
||||
me, sk, top = _world(world)
|
||||
before = _sum(me)
|
||||
assert before == pytest.approx(5000 + 2 * 3000)
|
||||
|
||||
got = api.post(SK_TREE + "/delete-check", json={"대상": [{"키": sk}]})
|
||||
assert got.status_code == 200, got.text
|
||||
rows = got.json()["쓰는곳"]
|
||||
assert got.json()["문서"] == [sk]
|
||||
assert sorted((r["종류"], r["이름"], r["키"], r["줄"], r["쓰기"]) for r in rows) == [
|
||||
("구조물 조합", "x1", sk, "1째", True),
|
||||
("일위대가", "위 일위대가", sk, "1째", True),
|
||||
]
|
||||
|
||||
res = _tree(api, SK_TREE, op="delete", 대상=[{"키": sk}])
|
||||
assert res.status_code == 409 and len(res.json()["detail"]["쓰는곳"]) == 2
|
||||
assert (me / "sangeun" / f"{sk}.json").is_file()
|
||||
|
||||
res = _tree(api, SK_TREE, op="delete", 대상=[{"키": sk}], 확인=True)
|
||||
assert res.status_code == 200, res.text
|
||||
assert res.json()["알림"]["기록"] == sk
|
||||
assert not (me / "sangeun" / f"{sk}.json").exists()
|
||||
assert [x.get("고정", {}).get("이름") for x in _read(me, "labor", "x1")["담은로직"]] == ["운반"]
|
||||
assert len(_read(me, "precombo", top)["담은로직"]) == 1
|
||||
assert _sum(me) == pytest.approx(5000) # 서버가 다시 셈
|
||||
|
||||
gone = api.get(SK_SAME).json()["합친것"]
|
||||
assert [(g["키"], g["남김"], g["옮긴곳수"]) for g in gone] == [(sk, None, 2)]
|
||||
back = api.post(SK_SAME + "/undo", json={"키": sk})
|
||||
assert back.status_code == 200, back.text
|
||||
assert back.json()["되돌린곳수"] == 2 and back.json()["못한곳"] == []
|
||||
assert (me / "sangeun" / f"{sk}.json").is_file()
|
||||
assert _read(me, "labor", "x1")["담은로직"][0]["참조"]["키"] == sk
|
||||
assert _sum(me) == pytest.approx(before)
|
||||
assert api.get(SK_SAME).json()["합친것"] == []
|
||||
|
||||
|
||||
def test_쓰는곳_없으면_그냥_지움_기록은_남음(api, world):
|
||||
me = world["personal"]
|
||||
sc = _sc(me, "혼자", [FIX])
|
||||
assert api.post(TREE + "/delete-check", json={"대상": [{"키": sc}]}).json()["쓰는곳"] == []
|
||||
assert _tree(api, op="delete", 대상=[{"키": sc}]).status_code == 200
|
||||
assert not (me / "precombo" / f"{sc}.json").exists()
|
||||
assert api.post(SAME + "/undo", json={"키": sc}).status_code == 200
|
||||
assert (me / "precombo" / f"{sc}.json").is_file()
|
||||
|
||||
|
||||
def test_권한_밖이면_409_목록_아무것도_안_바뀜(api, world, monkeypatch):
|
||||
me, sk, _top = _world(world)
|
||||
monkeypatch.setattr(deleting, "can_write", lambda session, at: False)
|
||||
res = _tree(api, SK_TREE, op="delete", 대상=[{"키": sk}], 확인=True)
|
||||
assert res.status_code == 409
|
||||
detail = res.json()["detail"]
|
||||
assert "권한 밖" in detail["까닭"] and "x1" in detail["까닭"] and sk in detail["까닭"]
|
||||
assert {r["이름"] for r in detail["막힘"]} == {"x1", "위 일위대가"}
|
||||
assert (me / "sangeun" / f"{sk}.json").is_file()
|
||||
assert len(_read(me, "labor", "x1")["담은로직"]) == 2
|
||||
|
||||
|
||||
def test_폴더_통째_한_기록_되돌림_자리까지_그새_고친_문서는_건너뜀(api, world):
|
||||
me = world["personal"]
|
||||
a = _sc(me, "가", [FIX])
|
||||
b = _sc(me, "나", [FIX])
|
||||
_labor(me, [{"참조": {**MINE, "키": a}, "수량": {"손": 1}}, FIX])
|
||||
other = _sc(me, "다른", [{"참조": {**MINE, "키": b}}, FIX])
|
||||
assert _tree(api, op="add-folder", 경로=[], 이름="묶음").status_code == 200
|
||||
for key in (a, b):
|
||||
assert _tree(api, op="move", 키=key, 새경로=["묶음"]).status_code == 200
|
||||
check = api.post(TREE + "/delete-check", json={"대상": [{"경로": ["묶음"]}]}).json()
|
||||
assert sorted(check["문서"]) == [a, b]
|
||||
assert sorted(r["키"] for r in check["쓰는곳"]) == [a, b]
|
||||
res = _tree(api, op="delete", 대상=[{"경로": ["묶음"]}], 확인=True)
|
||||
assert res.status_code == 200, res.text
|
||||
name = res.json()["알림"]["기록"]
|
||||
assert [g["키"] for g in api.get(SAME).json()["합친것"]] == [name]
|
||||
with store.at(me): # 그새 「다른」 을 고침 → 그 문서는 앞판으로 안 돌림
|
||||
have = store.read("precombo", other)
|
||||
store.write("precombo", other, have["판"], {**have["문서"], "이름": "다른 고침"})
|
||||
back = api.post(SAME + "/undo", json={"키": name}).json()
|
||||
assert back["되돌린곳수"] == 1 and "그새 고침" in back["못한곳"][0]
|
||||
assert (me / "precombo" / f"{a}.json").is_file() and (me / "precombo" / f"{b}.json").is_file()
|
||||
assert api.get(TREE).json()["자리"] == {a: ["묶음"], b: ["묶음"]}
|
||||
assert _read(me, "labor", "x1")["담은로직"][0]["참조"]["키"] == a
|
||||
|
||||
|
||||
def test_단가산출_바탕_더한줄_지움_열쇠_당김():
|
||||
gone = {**MINE, "키": "SK-000002"}
|
||||
keep = {**MINE, "키": "SK-000003"}
|
||||
doc = {
|
||||
"바탕": {"참조": gone},
|
||||
"열린입력": ["높이"],
|
||||
"더한줄": [{"참조": gone, "수량": 1}, {"참조": keep, "수량": 1}, {"종류": "로직"}],
|
||||
"덮개": {"labor:A#1": {"qty": 1}, "add:#1": {"배율": 2}, "add:#2/labor:B#1": {"qty": 3}},
|
||||
"뺀줄": ["labor:A#2", "add:#0"],
|
||||
"고름": {"add:#2/material:C#1": "MT1"},
|
||||
"자재표시": {},
|
||||
}
|
||||
out = deleting.strip(doc, {refs.ref_id(gone)})
|
||||
assert out["바탕"] is None and out["열린입력"] == []
|
||||
assert [x.get("참조") for x in out["더한줄"]] == [keep, None]
|
||||
assert out["덮개"] == {"add:#0": {"배율": 2}, "add:#1/labor:B#1": {"qty": 3}}
|
||||
assert out["뺀줄"] == []
|
||||
assert out["고름"] == {"add:#1/material:C#1": "MT1"}
|
||||
assert deleting.strip(doc, set()) == doc # 안 걸리면 그대로
|
||||
Reference in New Issue
Block a user