""" Pytest fixtures för LandveX Admin Backend. """ import asyncio import os import uuid from datetime import datetime, timezone import pytest import pytest_asyncio from httpx import AsyncClient, ASGITransport from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker os.environ.setdefault("DATABASE_URL", "postgresql+asyncpg://postgres:postgres@localhost:5432/landvex_test") os.environ.setdefault("SECRET_KEY", "test-secret-key-landvex-2026") from app.main import app from app.database import Base, get_db from app.models import Tenant, User, UserRole, UserStatus, TenantType, TenantStatus from app.security import get_password_hash TEST_DATABASE_URL = os.environ["DATABASE_URL"] engine = create_async_engine( TEST_DATABASE_URL, pool_pre_ping=True, future=True, ) TestSessionLocal = async_sessionmaker( engine, class_=AsyncSession, expire_on_commit=False, autoflush=False, ) async def override_get_db(): async with TestSessionLocal() as session: try: yield session await session.commit() except Exception: await session.rollback() raise finally: await session.close() app.dependency_overrides[get_db] = override_get_db @pytest_asyncio.fixture(scope="session") def event_loop(): loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest_asyncio.fixture(scope="session", autouse=True) async def setup_database(): """Skapa och tömma test-databasen.""" async with engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) await conn.run_sync(Base.metadata.create_all) yield async with engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) await engine.dispose() @pytest_asyncio.fixture async def db_session(): """Skapa en färsk session per test.""" async with TestSessionLocal() as session: yield session await session.rollback() @pytest_asyncio.fixture async def client(): """Async HTTP client för API-tester.""" transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as ac: yield ac @pytest_asyncio.fixture async def test_tenant(db_session: AsyncSession): """Skapa en test-tenant.""" tenant = Tenant( id=uuid.uuid4(), name="Test Municipality", slug="test-municipality", tenant_type=TenantType.MUNICIPALITY, status=TenantStatus.ACTIVE, schema_name="tenant_test_municipality", contact_email="test@kommun.se", city="Stockholm", country="SE", plan="basic", max_users=10, max_projects=5, storage_quota_mb=1024, created_at=datetime.now(timezone.utc), updated_at=datetime.now(timezone.utc), ) db_session.add(tenant) await db_session.commit() await db_session.refresh(tenant) return tenant @pytest_asyncio.fixture async def admin_user(db_session: AsyncSession, test_tenant): """Skapa en admin-användare.""" user = User( id=uuid.uuid4(), email="admin@landvex.se", hashed_password=get_password_hash("Admin123!"), first_name="Admin", last_name="User", role=UserRole.ADMIN, status=UserStatus.ACTIVE, is_superuser=True, tenant_id=test_tenant.id, created_at=datetime.now(timezone.utc), updated_at=datetime.now(timezone.utc), ) db_session.add(user) await db_session.commit() await db_session.refresh(user) return user @pytest_asyncio.fixture async def admin_token(admin_user): """Generera JWT-token för admin.""" from app.security import create_access_token return create_access_token(str(admin_user.id)) @pytest_asyncio.fixture async def auth_headers(admin_token): """Headers med Bearer-token för autentiserade requests.""" return {"Authorization": f"Bearer {admin_token}"}