- Router api_v2.py (~100 endpoints) : tokens, users, workspaces/members, collections, pages, proprietes, vues/dashboards, commentaires/mentions, notifications, favoris/tags/recents, partage/publish, historique, sprints, templates, export/import, forges, recherche FTS, admin, webhooks CRUD - Helpers api_v2_helpers.py : Bearer unifie (sha256/expires_at/extension_devices), scopes hierarchiques read<write<admin, pagination + X-Total-Count, ISO-8601, RFC 7807, idempotence, audit, rate-limit par token - Migration 20 : api_tokens.scopes/expires_at, webhook_deliveries, api_audit_log, idempotency_keys - main.py : handler d'erreurs unifie StarletteHTTPException, /docs + /redoc - config : PUBLIC_API_INSECURE_OK (dev only), API_V2_RATE_LIMIT_PER_TOKEN - OpenAPI docs/openapi-v2.json (402 chemins), tests/test_public_api_v2.py (24) - Docs : CHANGELOG (v6.2.0/6.2.1 clipper + v6.3.0), ROADMAP, API_GUIDE_V6, V6_Web_Clipper, README, ARCHITECTURE, /help - Suite complete 668 verte, ruff OK
74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
"""FlowDeck — pytest fixtures and configuration.
|
|
|
|
Each test gets a fresh, isolated SQLite database and backup directory so the
|
|
suite is safe to run in parallel (``pytest -n auto``): workers never share a
|
|
database file, and no state leaks between tests.
|
|
"""
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
"""FastAPI TestClient with a fresh temporary SQLite database."""
|
|
db_file = tempfile.NamedTemporaryFile(suffix=".db", delete=False)
|
|
db_path = db_file.name
|
|
db_file.close()
|
|
|
|
backup_dir = tempfile.mkdtemp(prefix="fd_backups_")
|
|
data_dir = tempfile.mkdtemp(prefix="fd_data_")
|
|
|
|
# Set env BEFORE importing app modules (config reads at import time).
|
|
os.environ["DATABASE_URL"] = f"sqlite:///{db_path}"
|
|
os.environ["APP_SECRET_KEY"] = "test-secret-for-tests"
|
|
os.environ["RATE_LIMIT_ENABLED"] = "false"
|
|
os.environ["PUBLIC_API_INSECURE_OK"] = "true"
|
|
os.environ["BACKUP_ENABLED"] = "true"
|
|
os.environ["BACKUP_DIR"] = backup_dir
|
|
os.environ["PROJECT_SYNC_ENABLED"] = "false"
|
|
# Point data-root (uploads/, emoji/, covers/) at a writable temp dir so tests
|
|
# don't depend on the container's /data path existing on a dev host.
|
|
os.environ["FLOWDECK_DATA_DIR"] = data_dir
|
|
|
|
# IMPORTANT: mutate the existing Settings singleton in place — do NOT rebind
|
|
# `app.config.settings`. Modules such as `app.services.backup` and
|
|
# `app.routers.auth` hold a direct reference imported at load time, so
|
|
# rebinding would leave them pointing at the stale defaults (this was the
|
|
# cause of the previously-skipped flaky backup tests).
|
|
import app.config
|
|
s = app.config.settings
|
|
s.database_url = f"sqlite:///{db_path}"
|
|
s.app_secret_key = "test-secret-for-tests"
|
|
s.rate_limit_enabled = False
|
|
s.public_api_insecure_ok = True
|
|
s.backup_enabled = True
|
|
s.backup_dir = backup_dir
|
|
s.backup_interval_hours = 24
|
|
s.backup_keep = 30
|
|
s.project_sync_enabled = False
|
|
|
|
from app.db import init_db
|
|
from app.main import app
|
|
init_db()
|
|
|
|
yield TestClient(app)
|
|
|
|
# Cleanup
|
|
try:
|
|
os.unlink(db_path)
|
|
except PermissionError:
|
|
pass # Windows: file may still be open in another thread
|
|
for p in Path(backup_dir).glob("*.db"):
|
|
try:
|
|
p.unlink()
|
|
except PermissionError:
|
|
pass
|
|
try:
|
|
Path(backup_dir).rmdir()
|
|
except OSError:
|
|
pass
|