personal-lifecycle-tracker / backend / tests / conftest.py
conftest.py
Raw
from __future__ import annotations

import os
import sys
from typing import Generator

# Ensure backend root is on sys.path
backend_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if backend_dir not in sys.path:
    sys.path.insert(0, backend_dir)

# Default test database resolution
DEFAULT_TEST_DB_URL = "sqlite:///./test_lifecycle.db"


def get_test_database_url() -> str:
    """
    Returns the database URL for the test session.
    Prioritizes TEST_DATABASE_URL; if not set, defaults to an isolated SQLite file
    so test runs never clobber active development databases.
    """
    return os.environ.get("TEST_DATABASE_URL") or os.environ.get("DATABASE_TEST_URL") or DEFAULT_TEST_DB_URL


import pytest
from fastapi.testclient import TestClient

from app.main import create_app
from app.store import get_store, reset_store


@pytest.fixture(scope="session", autouse=True)
def initialize_test_database():
    """Configure store with test database for the entire test session."""
    test_db_url = get_test_database_url()
    reset_store(test_db_url)
    yield
    # Cleanup test db file after session if local file
    if test_db_url.startswith("sqlite:///./") and os.path.exists("./test_lifecycle.db"):
        try:
            os.remove("./test_lifecycle.db")
        except OSError:
            pass


@pytest.fixture(autouse=True)
def reset_store_state():
    """Ensure every test starts with fresh seed data."""
    store = get_store()
    store.seed()
    yield
    store.seed()


@pytest.fixture
def client() -> Generator[TestClient, None, None]:
    app = create_app()
    with TestClient(app) as test_client:
        yield test_client


@pytest.fixture
def test_client(client: TestClient) -> TestClient:
    """Alias for backwards compatibility with test_client fixtures."""
    return client


@pytest.fixture
def auth_token(client: TestClient) -> str:
    res = client.post(
        "/api/v1/auth/login",
        json={"email": "alex@example.com", "password": "password123"},
    )
    assert res.status_code == 200
    return res.json()["token"]


@pytest.fixture
def auth_headers(auth_token: str) -> dict:
    return {"Authorization": f"Bearer {auth_token}"}