"""Shared pytest fixtures. Tests run against a throwaway SQLite database (fast, zero external services). The production path is Postgres via Alembic; ``make migrate-check`` smoke-tests the migration chain on SQLite in CI. All fixture data is invented — never real merchant or account data. """ from __future__ import annotations import os from pathlib import Path import pytest # Config must see the test DB before cayceops.config/db get imported. os.environ.setdefault("CAYCE_OPS_DATABASE_URL", "sqlite:///:memory:") os.environ.setdefault("CAYCE_OPS_AUTONOMOUS_MODE", "false") @pytest.fixture() def db_engine(tmp_path: Path): """A fresh schema per test, on a file-backed SQLite DB (shared in-process).""" from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from cayceops.db import reset_engine from cayceops.models import Base url = f"sqlite:///{tmp_path}/test.db" eng = create_engine(url, future=True, connect_args={"check_same_thread": False}) Base.metadata.create_all(eng) factory = sessionmaker(bind=eng, expire_on_commit=False, future=True) # point the app at the same engine/session factory reset_engine() import cayceops.db as appdb appdb._engine = eng appdb._factory = factory yield eng eng.dispose() reset_engine() @pytest.fixture() def sess(db_engine): """A session bound to the fresh schema (rolls back at test end).""" import cayceops.db as appdb s = appdb.session_factory()() yield s s.rollback() s.close() @pytest.fixture() def cfg(monkeypatch): """A Config snapshot with test defaults (no network, no autonomy).""" from cayceops.config import Config defaults = { "CAYCE_OPS_DATABASE_URL": "sqlite:///:memory:", "CAYCE_OPS_LLM_PROVIDER": "null", "CAYCE_OPS_ENABLE_FACEBOOK": "false", "CAYCE_OPS_ENABLE_INSTAGRAM": "false", "CAYCE_OPS_NOSTR_RELAYS": "", "CAYCE_OPS_MEDIA_DIR": "media", } def _apply(**overrides): merged = {**defaults, **{k: str(v) for k, v in overrides.items()}} for k, v in merged.items(): monkeypatch.setenv(k, v) return Config() return _apply