Files

105 lines
3.0 KiB
Python
Raw Permalink Normal View History

"""Test fixtures — async database and HTTP client.
Hver test får sin egen engine (function-scoped) med friske tabeller.
Appen får sin egen session per request via dependency override.
Ingen delte sessions — ingen "another operation is in progress".
"""
2026-07-11 02:10:27 +02:00
import pytest
import pytest_asyncio
from sqlalchemy.ext.asyncio import (
create_async_engine,
async_sessionmaker,
)
2026-07-11 02:10:27 +02:00
from httpx import ASGITransport, AsyncClient
from app.database import Base, get_db
from app.main import app
from app.auth import hash_password
from app.models import User
import os
DATABASE_URL = os.getenv(
"DATABASE_URL",
"postgresql+asyncpg://pokedexter:pokedexter_secret@localhost/pokedexter",
)
@pytest_asyncio.fixture(autouse=True)
2026-07-11 02:10:27 +02:00
async def engine():
"""Frisk engine per test — skaber tabeller, smider væk bagefter."""
2026-07-11 02:10:27 +02:00
e = create_async_engine(DATABASE_URL, echo=False)
async with e.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)
yield e
await e.dispose()
@pytest_asyncio.fixture
async def client(engine):
"""HTTP client — appen får en frisk session på testens engine per request."""
maker = async_sessionmaker(bind=engine, expire_on_commit=False)
2026-07-11 02:10:27 +02:00
async def override_get_db():
async with maker() as s:
yield s
2026-07-11 02:10:27 +02:00
app.dependency_overrides[get_db] = override_get_db
2026-07-11 02:10:27 +02:00
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as ac:
yield ac
app.dependency_overrides.clear()
2026-07-11 02:10:27 +02:00
@pytest_asyncio.fixture
async def admin_user(engine):
"""Insert admin user — frisk session, committer, lukker."""
maker = async_sessionmaker(bind=engine, expire_on_commit=False)
async with maker() as s:
u = User(
username="admin",
password_hash=hash_password("admin123"),
role="admin",
)
s.add(u)
await s.commit()
return u
2026-07-11 02:10:27 +02:00
@pytest_asyncio.fixture
async def normal_user(engine):
"""Insert normal user — frisk session, committer, lukker."""
maker = async_sessionmaker(bind=engine, expire_on_commit=False)
async with maker() as s:
u = User(
username="testuser",
password_hash=hash_password("test123"),
role="user",
)
s.add(u)
await s.commit()
return u
2026-07-11 02:10:27 +02:00
@pytest_asyncio.fixture
async def admin_token(client, admin_user):
"""Log in as admin and return the JWT token."""
resp = await client.post("/api/login", json={
"username": "admin",
"password": "admin123",
})
assert resp.status_code == 200
return resp.cookies.get("token")
@pytest_asyncio.fixture
async def user_token(client, normal_user):
"""Log in as normal user and return the JWT token."""
resp = await client.post("/api/login", json={
"username": "testuser",
"password": "test123",
})
assert resp.status_code == 200
return resp.cookies.get("token")