from pathlib import Path import pytest from cryptography.fernet import Fernet from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from sqlalchemy.pool import StaticPool from app.config import Settings from app.db.models import Activity, Base, HealthState from app.db.repositories import ActivityRepository, SyncRunRepository, UserRepository from app.main import create_app @pytest.fixture def db_session() -> Session: engine = create_engine( "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool, ) Base.metadata.create_all(engine) factory = sessionmaker(bind=engine, expire_on_commit=False) try: with factory() as session: yield session finally: engine.dispose() @pytest.fixture def user_repository(db_session: Session) -> UserRepository: return UserRepository(db_session) @pytest.fixture def activity_repository(db_session: Session) -> ActivityRepository: return ActivityRepository(db_session) @pytest.fixture def sync_run_repository(db_session: Session) -> SyncRunRepository: return SyncRunRepository(db_session) @pytest.fixture def client(tmp_path: Path) -> TestClient: settings = Settings( ADMIN_PASSWORD="admin-secret", SECRET_KEY="0123456789abcdef0123456789abcdef", CREDENTIAL_ENCRYPTION_KEY=Fernet.generate_key().decode("ascii"), DATA_DIR=str(tmp_path), DATABASE_URL=f"sqlite:///{tmp_path / 'app.db'}", SYNC_INTERVAL_MINUTES=5, ) app = create_app(settings) try: yield TestClient(app) finally: app.state.db_engine.dispose() @pytest.fixture def seeded_activity(db_session: Session, user_repository: UserRepository, activity_repository: ActivityRepository) -> Activity: user = user_repository.create( name="Test User", enabled=True, health_state=HealthState.HEALTHY, mywhoosh_email_enc="test@example.com", mywhoosh_password_enc="password", garmin_email_enc="test@garmin.com", garmin_password_enc="garmin_password", ) activity, _ = activity_repository.get_or_create_discovered( user_id=user.id, mywhoosh_activity_id="mw-test-123", activity_name="Test Activity", activity_timestamp=None, ) return activity