"""Tests für club_feature_logger und probe (ohne DB).""" import json from club_feature_logger import feature_usage_logger, log_club_feature_usage from club_features import club_feature_enforcement_enabled, probe_club_feature_access def test_log_club_feature_usage_json(monkeypatch): captured = [] monkeypatch.setattr(feature_usage_logger, "info", lambda msg: captured.append(msg)) access = { "allowed": False, "limit": 0, "used": 3, "remaining": 0, "reason": "feature_disabled", "plan_id": "free", } log_club_feature_usage( club_id=12, profile_id=7, feature_id="ai_calls", action="suggest", access=access, endpoint="POST /exercises/ai/suggest", ) assert captured payload = json.loads(captured[-1]) assert payload["club_id"] == 12 assert payload["profile_id"] == 7 assert payload["feature"] == "ai_calls" assert payload["allowed"] is False assert payload["plan_id"] == "free" assert payload["phase"] == "probe" def test_probe_no_club_context_logs_without_db(monkeypatch): # CI/Deploy kann CLUB_FEATURE_ENFORCE=1 setzen — Test prüft Probe-Modus (kein Hard-Block). monkeypatch.delenv("CLUB_FEATURE_ENFORCE", raising=False) logged = [] def _capture(**kwargs): logged.append(kwargs) monkeypatch.setattr("club_feature_logger.log_club_feature_usage", _capture) access = probe_club_feature_access( feature_id="ai_calls", action="suggest", club_id=None, profile_id=1, endpoint="test", ) assert access["reason"] == "no_club_context" assert access["allowed"] is True assert len(logged) == 1 assert logged[0]["club_id"] is None def test_club_feature_enforcement_default_off(monkeypatch): monkeypatch.delenv("CLUB_FEATURE_ENFORCE", raising=False) assert club_feature_enforcement_enabled() is False monkeypatch.setenv("CLUB_FEATURE_ENFORCE", "1") assert club_feature_enforcement_enabled() is True