"""Feature-Enforcement für Legacy Activity CSV-Import (#37).""" from unittest.mock import AsyncMock, patch import pytest from fastapi import HTTPException from routers.activity import import_activity_csv @pytest.mark.asyncio async def test_import_activity_csv_blocks_when_limit_reached(): upload = AsyncMock() upload.read = AsyncMock(return_value=b"Workout Type,Start\n") with patch("routers.activity.get_pid", return_value="profile-1"), patch( "routers.activity.check_feature_access", return_value={ "allowed": False, "reason": "limit_exceeded", "used": 30, "limit": 30, }, ), patch("routers.activity.log_feature_usage"): with pytest.raises(HTTPException) as exc: await import_activity_csv( file=upload, x_profile_id=None, session={"profile_id": "profile-1"}, ) assert exc.value.status_code == 403 @pytest.mark.asyncio async def test_import_activity_csv_increments_usage_per_insert(monkeypatch): upload = AsyncMock() upload.read = AsyncMock( return_value=( "Workout Type,Start,Duration,Aktive Energie (kJ),Ruheeinträge (kJ)," "Durchschn. Herzfrequenz (count/min),Max. Herzfrequenz (count/min),Distanz (km),End\n" "Running,2026-07-22 10:00:00 +0200,0:45:00,1000,500,140,160,5.0,\n" ).encode("utf-8") ) increments = [] class FakeCursor: def execute(self, *args, **kwargs): return None def fetchone(self): return None class FakeConn: def __enter__(self): return self def __exit__(self, *args): return False fake_cur = FakeCursor() monkeypatch.setattr("routers.activity.get_pid", lambda _h: "profile-1") monkeypatch.setattr( "routers.activity.check_feature_access", lambda *_a, **_k: {"allowed": True, "reason": "ok", "used": 0, "limit": 100}, ) monkeypatch.setattr("routers.activity.log_feature_usage", lambda *_a, **_k: None) monkeypatch.setattr("routers.activity.get_db", lambda: FakeConn()) monkeypatch.setattr("routers.activity.get_cursor", lambda _c: fake_cur) monkeypatch.setattr( "routers.activity.normalize_activity_start", lambda _s: ("2026-07-22", "10:00:00"), ) monkeypatch.setattr( "routers.activity.get_training_type_for_activity", lambda *_a, **_k: (1, "cardio", None), ) monkeypatch.setattr( "routers.activity.find_activity_duplicate_id", lambda *_a, **_k: None, ) monkeypatch.setattr( "routers.activity.new_activity_id", lambda: "new-id", ) monkeypatch.setattr( "routers.activity.insert_activity_csv_minimal", lambda *_a, **_k: None, ) monkeypatch.setattr( "routers.activity.run_activity_post_write_hooks_import", lambda *_a, **_k: None, ) monkeypatch.setattr( "routers.activity.increment_feature_usage", lambda _pid, feature: increments.append(feature), ) result = await import_activity_csv( file=upload, x_profile_id=None, session={"profile_id": "profile-1"}, ) assert result["inserted"] == 1 assert increments == ["activity_entries"]