"""PLAN 815-2 — M01 요소 「별칭」 한 열(요구 764 · 765). ① 별칭 칸 저장 = 그 줄만 바뀜 · 앞뒤 빈칸 뗌 · 빈 글이면 칸 없음(임시 사본 폴더만) ② M01 길은 시스템 관리자만(아니면 403) ③ 마스터 기계 별칭 다섯 → 기계 줄 `별칭` · 옛 장부 파일 걷음 """ from __future__ import annotations import json import shutil from pathlib import Path import pytest from fastapi import Depends, FastAPI from fastapi.testclient import TestClient from common_util import common_util_auth as auth from M01_MasterData import M01_MasterData_Router as router_module from M01_MasterData import M01_MasterData_Store as store ROOT = Path(__file__).resolve().parents[2] REAL = store.FOLDER MACHINE = "기계.json" KEY = "EQ000001" FIVE = { "EQ000192": "아스팔트페이버(피니셔)", "EQ000193": "아스팔트페이버(피니셔)", **{f"EQ000{n}": "디젤 엔진" for n in range(497, 508)}, "EQ000400": "워터제트", "EQ000425": "버킷준설기", "EQ000248": "바이브레이트 봉상후렉시블", } @pytest.fixture def copy(tmp_path: Path, monkeypatch) -> Path: for path in REAL.glob("*.json"): if not path.name.startswith("_") or path.name == store.mk.BOOK.name: shutil.copy(path, tmp_path / path.name) monkeypatch.setattr(store, "FOLDER", tmp_path) return tmp_path def _app(role: str = "SYSTEM_ADMIN") -> TestClient: app = FastAPI() app.dependency_overrides[auth.verify_session] = lambda: { "user_id": 1, "name": "시험", "role": role, "company_id": 1, } deps = [Depends(auth.verify_session), Depends(auth.require_system_admin)] app.include_router(router_module.router, dependencies=deps) return TestClient(app) def _save_alias(client: TestClient, text: str) -> None: one = client.get("/api/m01/rows", params={"file": MACHINE, "q": KEY}).json() row = next(r for r in one["rows"] if r["키"] == KEY) part = { "file": MACHINE, "version": one["version"], "changes": [{"op": "edit", "key": KEY, "row": {**row, "별칭": text}}], } res = client.post("/api/m01/save", json={"files": [part]}) assert res.status_code == 200, res.text def _around(text: str) -> tuple[str, str, str]: """(그 줄 앞 글, 그 줄 글, 뒤 글).""" start = text.rfind("{", 0, text.index(f'"키": "{KEY}"')) _, end = json.JSONDecoder().raw_decode(text, start) return text[:start], text[start:end], text[end:] def test_별칭_저장_그_줄만_빈칸이면_칸_없음(copy: Path) -> None: client = _app() before = (copy / MACHINE).read_bytes() _save_alias(client, " 시험별칭A, 시험별칭B ") after = (copy / MACHINE).read_bytes().decode("utf-8") row = next(r for r in json.loads(after)["줄"] if r["키"] == KEY) assert row["별칭"] == "시험별칭A, 시험별칭B" # 글 그대로 · 앞뒤 빈칸만 뗌 old, new = _around(before.decode("utf-8")), _around(after) assert old[0] == new[0] and old[2] == new[2] # 그 줄 밖 글 · 서식 그대로 assert json.loads(new[1]) == {**json.loads(old[1]), "별칭": "시험별칭A, 시험별칭B"} _save_alias(client, " ") last = _around((copy / MACHINE).read_bytes().decode("utf-8")) assert last[0] == old[0] and last[2] == old[2] assert json.loads(last[1]) == json.loads(old[1]) # 빈 글 = 칸 없음 = 처음 값 def test_M01_길은_시스템_관리자만() -> None: for role in ("USER", "COMPANY_ADMIN"): res = _app(role).post("/api/m01/save", json={"files": []}) assert res.status_code == 403 main = (ROOT / "main.py").read_text(encoding="utf-8") assert "include_router(m01_master_data_router, dependencies=system_admin_only)" in main def test_마스터_기계_별칭_다섯_옮김_장부_걷음() -> None: rows = {r["키"]: r for r in json.loads((REAL / MACHINE).read_text(encoding="utf-8"))["줄"]} assert {k: r.get("별칭") for k, r in rows.items() if r.get("별칭")} == FIVE assert not (ROOT / "resources" / "master_template" / "실무자료" / "맞춤.json").exists()