191 build - поправлены старые падения, проверены 3 матча и 6 агентов одновременных

This commit is contained in:
2026-10-21 13:41:47 +03:00
parent 787f880c0e
commit bf5e0d3101
52 changed files with 4024 additions and 730 deletions

View File

@@ -39,7 +39,51 @@ def test_editor_button_is_admin_only_and_hotkey_respects_it():
def test_editor_server_paths_are_admin_protected():
assert 'path == "/editor"' in APP_PY
assert 'path.startswith("/api/ui-builder/editor/")' in APP_PY
assert 'path.startswith("/api/ui-builder/auth/")' in APP_PY
assert '(khl_admin_path or editor_path) and not user.is_admin' in APP_PY
"""Execute the actual middleware with local identities; never import the live app."""
import ast
import asyncio
from types import SimpleNamespace
from fastapi import HTTPException
from fastapi.responses import JSONResponse, RedirectResponse
tree = ast.parse(APP_PY)
middleware = next(node for node in tree.body
if isinstance(node, ast.AsyncFunctionDef) and node.name == "hockey_runtime_auth")
middleware.decorator_list = []
current = SimpleNamespace(user=SimpleNamespace(is_admin=False))
async def optional_user(request):
return current.user
namespace = dict(hockey_auth=SimpleNamespace(optional_user=optional_user),
Request=object, HTTPException=HTTPException,
JSONResponse=JSONResponse, RedirectResponse=RedirectResponse,
apply_web_cache_policy=lambda request, response: response)
exec(compile(ast.fix_missing_locations(ast.Module(body=[middleware], type_ignores=[])),
"<production hockey_runtime_auth>", "exec"), namespace)
async def scenario():
async def following(request):
return JSONResponse({"allowed": True})
async def check(path, method, expected):
request = SimpleNamespace(url=SimpleNamespace(path=path), method=method,
state=SimpleNamespace())
response = await namespace["hockey_runtime_auth"](request, following)
assert response.status_code == expected, (path, method, response.body)
return response
assert (await check("/editor", "GET", 303)).headers["location"] == "/"
await check("/api/ui-builder/editor/config", "GET", 403)
await check("/api/ui-builder/auth/status", "GET", 403)
await check("/khl-site/api/players", "POST", 403)
await check("/khl-site/", "GET", 200)
await check("/", "GET", 200)
current.user = SimpleNamespace(is_admin=True)
await check("/editor", "GET", 200)
await check("/api/ui-builder/editor/config", "POST", 200)
current.user = None
assert (await check("/editor", "GET", 303)).headers["location"].startswith("/login")
await check("/api/ui-builder/auth/status", "GET", 401)
asyncio.run(scenario())