from contextlib import asynccontextmanager import os from pathlib import Path import subprocess import sys from unittest.mock import AsyncMock import pytest from fastapi import FastAPI from app import main def test_db_base_registers_permission_models_for_create_all(): backend_dir = Path(__file__).resolve().parents[1] code = """ from app.db.base_class import Base import app.db.base required_tables = { "api_endpoint_permissions", "api_endpoint_registries", "permission_templates", "permission_template_versions", } missing = sorted(required_tables - set(Base.metadata.tables)) if missing: print(",".join(missing)) raise SystemExit(1) """ env = { **os.environ, "PYTHONDONTWRITEBYTECODE": "1", "PYTHONPATH": str(backend_dir), } result = subprocess.run( [sys.executable, "-c", code], cwd=backend_dir, env=env, capture_output=True, text=True, check=False, ) assert result.returncode == 0, result.stdout + result.stderr class _DummyTask: def __init__(self): self.awaited = False self.cancelled = False def cancel(self): self.cancelled = True def done(self): return False def __await__(self): async def _wait(): self.awaited = True return _wait().__await__() class _DummySession: async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): return False class _DummyBegin: async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): return False async def run_sync(self, fn): return None class _DummyEngine: def begin(self): return _DummyBegin() @pytest.mark.asyncio async def test_development_startup_does_not_seed_business_data(monkeypatch): ensure_admin_exists = AsyncMock() create_all = AsyncMock() legacy_pk = AsyncMock() scheduler_task = _DummyTask() async def fake_scheduler(stop_event): return None def fake_create_task(coroutine): coroutine.close() return scheduler_task @asynccontextmanager async def fake_session_local(): yield _DummySession() monkeypatch.setattr(main.settings, "ENV", "development") monkeypatch.setattr(main, "ensure_admin_exists", ensure_admin_exists) monkeypatch.setattr(main, "run_daily_lost_visit_job", fake_scheduler) monkeypatch.setattr(main, "resolve_monitoring_server_location", AsyncMock(return_value=None)) monkeypatch.setattr(main.asyncio, "create_task", fake_create_task) monkeypatch.setattr(main, "engine", _DummyEngine()) monkeypatch.setattr(main, "SessionLocal", fake_session_local) monkeypatch.setattr(main, "_ensure_legacy_primary_keys", legacy_pk) monkeypatch.setattr(main.Base.metadata, "create_all", create_all) async with main.lifespan(FastAPI()): pass ensure_admin_exists.assert_awaited_once()