from __future__ import annotations from collections.abc import Generator from pathlib import Path import pytest from fastapi.testclient import TestClient from sqlalchemy.orm import Session, sessionmaker from app.config import Settings, get_settings from app.database import Base, build_engine, get_db from app.main import app @pytest.fixture() def test_settings(tmp_path: Path) -> Settings: db_file = tmp_path / "test_tryme.db" return Settings( database_url=f"sqlite:///{db_file.as_posix()}", dev_auth_enabled=True, admin_user="", session_secret="pytest-secret-key", seed_starter_quizzes=False, ) @pytest.fixture() def client(test_settings: Settings) -> Generator[TestClient, None, None]: test_engine = build_engine(test_settings.database_url) Base.metadata.create_all(bind=test_engine) TestingSessionLocal = sessionmaker( bind=test_engine, autoflush=False, autocommit=False, expire_on_commit=False ) def _override_get_db() -> Generator[Session, None, None]: db = TestingSessionLocal() try: yield db finally: db.close() app.dependency_overrides[get_db] = _override_get_db app.dependency_overrides[get_settings] = lambda: test_settings with TestClient(app) as test_client: yield test_client app.dependency_overrides.clear() test_engine.dispose() def create_onboarded_student( client: TestClient, nickname: str = "astro_fox", animal: str = "fox", color: str = "avatar-1", ) -> tuple[str, dict]: resp = client.post("/api/v1/auth/dev-login", json={"nickname": nickname}) assert resp.status_code == 200 token = resp.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} patch = client.patch( "/api/v1/users/me", headers=headers, json={ "nickname": nickname, "first_name": "Alex", "last_name": "Rivera", "age": 14, "gender": "non_binary", "avatar_animal": animal, "avatar_color": color, "public_website_consent": True, }, ) assert patch.status_code == 200 return token, patch.json()