Files
Aislo/resources/tester/test_821_1_my_machine.py
T

179 lines
9.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.
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
"""821-1 내 기계(개인 층 기계 줄) — M01 기계처럼: 만들 때 사본에 복사 · 고쳐도 금액 그대로 + 「단가새값」 ·
[단가 갱신] 으로 반영 · 지워도 마지막 값(임시 storage · M01 정본 안 고침).
① 세 꼴(바로 · 품셈 · 직접) 저장 · 키 · 원문번호 M01 과 안 겹침 ② 시간당 = M01 같은 값 기계와 같음
③ 찾기 · 남의 층 안 보임 ④ SK 사본에 박힘 · 고친 뒤 그대로 + 새값 · 갱신 뒤 반영 · 지운 뒤 마지막 값 ·
층 사이 복사 ⑤ M01 만 쓰는 SK 금액 그대로 ⑥ 권한.
"""
from __future__ import annotations
import json
import pytest
from fastapi import HTTPException
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_Labor_Ref as refs
from M02_MasterTemplete import M02_Machine_Find as mfind
from M02_MasterTemplete import M02_Machine_Hourly as mh
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_MyMachine as mym
from M02_MasterTemplete import M02_MyMachine_Router as route
from M02_MasterTemplete import M02_Sangeun_Calc as calc
from M02_MasterTemplete import M02_Sangeun_Copy as skc
from M02_MasterTemplete import M02_Template_Layers as layers
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 같은 임시 층
DIG = "EQ000022" # 굴착기(무한궤도) 1.0㎥ — 연료 · 조종원 있음
PCT = "GC001109" # M01 만 쓰는 SK 바탕
NAME = "서브셋임시기계" # 찾기 기종 글(수 = 규격으로 읽음 · 창 표시는 글로)
def _at(folder, fn, *args):
with store.at(folder):
return fn(*args)
def _easy(**vals):
base = {"가격": 1000, "손료계수": 2000, "주연료": 2, "주연료종류": "경유", "잡재료율": 10,
"조종원": 1, "조종원직종": "1048"} # fmt: skip
return {"이름": NAME, "규격": "1㎾", "방식": "바로", "값": base | vals}
def _sk(folder, machine_no):
line = {"종류": "로직", "로직": "GC000268", "입력값": {"기계": machine_no, "지역": "전국평균"},
"수량": "1"} # fmt: skip
body = {"이름": "sub3임시 내기계", "단위": "시간", "더한줄": [line]}
return _at(folder, lambda: refs.create("sangeun", body)["이름"])
def _doc(folder, key):
return _at(folder, lambda: store.read("sangeun", key)["문서"])
def _calc(folder, doc):
return _at(folder, calc.calc_doc, doc, None, False)
def _sum(folder, key):
return _calc(folder, _doc(folder, key))["기준"]["계"]
def test_three_shapes_and_keys(world):
"""① 바로 · 품셈 · 직접 — 키 EQP{사용자}-#### · 원문번호 「개인 …」 · M01 과 안 겹침 · 날."""
me = world["personal"]
easy = _at(me, mym.create, _easy())["줄"]
assert easy["키"] == "EQP42-0001" and easy["원문번호"] == "개인 EQP42-0001"
assert set(easy["값"]) >= {"가격", "손료계수"} and "상각비계수" not in easy["값"]
assert easy["넣은날"] == easy["고친날"] and easy["출처"]["가격"] == "개인"
book = _at(me, mym.create, {"방식": "품셈"}, DIG)["줄"] # M01 기계 복사해 만들기(비율 → 계수)
m01_row = m01.loaded()[1].get(DIG)["값"]
for k in ("상각비계수", "정비비계수", "관리비계수", "손료계수"):
assert float(book["값"][k]) == float(m01_row[k]), k
direct = _at(me, mym.create, {"이름": NAME, "규격": "1㎾", "방식": "직접",
"시간당": {"노무비": 10, "재료비": 20, "경비": 30}}) # fmt: skip
assert direct["시간당"]["계"] == 60 and direct["시간당"]["직접"] is True
m01_eq = m01.loaded()[1]
for row in _at(me, mym.rows):
assert row["키"] not in m01_eq.index["EQ"] and row["원문번호"] not in m01_eq.numbers["EQ"]
assert [r["키"] for r in _at(me, mym.rows)] == ["EQP42-0001", "EQP42-0002", "EQP42-0003"]
assert {x["키"] for x in direct["같은이름"]} == {"EQP42-0001"} # 같은 이름 · 규격 알림
for bad in ({"이름": ""}, {**_easy(), "값": {"가격": 1}}, {**_easy(가격=-1)},
{**_easy(주연료종류="물")}, {**_easy(조종원직종="없음")}): # fmt: skip
with pytest.raises(store.StoreError):
_at(me, mym.create, bad)
def test_hourly_same_as_m01(world):
"""② 굴착기 1.0㎥ 값을 내 기계로(바로 · 품셈) → 시간당 = M01 기계 · 식은 채운 칸으로."""
me = world["personal"]
want = mh.hourly(DIG)
for how in ("바로", "품셈"):
got = _at(me, mym.create, {"방식": how}, DIG)
hour = _at(me, mh.hourly, got["줄"]["키"])
assert hour["ok"] and hour["로직"] == "GC000268", how
for k in ("노무비", "재료비", "경비", "계"):
assert hour[k] == want[k], (how, k)
loss = _at(me, mym.create, _easy(주연료=0, 조종원=0))["시간당"]
assert loss["로직"] == "GC000273" and loss["계"] == loss["경비"] == 200 # 1000×1000×2000/10⁷
assert _at(me, mym.create, _easy(조종원=0))["시간당"]["로직"] == "GC000272"
assert _at(me, mym.create, _easy(주연료=0))["시간당"]["로직"] == "GC000276"
def test_find_and_other_layer_hidden(world):
"""③ 기계 찾기 = 그 층 내 기계도 · 남의 층 · 층 모르는 길 = M01 만."""
me, other = world["personal"], layers.personal_dir(7, 43)
key = _at(me, mym.create, _easy())["줄"]["키"]
got = _at(me, mfind.find, NAME, "1㎾")
assert got["판정"] == mfind.LINKED and got["키"] == key
assert _at(other, mfind.find, NAME, "1㎾")["판정"] == mfind.NONE
assert _at(other, mh.hourly, key)["ok"] is False
assert mh.hourly(key)["ok"] is False # 층 모르는 길
assert key not in _at(other, skc.whole_).index["EQ"]
def test_sk_copy_edit_refresh_delete(world):
"""④ 만들 때 사본에 박힘 → 고쳐도 그대로 + 새값 → [단가 갱신] 반영 → 지워도 마지막 값 · 층 복사."""
me = world["personal"]
made = _at(me, mym.create, _easy())
key, no = made["줄"]["키"], made["줄"]["원문번호"]
sk = _sk(me, no)
copy = _doc(me, sk)["사본"]
assert key in {r["키"] for r in copy["단가"]}
was = _sum(me, sk)
assert float(was) == made["시간당"]["계"]
assert _at(me, mym.one, key)["쓰는곳"] == [{"키": sk, "이름": "sub3임시 내기계"}]
_at(me, mym.update, key, _easy(가격=3000)) # 고침
now = _calc(me, _doc(me, sk))
assert now["기준"]["계"] == was and now["사본"]["단가새값"] is True
assert now["사본"]["지운키"] == []
new = _at(me, mh.hourly, key)["계"]
look = _at(me, skc.preview, _doc(me, sk), skc.PRICE)
assert float(look["전"]["계"]) == float(was) and float(look["후"]["계"]) == new
assert [x["키"] for x in look["바뀐자원"]] == [key]
with store.at(me): # [저장] = 할일 적용
store.write("sangeun", sk, store.read("sangeun", sk)["판"], look["문서"])
assert float(_sum(me, sk)) == new
assert _calc(me, _doc(me, sk))["사본"]["단가새값"] is False
# 층 사이 복사 — 사본이 따라감(받은 층에 그 내 기계 없음 · 마지막 값)
other = layers.personal_dir(7, 43)
moved = _at(other, skc.settle, {**_doc(me, sk), "키": "SK-999999"})
assert float(_calc(other, moved)["기준"]["계"]) == new
gone = _at(me, mym.delete, key)
assert gone["쓰는곳"] == [{"키": sk, "이름": "sub3임시 내기계"}]
after = _calc(me, _doc(me, sk))
assert float(after["기준"]["계"]) == new and after["사본"]["지운키"] == [key]
look = _at(me, skc.preview, _doc(me, sk), skc.PRICE)
assert look["바뀐자원"] == [{"키": key, "이름": NAME, "지워짐": True}]
assert float(look["후"]["계"]) == new
def test_m01_only_sk_same(world):
"""⑤ 내 기계가 있는 층에서도 M01 만 쓰는 SK 금액 · 사본 같음 · 사본 모으기에 내 기계 안 낌."""
me, other = world["personal"], layers.personal_dir(7, 43)
base = {"이름": "sub3임시 M01", "단위": "㎡", "바탕": {"로직": PCT}, "더한줄": []}
plain = _at(other, lambda: refs.create("sangeun", base)["이름"])
_at(me, mym.create, _easy())
mine = _at(me, lambda: refs.create("sangeun", base)["이름"])
a, b = _doc(other, plain)["사본"], _doc(me, mine)["사본"]
assert json.dumps(a["단가"], sort_keys=True) == json.dumps(b["단가"], sort_keys=True)
assert a["판"] == b["판"] and _sum(other, plain) == _sum(me, mine)
def test_rights(world):
"""⑥ 남의 개인 층 = 403(일반) · 회사 관리자 = 됨 · 개인 층 밖 = 404."""
user = {"role": "USER", "company_id": 7, "user_id": 42}
boss = {"role": "ADMIN", "company_id": 7, "user_id": 1}
with pytest.raises(HTTPException) as e:
route._folder(user, "personal", "7/43", True)
assert e.value.status_code == 403
with pytest.raises(HTTPException) as e:
route._folder(user, "company", None, True)
assert e.value.status_code == 404
assert route._folder(user, "personal", None, True) == world["personal"]
assert route._folder(boss, "personal", "7/42") == world["personal"] # 맡은 회사 관리자 읽기
with pytest.raises(store.StoreError): # 개인 층 아닌 자리에서 만들기
_at(world["company"], mym.create, _easy())