"""Tests for the LogService class.""" from datetime import date 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.log_service import LogService class TestLogService: """Tests for workout log CRUD operations.""" def _setup(self): """Create an in-memory DB with prerequisite data.""" engine = create_engine("sqlite:///:memory:") SQLModel.metadata.create_all(engine) session = Session(engine) user = User(username="phil", 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) ws = WorkoutSession( user_id=user.id, workout_day_id=day.id, date=date.today(), ) session.add(ws) session.commit() session.refresh(ws) service = LogService(session) return session, service, ws, exercise def test_create_log_entry(self) -> None: """create_log should insert a new log entry.""" session, service, ws, exercise = self._setup() log = service.create_log( session_id=ws.id, exercise_id=exercise.id, set_number=1, reps_completed=8, weight_used="30 lbs", felt_easy=False, ) assert log.id is not None assert log.reps_completed == 8 session.close() def test_list_logs_for_session(self) -> None: """list_logs_for_session should return all logs for a session.""" session, service, ws, exercise = self._setup() service.create_log(ws.id, exercise.id, 1, 8, "30 lbs", False) service.create_log(ws.id, exercise.id, 2, 8, "30 lbs", False) service.create_log(ws.id, exercise.id, 3, 7, "30 lbs", True) logs = service.list_logs_for_session(ws.id) assert len(logs) == 3 session.close() def test_list_logs_for_exercise_in_session(self) -> None: """list_logs_for_exercise should filter by exercise within a session.""" session, service, ws, exercise = self._setup() service.create_log(ws.id, exercise.id, 1, 8, "30 lbs", False) logs = service.list_logs_for_exercise(ws.id, exercise.id) assert len(logs) == 1 session.close() def test_update_log(self) -> None: """update_log should modify an existing log entry.""" session, service, ws, exercise = self._setup() log = service.create_log(ws.id, exercise.id, 1, 8, "30 lbs", False) updated = service.update_log(log.id, reps_completed=10, felt_easy=True) assert updated.reps_completed == 10 assert updated.felt_easy is True session.close() def test_delete_log(self) -> None: """delete_log should remove a log entry.""" session, service, ws, exercise = self._setup() log = service.create_log(ws.id, exercise.id, 1, 8, "30 lbs", False) service.delete_log(log.id) logs = service.list_logs_for_session(ws.id) assert len(logs) == 0 session.close() def test_get_latest_logs_for_exercise(self) -> None: """get_latest_logs should return the most recent logs for an exercise.""" session, service, ws, exercise = self._setup() service.create_log(ws.id, exercise.id, 1, 8, "30 lbs", False) service.create_log(ws.id, exercise.id, 2, 8, "30 lbs", True) logs = service.get_latest_logs_for_exercise( user_id=ws.user_id, exercise_id=exercise.id, ) assert len(logs) >= 1 session.close()