"""Unit tests ohne Datenbank für die Zugriffsschicht (Visibility-SQL, Header-Parsing).""" import pytest from fastapi import HTTPException from tenant_context import library_content_visibility_sql, parse_active_club_header, resolve_tenant_context def test_library_visibility_sql_platform_admin_no_filter(): sql, params = library_content_visibility_sql( alias="e", profile_id=1, role="admin", effective_club_id=None, ) assert sql == "TRUE" assert params == [] def test_library_visibility_sql_superadmin(): sql, params = library_content_visibility_sql( alias="fp", profile_id=2, role="superadmin", effective_club_id=100, ) assert sql == "TRUE" assert params == [] def test_library_visibility_sql_trainer_without_active_club_no_shared_club_branch(): sql, params = library_content_visibility_sql( alias="g", profile_id=42, role="trainer", effective_club_id=None, ) assert "official" in sql assert "private" in sql assert "visibility = 'club'" not in sql assert params == [42] def test_library_visibility_sql_user_with_active_club_includes_club_branch(): sql, params = library_content_visibility_sql( alias="t", profile_id=7, role="user", effective_club_id=99, ) assert "visibility = 'club'" in sql assert "club_members" in sql assert params[0] == 7 # private branch created_by assert 99 in params assert params.count(7) >= 2 # private + EXISTS membership def test_parse_active_club_header_none_and_empty(): assert parse_active_club_header(None) is None assert parse_active_club_header("") is None assert parse_active_club_header(" ") is None def test_parse_active_club_header_valid(): assert parse_active_club_header("12") == 12 def test_parse_active_club_header_invalid(): with pytest.raises(HTTPException) as exc: parse_active_club_header("not-int") assert exc.value.status_code == 400 def test_parse_active_club_header_non_positive(): with pytest.raises(HTTPException) as exc: parse_active_club_header("0") assert exc.value.status_code == 400 def test_resolve_platform_admin_uses_stored_club_without_header(monkeypatch): """Ohne X-Active-Club-Id: effective wie gespeichertes Profil (Sync mit Dropdown/DB).""" cur = object() def fake_exists(c, cid): return cid == 99 monkeypatch.setattr("tenant_context._club_exists", fake_exists) ctx = resolve_tenant_context( cur, profile_id=1, global_role="admin", header_raw=None, memberships=[{"id": 10}], stored_active_club_id=99, ) assert ctx.effective_club_id == 99 def test_resolve_platform_admin_header_overrides_stored(monkeypatch): cur = object() def fake_exists(c, cid): return cid in (5, 99) monkeypatch.setattr("tenant_context._club_exists", fake_exists) ctx = resolve_tenant_context( cur, profile_id=1, global_role="superadmin", header_raw="5", memberships=[{"id": 10}], stored_active_club_id=99, ) assert ctx.effective_club_id == 5 def test_resolve_platform_admin_no_header_stored_invalid(monkeypatch): cur = object() monkeypatch.setattr("tenant_context._club_exists", lambda c, cid: False) ctx = resolve_tenant_context( cur, profile_id=1, global_role="admin", header_raw=None, memberships=[{"id": 1}], stored_active_club_id=123, ) assert ctx.effective_club_id is None