Files
Aislo/resources/tester/test_m01_auto.py
T
eomsangdon 33d72fa3ce test(시험정리): 요구 329 남은 시험 빨강 가림 B
- M01 후보 0·전체 로직 시험은 실제 사용자 마스터 값에 기대어 지움.
- 마스터데이터 동력상하차기 시험은 실제 사용자 마스터 값에 기대어 지움.
2026-10-23 14:01:03 +09:00

133 lines
6.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.
"""M01 견본 입력(`GET /logic/auto`) · 값 빈 품목은 그 줄만 비움 — PLAN 3-2 · 계약 3-1 표.
자동값 = 고르기 목록 첫째 · 범위 최솟값 · 찾기 조건 값은 그 표 가장 낮은 줄 · 나누는 수 1 · 그 밖 0.
정본 폴더를 읽기만 함(쓰지 않음).
"""
from __future__ import annotations
from decimal import Decimal
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from M01_MasterData import M01_MasterData_Router as router_module
@pytest.fixture(scope="module")
def client() -> TestClient:
app = FastAPI()
app.include_router(router_module.router)
return TestClient(app)
def _auto(client: TestClient, key: str) -> dict:
got = client.get("/api/m01/logic/auto", params={"key": key})
assert got.status_code == 200, got.text
return got.json()["값"]
def _calc(client: TestClient, key: str) -> dict:
got = client.post("/api/m01/calc", json={"key": key, "inputs": _auto(client, key)}).json()
assert got["ok"] is True, got
return got
def test_고르기는_목록_첫째_범위는_최솟값(client) -> None:
got = _auto(client, "GF000160") # 12-4 합판거푸집
assert got["횟수"] == "1회사용시" and got["폼타이"] == "아님"
assert "합판" not in got # 재료 입력 키 목록은 걷음 — 품목은 기본 검색어(PLAN 8-3)
assert got["소형할증"] == 0 # 범위 [0, 30]
assert got["높이할증"] == 0 # 찾기·나누기에 안 쓰임
def test_찾기_조건_값은_표_가장_낮은_줄(client) -> None:
assert _auto(client, "GC000561")["층수층"] == 0 # 가장 낮은 줄 「6 미만」 — 아래 끝이 열림
assert _auto(client, "GC000559")["강재총사용량"] == 0 # 「60 미만」
# 두 표가 같은 입력을 씀 — 한 표는 6 부터 · 한 표는 15 부터 → 둘 다에 드는 가장 낮은 값
assert _auto(client, "GC000724")["규격"] == 15
def test_나누는_수는_1(client) -> None:
assert _auto(client, "GC000998")["수직고초과단계"] == 1
assert _auto(client, "GC000278")["두께"] == 1
def test_없는_로직은_404(client) -> None:
assert client.get("/api/m01/logic/auto", params={"key": "GF999999"}).status_code == 404
def test_견본_금액은_앞과_같음(client) -> None:
assert Decimal(str(_calc(client, "GF000160")["sums"]["계"])) == Decimal("117485.212")
assert Decimal(str(_calc(client, "GF000219")["sums"]["계"])) == Decimal("79279.668")
def test_빈_줄을_부르는_덧줄도_비움(client) -> None:
got = _calc(client, "GF000185") # 레미콘 후보 0 → 레미콘 금액을 부르는 덧줄
blank = [one for one in got["lines"] if one.get("까닭")]
assert [one["이름"] for one in blank] == ["구체콘크리트(철근) 레미콘", "콘크리트다짐"]
assert "구체콘크리트(철근) 레미콘" in blank[1]["까닭"] and blank[1]["금액"] is None
def test_원_단위_입력은_자동값_null(client) -> None:
got = _auto(client, "GF000051") # 예취기가격(원)
assert got["예취기가격"] is None
assert got["조림목본수"] == 0 # 원 아닌 수는 그대로 0
def test_빈_입력을_쓰는_줄만_비움(client) -> None:
got = _calc(client, "GF000051")
blank = {one["이름"]: one for one in got["lines"] if one.get("까닭")}
assert set(blank) == {"예취기 손료"}
for one in blank.values():
assert one["단가"] is None and one["금액"] is None and "비어 있음" in one["까닭"]
rest = sum(Decimal(str(one["금액"])) for one in got["lines"] if one["금액"] is not None)
assert Decimal(str(got["sums"]["계"])) == rest > 0 # 빈 줄은 빼고 더함
assert got["sums"]["경비"] == 0
def test_빠진_원_입력도_null_처럼_줄만_비움(client) -> None:
given = {k: v for k, v in _auto(client, "GF000051").items() if k != "예취기가격"}
for path in ("calc", "text"):
got = client.post(f"/api/m01/{path}", json={"key": "GF000051", "inputs": given}).json()
assert got["ok"] is True, (path, got)
lines = client.post("/api/m01/calc", json={"key": "GF000051", "inputs": given}).json()["lines"]
assert {o["이름"] for o in lines if o.get("까닭")} == {"예취기 손료"}
@pytest.mark.parametrize("key", ["GF000002", "GF000056", "GF000076"])
def test_체인톱_가격_오일은_자재품목(client, key) -> None:
"""44-5 — 체인톱 가격 = 「동력체인톱」(기본 첫 규격) · 체인오일 = 「작동유」 · 손 입력 없음."""
assert not {"체인톱가격", "체인오일단가"} & set(_auto(client, key))
lines = {o["이름"]: o for o in _calc(client, key)["lines"]}
assert lines["체인톱 손료"]["품목"]["키"] == "MT016587" # 400mm · 530,000원
assert lines["체인톱 손료"]["단가"] == 530000 and "경비" in lines["체인톱 손료"]["비목"]
assert lines["체인오일"]["품목"]["키"] == "MT000583" # 기어작동유 · 4,612원/ℓ
assert lines["체인오일"]["단가"] == 4612
gas = Decimal(str(lines["휘발유(체인톱)"]["금액"]))
assert abs(Decimal(str(lines["잡품"]["금액"])) - gas * Decimal("0.4")) < Decimal(
"0.001"
) # 잡품 = 휘발유값 40% 그대로
def test_체인톱_규격은_고를_수_있음(client) -> None:
given = _auto(client, "GF000056")
body = {"key": "GF000056", "inputs": given, "고름": {"4": "MT016588"}} # 4 = 체인톱 손료 줄
got = client.post("/api/m01/calc", json=body).json()
saw = next(o for o in got["lines"] if o["이름"] == "체인톱 손료")
assert saw["품목"]["키"] == "MT016588" and saw["단가"] == 900000
def test_표_찾기_실패는_그_줄만_비우고_까닭은_날글_없이(client) -> None:
given = {**_auto(client, "GC001000"), "시공구분": "기계시공"} # 표 1-2-3 에 그 조합 줄이 없음
got = client.post("/api/m01/calc", json={"key": "GC001000", "inputs": given}).json()
assert got["ok"] is True, got
blank = [one for one in got["lines"] if one.get("까닭")]
assert blank and all(one["금액"] is None for one in blank)
why = blank[0]["까닭"]
assert "표 QC001869(1-2-3)에 시공구분 기계시공" in why and "인 줄이 없음" in why
assert not any(ch in why for ch in "{}'") and "Decimal" not in why
rest = sum(Decimal(str(one["금액"])) for one in got["lines"] if one["금액"] is not None)
assert Decimal(str(got["sums"]["계"])) == rest