ci / lint-test-leaks (pull_request) Canceled after 0s
- cayceops core: env-only config (CAYCE_OPS_*), engine/session, ORM models with state machines (proposal/mail/content) and audited writes - provider-agnostic LLM interface (null provider default, stdlib openai-compat) - Typer CLI with lazy component loading (scanner/executor/maild/publisher/monitor) - alembic 0001 initial schema; sqlite-portable JSON columns - tests: 7 passing on throwaway sqlite; fixtures invented, never real data - ci: ruff + alembic smoke + pytest + gitleaks(full history) in .gitea/workflows + .github/workflows; local gate = make check - deploy: docker-compose (postgres 16) + hardened systemd units/timers - docs: DECISIONS D1-D9; README project (grant text retired)
78 lines
2.2 KiB
Python
78 lines
2.2 KiB
Python
"""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
|