from __future__ import annotations import os from pathlib import Path # Set environment variables BEFORE importing the app or settings module. # Use a fixed test workspace so every module that imports settings sees the # same paths. The client fixture wipes the DB before each test. TEST_DIR = Path(__file__).resolve().parent TEST_DB = TEST_DIR / "test.sqlite" TEST_MEDS = TEST_DIR / "fixtures" / "meds.yaml" TEST_MESSAGES = TEST_DIR / "fixtures" / "messages.yaml" os.environ["APP_PIN"] = "1234" os.environ["JWT_SECRET"] = "test-secret-must-be-at-least-32-bytes-long-ok" os.environ["AGENT_TOKEN"] = "agent-test-token-must-be-long-enough-for-secrets" os.environ["VAPID_PRIVATE_KEY"] = "" os.environ["VAPID_PUBLIC_KEY"] = "" os.environ["OPENROUTER_API_KEY"] = "" os.environ["DB_PATH"] = str(TEST_DB) os.environ["MEDS_PATH"] = str(TEST_MEDS) os.environ["MESSAGES_PATH"] = str(TEST_MESSAGES) # Neutralize the background scheduler for tests — it binds to the asyncio loop # and survives poorly across multiple TestClient lifecycles. import server.scheduler server.scheduler.start_scheduler = lambda: None # type: ignore[assignment] import pytest from fastapi.testclient import TestClient from server.app import app from server.auth import create_token from server.config_loader import reload_meds_config def _write_fixtures() -> None: TEST_MEDS.parent.mkdir(parents=True, exist_ok=True) TEST_MEDS.write_text( "timezone: Europe/Berlin\n" "slots:\n" " - id: morning\n" " time: \"08:00\"\n" " label: Morgens\n" " meds:\n" " - name: Elvanse\n" " dose: 30mg\n" " reminder_window_minutes: 90\n" ) TEST_MESSAGES.write_text( "reminder: [\"Zeit für Medis.\"]\n" "success: [\"Genommen.\"]\n" "missed: [\"Verpasst.\"]\n" "snooze: [\"Snooze.\"]\n" "motivation_fallback: [\"Motivation.\"]\n" "roast_fallback: [\"Roast.\"]\n" ) _write_fixtures() reload_meds_config() @pytest.fixture(scope="function") def client(): if TEST_DB.exists(): TEST_DB.unlink() with TestClient(app) as c: yield c @pytest.fixture def user_token() -> str: return create_token() @pytest.fixture def auth_headers(user_token: str): return {"Authorization": f"Bearer {user_token}"} @pytest.fixture def agent_headers(): return {"Authorization": "Bearer agent-test-token-must-be-long-enough-for-secrets"}