VirtForemanBackend / tests /conftest.py
Dirbol's picture
feat(uploads): D-light blueprint pipeline (Phase-2, no OCR)
e10629e
Raw
History Blame Contribute Delete
3.71 kB
"""Pytest configuration shared across the suite.
Skips tests that require external services (Supabase, NVIDIA integrate)
unless the right env vars are set.
"""
from __future__ import annotations
import os
from pathlib import Path
import pytest
def _truthy(v: str | None) -> bool:
return v is not None and v not in ("", "0", "false", "False")
@pytest.fixture(scope="session")
def has_supabase() -> bool:
return _truthy(os.environ.get("SUPABASE_URL")) and _truthy(
os.environ.get("SUPABASE_SECRET_KEY")
or os.environ.get("SUPABASE_KEY")
)
@pytest.fixture(scope="session")
def has_nvidia() -> bool:
return _truthy(os.environ.get("NVIDIA_API_KEY")) or _truthy(
os.environ.get("LLM_API_KEY")
)
@pytest.fixture(scope="session")
def fastapi_client():
"""Starlette TestClient for the FastAPI app.
Only constructed when no external network is needed (e.g. /health,
/, /documents/templates).
"""
from fastapi.testclient import TestClient # type: ignore
# Provides query/key so supabase init doesn't blow up
os.environ.setdefault("SUPABASE_URL", "")
os.environ.setdefault("SUPABASE_SECRET_KEY", "")
os.environ.setdefault("NVIDIA_API_KEY", "test")
from app.main import app
return TestClient(app)
@pytest.fixture(scope="session")
def minimal_app_client():
"""Lightweight TestClient that mounts ONLY /uploads/blueprint*.
Use this when the canonical app depends on packages (PIL etc.) the
local Termux env can't build — this fixture isolates the new router
so we can run its smoke tests in this env without breaking CI runs
that already exercise the full app elsewhere.
"""
from fastapi import FastAPI # type: ignore
from fastapi.middleware.cors import CORSMiddleware # type: ignore
from fastapi.testclient import TestClient # type: ignore
# Load the uploads router module directly — bypass app.routers.__init__
# which transitively imports the legacy blueprint service (depends on
# Pillow, missing on Termux). The router file itself only imports
# Pydantic models and the canonical services it owns.
import importlib.util as _util
import sys as _sys
_spec = _util.spec_from_file_location(
"vf_uploads_isolated",
str(Path(__file__).parent.parent
/ "app" / "routers" / "uploads.py"),
)
_mod = _util.module_from_spec(_spec)
_spec.loader.exec_module(_mod)
uploads_router = _mod.router
os.environ.setdefault("SUPABASE_URL", "")
os.environ.setdefault("SUPABASE_SECRET_KEY", "")
os.environ.setdefault("NVIDIA_API_KEY", "test")
app = FastAPI(title="VF uploads (minimal)")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["GET", "POST", "OPTIONS"],
allow_headers=["*"],
)
app.include_router(uploads_router)
return TestClient(app)
def pytest_collection_modifyitems(config, items):
"""Mark tests that hit external services with a skip marker when
the required env var is missing.
"""
skip_no_sb = pytest.mark.skip(reason="Supabase credentials required")
skip_no_nv = pytest.mark.skip(reason="NVIDIA API key required")
has_sb = _truthy(os.environ.get("SUPABASE_URL")) and _truthy(
os.environ.get("SUPABASE_SECRET_KEY")
or os.environ.get("SUPABASE_KEY")
)
has_nv = _truthy(os.environ.get("NVIDIA_API_KEY")) or _truthy(
os.environ.get("LLM_API_KEY")
)
for item in items:
if "supabase" in item.keywords and not has_sb:
item.add_marker(skip_no_sb)
if "nvidia" in item.keywords and not has_nv:
item.add_marker(skip_no_nv)