import sys import uuid import types import pytest from fastapi.testclient import TestClient from httpx import AsyncClient, ASGITransport # Stub sentry_sdk to avoid optional dependency issues during import of app stub = types.ModuleType("sentry_sdk") stub.init = lambda *args, **kwargs: None sys.modules.setdefault("sentry_sdk", stub) # Import the FastAPI application from app.app import fastApi as app # noqa: E402 @pytest.fixture(scope="session") def fastapi_app(): return app @pytest.fixture(scope="session") def client(fastapi_app): return TestClient(fastapi_app, raise_server_exceptions=True) @pytest.fixture(scope="function") async def test_user(fastapi_app): """ Creates a new user asynchronously and returns their credentials. Does NOT log them in. Using AsyncClient with ASGITransport avoids event loop conflicts with DB connections. """ unique_email = f"testuser_{uuid.uuid4()}@example.com" password = "a_strong_password" user_payload = {"email": unique_email, "password": password} transport = ASGITransport(app=fastapi_app, raise_app_exceptions=True) async with AsyncClient(transport=transport, base_url="http://testserver") as ac: response = await ac.post("/auth/register", json=user_payload) assert response.status_code == 201 return {"username": unique_email, "password": password} @pytest.fixture(scope="function") def authenticated_client(client: TestClient): """ Creates a new user, logs them in, and returns a client with the authorization headers already set. """ # 1. Create a unique user unique_email = f"testuser_{uuid.uuid4()}@example.com" password = "a_strong_password" user_payload = {"email": unique_email, "password": password} register_resp = client.post("/auth/register", json=user_payload) assert register_resp.status_code == 201 # 2. Log in to get the token login_payload = {"username": unique_email, "password": password} login_resp = client.post("/auth/jwt/login", data=login_payload) token = login_resp.json()["access_token"] # 3. Set the authorization header for subsequent requests client.headers = {"Authorization": f"Bearer {token}"} yield client # Teardown: Clear headers after the test client.headers.pop("Authorization", None)