43 lines
1.9 KiB
Python
43 lines
1.9 KiB
Python
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
APP = (ROOT / "app" / "web_app_fastapi.py").read_text(encoding="utf-8")
|
|
INDEX = (ROOT / "app" / "templates" / "index.html").read_text(encoding="utf-8")
|
|
ADMIN = (ROOT / "app" / "templates" / "admin_tools.html").read_text(encoding="utf-8")
|
|
COMPOSE = (ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
|
|
|
|
|
def test_upload_contract_keeps_os_type_and_adds_optional_profile_id():
|
|
for function_name in ("api_upload_async", "upload_files", "api_upload_files"):
|
|
function = APP.split(f"async def {function_name}(", 1)[1].split("):", 1)[0]
|
|
assert "os_type: str = Form(...)" in function
|
|
assert "profile_id: Optional[str] = Form(None)" in function
|
|
|
|
|
|
def test_registry_mutations_are_admin_guarded_and_analyzer_remains_tool_only():
|
|
for function_name in (
|
|
"registry_create_category_v2", "registry_create_component_v2", "registry_create_profile_v2",
|
|
"registry_upload_version_v2", "registry_activate_v2", "registry_rollback_v2",
|
|
):
|
|
function = APP.split(f"async def {function_name}(", 1)[1].split("@app.", 1)[0]
|
|
assert "_admin_or_403(request)" in function
|
|
tool_upload = APP.split("async def admin_upload_tool(", 1)[1].split("@app.", 1)[0]
|
|
assert "require_tool_manager_session(request)" in tool_upload
|
|
|
|
|
|
def test_audit_and_admin_ui_expose_profile_registry_by_role():
|
|
assert 'name="profile_id"' in INDEX
|
|
assert "active_profiles" in INDEX
|
|
admin_block = ADMIN.split("user_info.role == 'admin'", 1)[1]
|
|
assert "profile-registry" in admin_block
|
|
assert "registry_upload_version_v2" in admin_block
|
|
assert "registry_activate_v2" in admin_block
|
|
assert "registry_rollback_v2" in admin_block
|
|
|
|
|
|
def test_registry_uses_persistent_config_mount():
|
|
assert "./config:/app/config" in COMPOSE
|
|
assert "./registry:/app/registry" in COMPOSE
|
|
assert "AUDIT_REGISTRY_ROOT=/app/registry" in COMPOSE
|