from __future__ import annotations from uuid import uuid4 import pytest from sqlalchemy import Column, String, Table, select from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine from core.db.base import Base from models.profile import Profile @pytest.fixture async def db_engine(): """Create in-memory SQLite engine for testing.""" users_table = Table( "users", Base.metadata, Column("id", String, primary_key=True), schema="auth", extend_existing=True, ) engine = create_async_engine( "sqlite+aiosqlite:///:memory:", echo=False, ) async with engine.begin() as conn: await conn.exec_driver_sql("ATTACH DATABASE ':memory:' AS auth") await conn.run_sync(Base.metadata.create_all) yield engine Base.metadata.remove(users_table) await engine.dispose() @pytest.fixture async def db_session(db_engine): """Create a database session for testing.""" async_session = async_sessionmaker( bind=db_engine, class_=AsyncSession, expire_on_commit=False, ) async with async_session() as session: yield session await session.rollback() @pytest.mark.asyncio async def test_profile_model_create(db_session: AsyncSession) -> None: """Test creating a Profile model.""" profile_id = uuid4() profile = Profile( id=profile_id, username="testuser", ) db_session.add(profile) await db_session.commit() await db_session.refresh(profile) assert profile.id == profile_id assert profile.username == "testuser" assert profile.created_at is not None assert profile.updated_at is not None assert profile.deleted_at is None @pytest.mark.asyncio async def test_profile_model_get_by_id(db_session: AsyncSession) -> None: """Test retrieving a Profile by ID.""" profile_id = uuid4() profile = Profile( id=profile_id, username="testuser", ) db_session.add(profile) await db_session.commit() result = await db_session.get(Profile, profile_id) assert result is not None assert result.username == "testuser" @pytest.mark.asyncio async def test_profile_model_get_by_username(db_session: AsyncSession) -> None: """Test retrieving a Profile by username.""" profile = Profile( id=uuid4(), username="testuser", ) db_session.add(profile) await db_session.commit() result = await db_session.execute( select(Profile).where(Profile.username == "testuser") ) found = result.scalar_one() assert found is not None assert found.username == "testuser" @pytest.mark.asyncio async def test_profile_model_update(db_session: AsyncSession) -> None: """Test updating a Profile.""" profile = Profile( id=uuid4(), username="testuser", bio="Old bio", ) db_session.add(profile) await db_session.commit() profile.bio = "New bio" await db_session.commit() await db_session.refresh(profile) assert profile.bio == "New bio" @pytest.mark.asyncio async def test_profile_model_allows_duplicate_usernames( db_session: AsyncSession, ) -> None: first = Profile(id=uuid4(), username="same_name") second = Profile(id=uuid4(), username="same_name") db_session.add(first) db_session.add(second) await db_session.commit() result = await db_session.execute( select(Profile).where(Profile.username == "same_name") ) found = result.scalars().all() assert len(found) == 2