"""Tests for SQLModel model definitions.""" from datetime import datetime from sqlmodel import SQLModel, Session, create_engine from app.models.user import User from app.models.exercise import Exercise from app.models.warmup import Warmup from app.models.workout_day import WorkoutDay from app.models.user_exercise_program import UserExerciseProgram from app.models.workout_session import WorkoutSession from app.models.workout_log import WorkoutLog from app.models.progress_log import ProgressLog class TestModels: """Tests that all models can be instantiated and persisted.""" def _create_engine(self): """Create an in-memory SQLite engine with all tables.""" engine = create_engine("sqlite:///:memory:") SQLModel.metadata.create_all(engine) return engine def test_user_model_roundtrip(self) -> None: """User model should persist and retrieve correctly.""" engine = self._create_engine() user = User( username="testuser", password_hash="fakehash", display_name="Test User", height="6'0\"", weight="200 lbs", goals="Get strong", is_admin=False, ) with Session(engine) as session: session.add(user) session.commit() session.refresh(user) assert user.id is not None assert user.username == "testuser" assert user.is_admin is False assert isinstance(user.created_at, datetime) def test_exercise_model_roundtrip(self) -> None: """Exercise model should persist and retrieve correctly.""" engine = self._create_engine() exercise = Exercise( name="DB Chest Press (Floor)", muscle_group="Chest", workout_day="Push", sets=3, tempo="3-1-2", form_cues="Lie on the floor...", ) with Session(engine) as session: session.add(exercise) session.commit() session.refresh(exercise) assert exercise.id is not None assert exercise.name == "DB Chest Press (Floor)" def test_warmup_model_roundtrip(self) -> None: """Warmup model should persist and retrieve correctly.""" engine = self._create_engine() warmup = Warmup( name="Cat / Cow", type="Thoracic Mob", reps="8 reps", form_cues="Start on hands and knees...", sort_order=1, ) with Session(engine) as session: session.add(warmup) session.commit() session.refresh(warmup) assert warmup.id is not None def test_workout_day_model_roundtrip(self) -> None: """WorkoutDay model should persist and retrieve correctly.""" engine = self._create_engine() day = WorkoutDay( name="Push", day_number=1, description="Chest, shoulders, triceps", ) with Session(engine) as session: session.add(day) session.commit() session.refresh(day) assert day.id is not None assert day.day_number == 1 def test_user_exercise_program_model_roundtrip(self) -> None: """UserExerciseProgram model should persist with FK references.""" engine = self._create_engine() with Session(engine) as session: user = User(username="u", password_hash="h", display_name="U") exercise = Exercise( name="Test Ex", muscle_group="Test", workout_day="Push", sets=3, tempo="3-1-2", form_cues="..." ) session.add(user) session.add(exercise) session.commit() session.refresh(user) session.refresh(exercise) program = UserExerciseProgram( user_id=user.id, exercise_id=exercise.id, wk1_reps="8", wk4_reps="12", wk1_weight="30 lbs", wk4_weight="40 lbs", ) session.add(program) session.commit() session.refresh(program) assert program.id is not None assert program.user_id == user.id def test_workout_session_model_roundtrip(self) -> None: """WorkoutSession model should persist correctly.""" engine = self._create_engine() with Session(engine) as session: user = User(username="u", password_hash="h", display_name="U") day = WorkoutDay(name="Push", day_number=1, description="Push day") session.add(user) session.add(day) session.commit() session.refresh(user) session.refresh(day) ws = WorkoutSession( user_id=user.id, workout_day_id=day.id, date=datetime.utcnow().date(), ) session.add(ws) session.commit() session.refresh(ws) assert ws.id is not None def test_workout_log_model_roundtrip(self) -> None: """WorkoutLog model should persist correctly.""" engine = self._create_engine() with Session(engine) as session: user = User(username="u", password_hash="h", display_name="U") day = WorkoutDay(name="Push", day_number=1, description="Push day") exercise = Exercise( name="Ex", muscle_group="Test", 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=datetime.utcnow().date(), ) session.add(ws) session.commit() session.refresh(ws) log = WorkoutLog( session_id=ws.id, exercise_id=exercise.id, set_number=1, reps_completed=8, weight_used="30 lbs", felt_easy=False, ) session.add(log) session.commit() session.refresh(log) assert log.id is not None assert log.felt_easy is False def test_progress_log_model_roundtrip(self) -> None: """ProgressLog model should persist correctly.""" engine = self._create_engine() with Session(engine) as session: user = User(username="u", password_hash="h", display_name="U") exercise = Exercise( name="Ex", muscle_group="Test", workout_day="Push", sets=3, tempo="3-1-2", form_cues="..." ) session.add_all([user, exercise]) session.commit() session.refresh(user) session.refresh(exercise) pl = ProgressLog( user_id=user.id, exercise_id=exercise.id, date=datetime.utcnow().date(), suggested_reps=10, suggested_weight="35 lbs", actual_reps=10, actual_weight="35 lbs", progression_applied="reps_increase", ) session.add(pl) session.commit() session.refresh(pl) assert pl.id is not None def test_all_models_importable_from_init(self) -> None: """All models should be importable from app.models.""" from app.models import ( User, Exercise, Warmup, WorkoutDay, UserExerciseProgram, WorkoutSession, WorkoutLog, ProgressLog, ) assert User is not None assert Exercise is not None assert Warmup is not None assert WorkoutDay is not None assert UserExerciseProgram is not None assert WorkoutSession is not None assert WorkoutLog is not None assert ProgressLog is not None