""" 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)