Files
timemaster/backend/tests/conftest.py
T
patrick fbc04bc2c0 agent-07 phase 2: fix test isolation + CSV import UI
- Fix conftest.py: commit after each request in override_get_db so
  preview_csv's rollback no longer wipes the shared registered_user
  (root cause of 401 cascade across test_user_import + test_personnel_number)
- Fix limiter.enabled=False in client fixture (blocks rate-limit 429)
- Fix user_import_service: allow reactivation when personnel number
  belongs to the same user being reactivated
- Fix test_personnel_number: use PATCH /companies/me (not /companies/{id})
  and add try/finally cleanup for personnel_number_required flag
- Frontend UsersPage: add CSV import modal with template download,
  preview/validation table, and guarded apply button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 21:07:32 +02:00

83 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy import text
from app.main import app
from app.core.database import Base, get_db
from app.core.limiter import limiter
# Echte PostgreSQL Test-Datenbank (kein SQLite Models nutzen JSONB/UUID)
TEST_DATABASE_URL = "postgresql+asyncpg://timemaster:timemaster_secret_change_me@localhost:5432/timemaster_test"
test_engine = create_async_engine(TEST_DATABASE_URL, echo=False)
TestSessionLocal = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
@pytest_asyncio.fixture(scope="session", loop_scope="session", autouse=True)
async def setup_db():
async with test_engine.begin() as conn:
# Schema komplett neu anlegen löst circular dependency departments↔users
await conn.execute(text("DROP SCHEMA public CASCADE"))
await conn.execute(text("CREATE SCHEMA public"))
await conn.execute(text("GRANT ALL ON SCHEMA public TO timemaster"))
await conn.execute(text("GRANT ALL ON SCHEMA public TO public"))
await conn.run_sync(Base.metadata.create_all)
yield
async with test_engine.begin() as conn:
await conn.execute(text("DROP SCHEMA public CASCADE"))
await conn.execute(text("CREATE SCHEMA public"))
await conn.execute(text("GRANT ALL ON SCHEMA public TO timemaster"))
await conn.execute(text("GRANT ALL ON SCHEMA public TO public"))
@pytest_asyncio.fixture(scope="session", loop_scope="session")
async def db_session():
async with TestSessionLocal() as session:
yield session
await session.rollback()
@pytest_asyncio.fixture(scope="session", loop_scope="session")
async def client(db_session: AsyncSession):
async def override_get_db():
try:
yield db_session
await db_session.commit()
except Exception:
await db_session.rollback()
raise
app.dependency_overrides[get_db] = override_get_db
limiter.enabled = False # Rate-Limiter in Tests deaktivieren
async with AsyncClient(
transport=ASGITransport(app=app),
base_url="http://test",
) as ac:
yield ac
limiter.enabled = True
app.dependency_overrides.clear()
@pytest_asyncio.fixture(scope="session", loop_scope="session")
async def registered_user(client: AsyncClient):
"""Register a company + admin user, return tokens + user data."""
resp = await client.post("/api/v1/auth/register", json={
"company_name": "Test GmbH",
"first_name": "Max",
"last_name": "Mustermann",
"email": "max@testgmbh.de",
"password": "Secret123",
})
assert resp.status_code == 201
tokens = resp.json()
me = await client.get(
"/api/v1/auth/me",
headers={"Authorization": f"Bearer {tokens['access_token']}"},
)
return {"tokens": tokens, "user": me.json()}