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
- 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.
139 lines
3.9 KiB
Python
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"
|