from __future__ import annotations from fastapi.testclient import TestClient from app.core.config import get_settings import app.main as main_module def _set_bootstrap_step( monkeypatch, name: str, calls: list[str], *, should_fail: bool = False, ) -> None: def step() -> None: calls.append(name) if should_fail: raise RuntimeError(f"{name} failed") monkeypatch.setattr(main_module, name, step) def test_lifespan_can_skip_startup_bootstrap(monkeypatch) -> None: calls: list[str] = [] monkeypatch.setenv("STARTUP_BOOTSTRAP_ENABLED", "false") monkeypatch.setenv("BACKGROUND_SCHEDULERS_ENABLED", "false") get_settings.cache_clear() for name in ( "prepare_employee_directory", "prepare_agent_foundation", "prepare_knowledge_library", "sync_repository_hermes_skills", ): _set_bootstrap_step(monkeypatch, name, calls) try: with TestClient(main_module.create_app()) as client: response = client.get("/") finally: get_settings.cache_clear() assert response.status_code == 200 assert calls == [] def test_lifespan_continues_when_startup_bootstrap_fails(monkeypatch) -> None: calls: list[str] = [] monkeypatch.setenv("STARTUP_BOOTSTRAP_ENABLED", "true") monkeypatch.setenv("BACKGROUND_SCHEDULERS_ENABLED", "false") get_settings.cache_clear() steps: tuple[tuple[str, bool], ...] = ( ("prepare_employee_directory", True), ("prepare_agent_foundation", False), ("prepare_knowledge_library", False), ("sync_repository_hermes_skills", False), ) for name, should_fail in steps: _set_bootstrap_step(monkeypatch, name, calls, should_fail=should_fail) try: with TestClient(main_module.create_app()) as client: response = client.get("/") finally: get_settings.cache_clear() assert response.status_code == 200 assert calls == [name for name, _ in steps]