- 「구조물 관리」 컨테이너 삭제 · 「시스템 설정」을 모든 역할 맨 위 한 줄 · 통째로 접힘(attachCollapsible) - 안은 작은 카드(제목 + 한 줄 설명) 공용 양식 하나 · 역할로 숨김 - 시스템 관리자: 마스터 데이터 · 일위대가 조합 · 구조물 조합 · 구조물 옵션 · 도면 양식 - 회사 관리자 · 개인: 일위대가 조합 · 구조물 조합(마스터 읽기 · 회사 수정|읽기 · 개인 수정) - 카드 누르면 #/m02-master-template?open=…&root=… · 마스터 데이터는 M01 - 시험 test_b01_settings_cards 새로 · test_m02_layer_screen 옛 대시보드 카드 시험 뺌 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ly2oHAaTDYRjcniAmHR81z
109 lines
4.6 KiB
Python
109 lines
4.6 KiB
Python
"""B01 대시보드 「시스템 설정」 컨테이너 시험(27-3) — 화면 조작은 ORCA.
|
|
|
|
· 역할별 카드(제목 · 설명 · 이동 해시)를 Node 로 바로 돌림 — 가짜 DOM
|
|
· 모든 역할 맨 위 한 줄 · 통째로 접힘 · 「구조물 관리」 컨테이너 없음
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
PAGE = ROOT / "B01_Dashboard" / "B01_Dashboard_UI_Page.ts"
|
|
|
|
|
|
def _text(path: Path) -> str:
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
def _fn(src: str, name: str) -> str:
|
|
found = re.search(rf"^function {name}\([\s\S]*?^}}", src, re.M)
|
|
assert found, f"{name} 를 못 찾음"
|
|
return found.group(0)
|
|
|
|
|
|
def _cards(user: dict) -> list:
|
|
src = _text(PAGE)
|
|
script = (
|
|
"interface DashboardUser { role: string; is_master: boolean }\n"
|
|
"const ROUTES = { M01_MASTER_DATA: 'm01-master-data', M02_MASTER_TEMPLATE: 'm02-master-template' };\n"
|
|
"const L = (k: string) => k;\n"
|
|
"let went = '';\n"
|
|
"const navigateTo = (r: string, q?: Record<string, string>) =>"
|
|
" { went = r + (q ? '?' + new URLSearchParams(q) : ''); };\n"
|
|
"const mk = (): any => ({ children: [] as any[], textContent: '', className: '', on: null as any,"
|
|
" append(...c: any[]) { this.children.push(...c); },"
|
|
" addEventListener(_: string, f: any) { this.on = f; } });\n"
|
|
"const document = { createElement: () => mk() };\n"
|
|
+ _fn(src, "settingCard")
|
|
+ "\n"
|
|
+ _fn(src, "buildSystemSettingsPanel")
|
|
+ "\nconst user = JSON.parse(process.argv[1]);"
|
|
+ "\nconsole.log(JSON.stringify(buildSystemSettingsPanel(user).children.map((c: any) => {"
|
|
+ " c.on(); return [c.children[0].textContent, c.children[1].textContent,"
|
|
+ " decodeURIComponent(went)]; })));"
|
|
)
|
|
result = subprocess.run(
|
|
["node", "--experimental-strip-types", "--no-warnings",
|
|
"--input-type=module-typescript", "-e", script, json.dumps(user)],
|
|
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
|
) # fmt: skip
|
|
assert result.returncode == 0, result.stderr
|
|
return json.loads(result.stdout)
|
|
|
|
|
|
M02 = "m02-master-template"
|
|
READ_CO = (
|
|
"B01_Dashboard_PermMasterRead · B01_Dashboard_PermCompanyRead · B01_Dashboard_PermPersonalWrite"
|
|
)
|
|
WRITE_CO = READ_CO.replace("CompanyRead", "CompanyWrite")
|
|
|
|
|
|
@pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
|
def test_시스템_관리자_카드_다섯():
|
|
m = "B01_Dashboard_PermMasterWrite"
|
|
assert _cards({"role": "SYSTEM_ADMIN", "is_master": False}) == [
|
|
["B01_Dashboard_MasterElements", "B01_Dashboard_PermSourceRead", "m01-master-data"],
|
|
["B01_Dashboard_CardUnitCombo", m, f"{M02}?open=일위대가&root=master"],
|
|
["B01_Dashboard_CardStructCombo", m, f"{M02}?open=구조물조합&root=master"],
|
|
["B01_Dashboard_CardStructOption", m, f"{M02}?open=옵션&root=master"],
|
|
["B01_Dashboard_CardDrawing", m, f"{M02}?open=도면&root=master"],
|
|
]
|
|
|
|
|
|
@pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
|
def test_회사_관리자_개인_카드_둘():
|
|
company = [
|
|
["B01_Dashboard_CardUnitCombo", WRITE_CO, f"{M02}?open=일위대가&root=company"],
|
|
["B01_Dashboard_CardStructCombo", WRITE_CO, f"{M02}?open=구조물조합&root=company"],
|
|
]
|
|
assert _cards({"role": "ADMIN", "is_master": False}) == company
|
|
assert _cards({"role": "USER", "is_master": True}) == company # 회사 마스터 = 회사 수정
|
|
assert _cards({"role": "USER", "is_master": False}) == [
|
|
["B01_Dashboard_CardUnitCombo", READ_CO, f"{M02}?open=일위대가&root=personal"],
|
|
["B01_Dashboard_CardStructCombo", READ_CO, f"{M02}?open=구조물조합&root=personal"],
|
|
]
|
|
|
|
|
|
def test_모든_역할_맨_위_통째로_접힘():
|
|
src = _text(PAGE)
|
|
build = _fn(src, "buildPage")
|
|
# 역할 갈래 앞에서 한 번 — 모든 역할 · 프로젝트 위
|
|
assert build.index("grid.append(buildSystemSettingsSection(state.user))") < build.index(
|
|
'if (state.user.role === "SYSTEM_ADMIN")'
|
|
)
|
|
assert "StructureManage" not in src and "buildStructurePanel" not in src
|
|
assert "top-row" not in src
|
|
sect = _fn(src, "buildSystemSettingsSection")
|
|
assert "buildSystemSettingsPanel(user), true)" in sect # 한 줄 통째
|
|
assert '"ui-collapsible"' in sect and '"ui-collapsible__title"' in sect
|
|
assert "attachCollapsible(card)" in sect
|
|
config = _text(ROOT / "config" / "config_frontend.ts")
|
|
assert re.search(r"PROTECTED_ROUTES[\s\S]*?ROUTES\.M02_MASTER_TEMPLATE,[\s\S]*?\];", config)
|