Files
gh-christianlouis-dmarq/backend/app/tests/conftest.py
T
copilot-swe-agent[bot] 241713083b Add persistent settings system with database backend and comprehensive UI
- New Setting ORM model (key-value store with category, value_type, audit fields)
- Alembic migration to create the settings table
- Settings API endpoints: GET/PUT /api/v1/settings/{key}, GET /api/v1/settings (list+filter), POST /api/v1/settings/bulk
- Default seeding (17 sensible defaults across general/dmarc/dns/cloudflare/notifications categories)
- Secret redaction for cloudflare.api_token and notifications.smtp_password
- Updated settings.html: General, DMARC Policy Defaults, DNS Resolver, Cloudflare Integration, Email Notifications sections
- All forms wired to the API via Alpine.js with flash feedback
- 12 new tests for the settings model and endpoints

Agent-Logs-Url: https://github.com/christianlouis/dmarq/sessions/19dbc6cd-07cb-406e-b3b6-411f7721f737

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-30 07:58:51 +00:00

99 lines
3.1 KiB
Python

# Import all models so Base.metadata knows every table
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
import app.models.domain # noqa: F401 # pylint: disable=unused-import
import app.models.mail_source as _mail_source_model # noqa: F401 # pylint: disable=unused-import
import app.models.report # noqa: F401 # pylint: disable=unused-import
import app.models.setting # noqa: F401 # pylint: disable=unused-import
import app.models.user # noqa: F401 # pylint: disable=unused-import
from app.core.database import Base, get_db
from app.core.security import require_admin_auth
from app.main import create_app
from app.services.report_store import ReportStore
@pytest.fixture()
def test_app() -> FastAPI:
"""Create a fresh FastAPI application instance for testing."""
application = create_app()
return application
@pytest.fixture()
def db_session():
"""Create a fresh in-memory SQLite database session per test.
``StaticPool`` ensures every SQLAlchemy operation reuses the same
underlying DBAPI connection so the in-memory database (and its tables)
persist for the full duration of the test, even across commits.
"""
engine = create_engine(
"sqlite://",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
Base.metadata.create_all(engine)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
Base.metadata.drop_all(engine)
engine.dispose()
@pytest.fixture()
def client(test_app: FastAPI, db_session): # pylint: disable=redefined-outer-name
"""Create a TestClient with a DB override for the test app."""
def override_get_db():
try:
yield db_session
finally:
pass
test_app.dependency_overrides[get_db] = override_get_db
with TestClient(test_app) as test_client:
yield test_client
test_app.dependency_overrides.clear()
@pytest.fixture(autouse=True)
def _reset_report_store():
"""Reset the ReportStore singleton between tests to avoid state leakage."""
store = ReportStore.get_instance()
store.clear()
yield
store.clear()
@pytest.fixture()
def authed_client(test_app: FastAPI, db_session): # pylint: disable=redefined-outer-name
"""
TestClient with both DB and admin-auth dependency overrides.
Bypasses ``require_admin_auth`` so tests can call admin-only endpoints
without needing a real API key or JWT token.
"""
async def mock_admin_auth():
return {"auth_type": "api_key", "api_key": "test-key"}
def override_get_db():
try:
yield db_session
finally:
pass
test_app.dependency_overrides[get_db] = override_get_db
test_app.dependency_overrides[require_admin_auth] = mock_admin_auth
with TestClient(test_app) as test_client:
yield test_client
test_app.dependency_overrides.clear()