Files
boc/landvex-admin-backend/tests/conftest.py
T

148 lines
3.9 KiB
Python
Raw Normal View History

"""
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}"}