낡은 시험 고침: test_m01_api · test_m01_cache · test_m01_logic_flow_save · test_208_1_logic_alias · test_m01_logic_flow_project 가 임시 사본의 정본 로직 줄을 고쳐 저장 — 이제 개정 확인이 필요하므로 몸에 개정확인 true(뜻 그대로) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
104 lines
4.5 KiB
Python
104 lines
4.5 KiB
Python
"""713-1 지킴 — 로직 정본 줄 고침 · 지우기 · 더하기는 「원문 개정 반영」 확인(`개정확인`) 없이는 409 ·
|
|
요소 · 같은 줄 다시 보냄은 그대로 · 줄 바탕 지문(`Store_Revise.row_print`). 임시 사본 폴더만 씀."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
from M01_MasterData import M01_MasterData_Router as router_module
|
|
from M01_MasterData import M01_MasterData_Store as store
|
|
from M01_MasterData import M01_MasterData_Store_Revise as revise
|
|
|
|
REAL = store.FOLDER
|
|
KEY = "GC000091" # 공통 3-3-1 암발파 — 로직_건설품셈_03장_토공사.json
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def client(tmp_path_factory) -> TestClient:
|
|
folder = tmp_path_factory.mktemp("m01_revise")
|
|
for path in REAL.glob("*.json"):
|
|
if not path.name.startswith("_") or path.name == store.mk.BOOK.name:
|
|
shutil.copy(path, folder / path.name)
|
|
patch = pytest.MonkeyPatch()
|
|
patch.setattr(store, "FOLDER", folder)
|
|
app = FastAPI()
|
|
app.include_router(router_module.router)
|
|
yield TestClient(app)
|
|
patch.undo()
|
|
|
|
|
|
def _part(client: TestClient, op: str, row: dict | None = None, key: str | None = KEY) -> dict:
|
|
one = client.get("/api/m01/logic", params={"key": KEY}).json()
|
|
return {
|
|
"file": one["file"],
|
|
"version": one["version"],
|
|
"changes": [{"op": op, "key": key, "row": row}],
|
|
}
|
|
|
|
|
|
def _bytes(client: TestClient) -> bytes:
|
|
return (
|
|
store.FOLDER / client.get("/api/m01/logic", params={"key": KEY}).json()["file"]
|
|
).read_bytes()
|
|
|
|
|
|
def test_정본_고침_지움_더함_확인_없으면_409(client: TestClient) -> None:
|
|
base = client.get("/api/m01/logic", params={"key": KEY}).json()["logic"]
|
|
before = _bytes(client)
|
|
for op, row, key in (
|
|
("edit", {**base, "비고": "개정 시험"}, KEY),
|
|
("delete", None, KEY),
|
|
("add", {k: v for k, v in base.items() if k != "키"}, None),
|
|
):
|
|
res = client.post("/api/m01/save", json={"files": [_part(client, op, row, key)]})
|
|
assert res.status_code == 409, (op, res.text)
|
|
got = res.json()["detail"]
|
|
assert got["개정"][0]["op"] == op and "원문 개정 반영" in got["까닭"]
|
|
assert _bytes(client) == before # 확인 없이는 한 바이트도 안 바뀜
|
|
|
|
|
|
def test_같은_줄_다시_보냄은_그대로(client: TestClient) -> None:
|
|
base = client.get("/api/m01/logic", params={"key": KEY}).json()["logic"]
|
|
res = client.post("/api/m01/save", json={"files": [_part(client, "edit", base)]})
|
|
assert res.status_code == 200, res.text
|
|
|
|
|
|
def test_확인하면_저장_지문은_계산_칸만(client: TestClient) -> None:
|
|
one = client.get("/api/m01/logic", params={"key": KEY}).json()
|
|
base, print0 = one["logic"], one["지문"]
|
|
assert print0 == revise.row_print(base)
|
|
body = {"files": [_part(client, "edit", {**base, "비고": "개정 시험"})], "개정확인": True}
|
|
assert client.post("/api/m01/save", json=body).status_code == 200
|
|
again = client.get("/api/m01/logic", params={"key": KEY}).json()
|
|
assert again["logic"]["비고"] == "개정 시험" and again["지문"] == print0 # 비고 = 지문 밖
|
|
hop = [dict(x) for x in base["호표"]]
|
|
hop[0]["수량"] = f"({hop[0]['수량']}) * 2"
|
|
body = {"files": [_part(client, "edit", {**again["logic"], "호표": hop})], "개정확인": True}
|
|
assert client.post("/api/m01/save", json=body).status_code == 200, "계산 칸 고침"
|
|
assert client.get("/api/m01/logic", params={"key": KEY}).json()["지문"] != print0
|
|
|
|
|
|
def test_요소_파일은_대상_밖(client: TestClient) -> None:
|
|
rows = client.get("/api/m01/rows", params={"file": "인력.json", "size": 1}).json()
|
|
row = {**rows["rows"][0], "비고": "요소 시험"}
|
|
part = {
|
|
"file": "인력.json",
|
|
"version": rows["version"],
|
|
"changes": [{"op": "edit", "key": row["키"], "row": row}],
|
|
}
|
|
assert client.post("/api/m01/save", json={"files": [part]}).status_code == 200
|
|
|
|
|
|
def test_지문_수_꼴_같음() -> None:
|
|
a = {"이름": "가", "호표": [{"수량": Decimal("10.0")}], "끝수": 1}
|
|
b = {"이름": "나", "호표": [{"수량": 10}], "끝수": 1.0, "별칭": "x"}
|
|
assert revise.row_print(a) == revise.row_print(b)
|
|
assert revise.is_canon("로직_산림품셈_09장_토공.json")
|
|
assert not revise.is_canon("로직_자체.json") and not revise.is_canon("인력.json")
|