| """ |
| Test configuration and fixtures. |
| """ |
| import asyncio |
| import uuid |
| from typing import AsyncGenerator |
|
|
| import pytest |
| import pytest_asyncio |
| from httpx import ASGITransport, AsyncClient |
| from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine |
|
|
| from app.core.config import settings |
| from app.core.database import Base, get_db |
| from app.core.security import create_access_token, hash_password |
| from app.main import app |
| from app.models.user import AuthProvider, Profile, User |
|
|
| |
| TEST_DATABASE_URL = settings.DATABASE_URL.replace("/jobportal", "/jobportal_test") |
|
|
| engine_test = create_async_engine(TEST_DATABASE_URL, echo=False) |
| async_session_test = async_sessionmaker(engine_test, class_=AsyncSession, expire_on_commit=False) |
|
|
|
|
| @pytest.fixture(scope="session") |
| def event_loop(): |
| """Create event loop for the test session.""" |
| loop = asyncio.new_event_loop() |
| yield loop |
| loop.close() |
|
|
|
|
| @pytest_asyncio.fixture(autouse=True) |
| async def setup_database(): |
| """Create tables before tests and drop after.""" |
| async with engine_test.begin() as conn: |
| await conn.run_sync(Base.metadata.create_all) |
| yield |
| async with engine_test.begin() as conn: |
| await conn.run_sync(Base.metadata.drop_all) |
|
|
|
|
| @pytest_asyncio.fixture |
| async def db_session() -> AsyncGenerator[AsyncSession, None]: |
| """Provide a test database session.""" |
| async with async_session_test() as session: |
| yield session |
| await session.rollback() |
|
|
|
|
| @pytest_asyncio.fixture |
| async def client(db_session: AsyncSession) -> AsyncGenerator[AsyncClient, None]: |
| """Provide a test HTTP client.""" |
|
|
| async def override_get_db(): |
| yield db_session |
|
|
| app.dependency_overrides[get_db] = override_get_db |
|
|
| async with AsyncClient( |
| transport=ASGITransport(app=app), |
| base_url="http://test", |
| ) as client: |
| yield client |
|
|
| app.dependency_overrides.clear() |
|
|
|
|
| @pytest_asyncio.fixture |
| async def test_user(db_session: AsyncSession) -> User: |
| """Create a test user.""" |
| user = User( |
| id=uuid.uuid4(), |
| email="test@example.com", |
| hashed_password=hash_password("testpass123"), |
| full_name="Test User", |
| role="candidate", |
| auth_provider=AuthProvider.LOCAL, |
| is_active=True, |
| is_verified=True, |
| ) |
| db_session.add(user) |
|
|
| profile = Profile(user_id=user.id) |
| db_session.add(profile) |
|
|
| await db_session.commit() |
| await db_session.refresh(user) |
| return user |
|
|
|
|
| @pytest_asyncio.fixture |
| async def admin_user(db_session: AsyncSession) -> User: |
| """Create a test admin user.""" |
| user = User( |
| id=uuid.uuid4(), |
| email="admin@example.com", |
| hashed_password=hash_password("adminpass123"), |
| full_name="Admin User", |
| role="admin", |
| auth_provider=AuthProvider.LOCAL, |
| is_active=True, |
| is_verified=True, |
| is_superuser=True, |
| ) |
| db_session.add(user) |
| await db_session.commit() |
| await db_session.refresh(user) |
| return user |
|
|
|
|
| @pytest_asyncio.fixture |
| async def auth_headers(test_user: User) -> dict: |
| """Generate auth headers for test user.""" |
| token = create_access_token(subject=str(test_user.id)) |
| return {"Authorization": f"Bearer {token}"} |
|
|
|
|
| @pytest_asyncio.fixture |
| async def admin_headers(admin_user: User) -> dict: |
| """Generate auth headers for admin user.""" |
| token = create_access_token(subject=str(admin_user.id)) |
| return {"Authorization": f"Bearer {token}"} |
|
|