76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
|
|
"""
|
||
|
|
Geschützte Übungs-Mediendatei: Auth + Governance (kein anonymes /media/).
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import os
|
||
|
|
from unittest.mock import MagicMock, patch
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from fastapi.testclient import TestClient
|
||
|
|
|
||
|
|
os.environ.setdefault("SKIP_DB_MIGRATE", "1")
|
||
|
|
|
||
|
|
from auth import require_auth_flexible
|
||
|
|
from main import app
|
||
|
|
from tenant_context import TenantContext, get_tenant_context_flexible
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def client() -> TestClient:
|
||
|
|
return TestClient(app)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture(autouse=True)
|
||
|
|
def _clear_overrides():
|
||
|
|
yield
|
||
|
|
app.dependency_overrides.pop(require_auth_flexible, None)
|
||
|
|
app.dependency_overrides.pop(get_tenant_context_flexible, None)
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_media_file_unauthenticated_401(client: TestClient) -> None:
|
||
|
|
r = client.get("/api/exercises/1/media/2/file")
|
||
|
|
assert r.status_code == 401
|
||
|
|
|
||
|
|
|
||
|
|
def test_exercise_media_file_forbidden_when_not_visible(client: TestClient) -> None:
|
||
|
|
app.dependency_overrides[get_tenant_context_flexible] = lambda: TenantContext(
|
||
|
|
profile_id=22,
|
||
|
|
global_role="trainer",
|
||
|
|
effective_club_id=None,
|
||
|
|
club_ids=frozenset(),
|
||
|
|
memberships=[],
|
||
|
|
)
|
||
|
|
|
||
|
|
mock_cm = MagicMock()
|
||
|
|
mock_conn = MagicMock()
|
||
|
|
mock_cm.__enter__.return_value = mock_conn
|
||
|
|
mock_cm.__exit__.return_value = False
|
||
|
|
mock_cur = MagicMock()
|
||
|
|
mock_cur.fetchone.return_value = {
|
||
|
|
"id": 3,
|
||
|
|
"visibility": "private",
|
||
|
|
"club_id": None,
|
||
|
|
"created_by": 99,
|
||
|
|
}
|
||
|
|
|
||
|
|
with patch("routers.exercises.get_db", return_value=mock_cm), patch(
|
||
|
|
"routers.exercises.get_cursor", return_value=mock_cur
|
||
|
|
), patch("routers.exercises.library_content_visible_to_profile", return_value=False):
|
||
|
|
r = client.get("/api/exercises/3/media/2/file", headers={"X-Auth-Token": "t"})
|
||
|
|
assert r.status_code == 403
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_maturity_model_requires_admin(client: TestClient) -> None:
|
||
|
|
from auth import require_auth
|
||
|
|
|
||
|
|
def _user() -> dict:
|
||
|
|
return {"profile_id": 1, "role": "trainer"}
|
||
|
|
|
||
|
|
app.dependency_overrides[require_auth] = _user
|
||
|
|
try:
|
||
|
|
r = client.get("/api/maturity-models/1", headers={"X-Auth-Token": "x"})
|
||
|
|
assert r.status_code == 403
|
||
|
|
finally:
|
||
|
|
app.dependency_overrides.pop(require_auth, None)
|