"""Tests for the AnalyticsService class.""" from datetime import date, timedelta from sqlmodel import SQLModel, Session, create_engine from app.models.user import User from app.models.exercise import Exercise from app.models.workout_day import WorkoutDay from app.models.workout_session import WorkoutSession from app.models.workout_log import WorkoutLog from app.services.analytics_service import AnalyticsService class TestAnalyticsService: """Tests for analytics data aggregation.""" def _setup(self): """Create DB with sessions and logs for analytics.""" engine = create_engine("sqlite:///:memory:") SQLModel.metadata.create_all(engine) session = Session(engine) user = User(username="phil", password_hash="h", display_name="Phillip") day = WorkoutDay(name="Push", day_number=1, description="Push day") exercise = Exercise( name="DB Chest Press", muscle_group="Chest", workout_day="Push", sets=3, tempo="3-1-2", form_cues="...", ) session.add_all([user, day, exercise]) session.commit() session.refresh(user) session.refresh(day) session.refresh(exercise) # Create 3 sessions over 3 weeks for week in range(3): ws = WorkoutSession( user_id=user.id, workout_day_id=day.id, date=date.today() - timedelta(days=(2 - week) * 7), ) session.add(ws) session.commit() session.refresh(ws) for set_num in range(1, 4): session.add(WorkoutLog( session_id=ws.id, exercise_id=exercise.id, set_number=set_num, reps_completed=8 + week, weight_used="30 lbs", felt_easy=(week == 2), )) session.commit() service = AnalyticsService(session) return session, service, user, exercise def test_get_total_sessions(self) -> None: """Should return the total number of sessions for a user.""" session, service, user, exercise = self._setup() stats = service.get_user_stats(user.id) assert stats["total_sessions"] == 3 session.close() def test_get_total_volume(self) -> None: """Should calculate total volume (sets x reps x weight).""" session, service, user, exercise = self._setup() stats = service.get_user_stats(user.id) assert stats["total_volume"] > 0 session.close() def test_get_workout_streak(self) -> None: """Should calculate consecutive workout weeks.""" session, service, user, exercise = self._setup() stats = service.get_user_stats(user.id) assert stats["current_streak"] >= 1 session.close() def test_get_exercise_progress_data(self) -> None: """Should return chart-ready data for an exercise.""" session, service, user, exercise = self._setup() data = service.get_exercise_progress(user.id, exercise.id) assert "dates" in data assert "reps" in data assert "weights" in data assert len(data["dates"]) == 3 session.close() def test_get_volume_by_day(self) -> None: """Should return volume per workout day for charts.""" session, service, user, exercise = self._setup() data = service.get_volume_by_day(user.id) assert "Push" in data assert data["Push"] > 0 session.close()