"""Pytest configuration and shared fixtures for Sneaky Klaus tests.""" import pytest from src.app import create_app from src.app import db as _db from src.models import Admin @pytest.fixture(scope="session") def app(): """Create and configure a test Flask application instance. This fixture is scoped to the session so the app is created once for all tests. Yields: Flask application configured for testing. """ app = create_app("testing") yield app @pytest.fixture(scope="function") def db(app): """Create a clean database for each test. This fixture creates all tables before each test and drops them after each test to ensure isolation. Args: app: Flask application instance from app fixture. Yields: SQLAlchemy database instance. """ with app.app_context(): _db.create_all() yield _db _db.session.remove() _db.drop_all() @pytest.fixture(scope="function") def client(app, db): # noqa: ARG001 """Create a test client for the Flask application. Args: app: Flask application instance. db: Database instance (ensures db is set up first). Yields: Flask test client. """ with app.test_client() as client: yield client @pytest.fixture def admin(db): """Create an admin user for testing. Args: db: Database instance. Returns: Admin model instance. """ from src.app import bcrypt admin = Admin( email="admin@example.com", password_hash=bcrypt.generate_password_hash("testpassword123").decode("utf-8"), ) db.session.add(admin) db.session.commit() return admin @pytest.fixture def exchange_factory(db): """Factory for creating test exchanges. Args: db: Database instance. Returns: Function that creates and returns Exchange instances. """ from datetime import UTC, datetime, timedelta from src.models.exchange import Exchange def _create(state="draft", **kwargs): exchange = Exchange( slug=kwargs.get("slug", Exchange.generate_slug()), name=kwargs.get("name", "Test Exchange"), budget=kwargs.get("budget", "$25-50"), max_participants=kwargs.get("max_participants", 50), registration_close_date=kwargs.get( "registration_close_date", datetime.now(UTC) + timedelta(days=7) ), exchange_date=kwargs.get( "exchange_date", datetime.now(UTC) + timedelta(days=14) ), timezone=kwargs.get("timezone", "UTC"), state=state, ) db.session.add(exchange) db.session.commit() return exchange return _create @pytest.fixture def participant_factory(db, exchange_factory): """Factory for creating test participants. Args: db: Database instance. exchange_factory: Exchange factory fixture. Returns: Function that creates and returns Participant instances. """ from src.models.participant import Participant counter = {"value": 0} def _create(exchange=None, **kwargs): if not exchange: exchange = exchange_factory() counter["value"] += 1 participant = Participant( exchange_id=exchange.id, name=kwargs.get("name", f"Test Participant {counter['value']}"), email=kwargs.get("email", f"test{counter['value']}@example.com"), gift_ideas=kwargs.get("gift_ideas", "Test ideas"), reminder_enabled=kwargs.get("reminder_enabled", True), withdrawn_at=kwargs.get("withdrawn_at"), ) db.session.add(participant) db.session.commit() return participant return _create @pytest.fixture def auth_participant(client, exchange_factory, participant_factory): """Create an authenticated participant session. Args: client: Flask test client. exchange_factory: Exchange factory fixture. participant_factory: Participant factory fixture. Returns: Authenticated participant instance. """ exchange = exchange_factory(state="registration_open") participant = participant_factory(exchange=exchange) with client.session_transaction() as session: session["user_id"] = participant.id session["user_type"] = "participant" session["exchange_id"] = exchange.id return participant