shinkan-jinkendo/backend/tests/test_club_feature_exemptions.py
Lars 8404a42b6c
Some checks failed
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Failing after 2s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 42s
Test Suite / playwright-tests (push) Successful in 1m19s
Implement Club Feature Quota Bypass and Update Versioning
- Added support for club feature quota bypass based on portal roles and profile grants in the capabilities check.
- Introduced new functions to handle quota bypass logic in club feature access and consumption.
- Updated the FeatureUsageBadge component to reflect platform exemptions for features.
- Incremented application version to 0.8.195 and database schema version to 20260606083 to reflect these changes.
- Enhanced backend routers to include new logic for consuming club features during AI-related actions.
2026-06-07 07:43:35 +02:00

139 lines
3.9 KiB
Python

"""Kontingent-Bypass über Capability-Grants (kein Env-Hardcoding)."""
import pytest
from club_quota_bypass import (
QUOTA_BYPASS_ALL,
is_club_feature_quota_bypassed,
quota_bypass_access,
)
from club_features import consume_club_feature, probe_club_feature_access
class _FakeCur:
def __init__(self, *, portal_grants=None, profile_grants=None):
self._portal_grants = set(portal_grants or ())
self._profile_grants = set(profile_grants or ())
self._last_sql = ""
self._last_params = ()
def execute(self, sql, params=None):
self._last_sql = (sql or "").lower()
self._last_params = params or ()
def fetchone(self):
if "portal_role_capability_grants" in self._last_sql:
role, cap = self._last_params[:2]
if (role, cap) in self._portal_grants:
return {"1": 1}
if "profile_capability_grants" in self._last_sql:
pid, cap = self._last_params[:2]
if (int(pid), cap) in self._profile_grants:
return {"1": 1}
return None
def fetchall(self):
return []
def test_portal_role_grant_bypasses():
cur = _FakeCur(portal_grants={("superadmin", QUOTA_BYPASS_ALL)})
assert is_club_feature_quota_bypassed(
cur, profile_id=1, portal_role="superadmin", feature_id="ai_calls"
)
assert not is_club_feature_quota_bypassed(
cur, profile_id=1, portal_role="trainer", feature_id="ai_calls"
)
def test_profile_grant_bypasses():
cap = "platform.club_quota.bypass.ai_calls"
cur = _FakeCur(profile_grants={(42, cap)})
assert is_club_feature_quota_bypassed(
cur, profile_id=42, portal_role="trainer", feature_id="ai_calls"
)
def test_probe_superadmin_bypasses_enforce(monkeypatch):
monkeypatch.setenv("CLUB_FEATURE_ENFORCE", "1")
monkeypatch.setattr("club_feature_logger.log_club_feature_usage", lambda **kwargs: None)
class Cur:
def execute(self, *a, **k):
pass
def fetchone(self):
return {"1": 1}
def fetchall(self):
return []
monkeypatch.setattr("club_features.get_cursor", lambda c: Cur())
monkeypatch.setattr(
"club_features.get_effective_club_plan",
lambda cur, club_id: "free",
)
monkeypatch.setattr(
"club_quota_bypass._portal_role_has_grant",
lambda cur, role, cap: role == "superadmin",
)
monkeypatch.setattr(
"club_quota_bypass._profile_has_grant",
lambda cur, pid, cap: False,
)
access = probe_club_feature_access(
feature_id="ai_calls",
action="suggest",
club_id=5,
profile_id=1,
portal_role="superadmin",
conn=object(),
)
assert access["allowed"] is True
assert access["reason"] == "capability_quota_bypass"
def test_consume_skips_for_bypass_grant(monkeypatch):
calls = []
monkeypatch.setattr(
"club_features.increment_club_feature_usage",
lambda *a, **k: calls.append(1),
)
class Cur:
def execute(self, *a, **k):
pass
def fetchone(self):
return {"1": 1}
def fetchall(self):
return []
monkeypatch.setattr("club_features.get_cursor", lambda c: Cur())
monkeypatch.setattr(
"club_quota_bypass._portal_role_has_grant",
lambda cur, role, cap: role == "superadmin",
)
monkeypatch.setattr(
"club_quota_bypass._profile_has_grant",
lambda cur, pid, cap: False,
)
consume_club_feature(
feature_id="ai_calls",
club_id=9,
profile_id=1,
portal_role="superadmin",
conn=object(),
)
assert calls == []
def test_quota_bypass_access_shape():
row = quota_bypass_access(feature_id="ai_calls", club_id=3, plan_id="free")
assert row["platform_exempt"] is True
assert row["limit"] is None
assert row["allowed"] is True
assert row["reason"] == "capability_quota_bypass"