from __future__ import annotations import importlib import os from pathlib import Path from typing import Generator import pandas as pd import pytest from sqlalchemy import create_engine, text from sqlalchemy.engine import make_url from sqlalchemy.exc import OperationalError import scripts.init_db as init_db from projet_05.settings import load_settings @pytest.fixture(scope="session") def test_db_url() -> str: """URL de connexion PostgreSQL utilisée pendant les tests.""" return os.getenv( "PROJET05_TEST_DATABASE_URL", "postgresql+psycopg://postgres:postgres@localhost:5432/projet05_test", ) @pytest.fixture(scope="session") def initialized_db(test_db_url: str) -> Generator[str, None, None]: """Crée une base dédiée aux tests, exécute scripts.init_db puis la met à disposition.""" url = make_url(test_db_url) admin_url = url.set(database="postgres") try: admin_engine = create_engine(admin_url, future=True) with admin_engine.execution_options(isolation_level="AUTOCOMMIT").connect() as conn: conn.execute(text(f"DROP DATABASE IF EXISTS {url.database}")) conn.execute(text(f"CREATE DATABASE {url.database}")) except OperationalError as exc: pytest.skip(f"Base PostgreSQL de test indisponible: {exc}") os.environ["PROJET05_DATABASE_URL"] = test_db_url load_settings.cache_clear() init_db.main(settings_path=None) yield test_db_url load_settings.cache_clear() with admin_engine.execution_options(isolation_level="AUTOCOMMIT").connect() as conn: conn.execute( text( "SELECT pg_terminate_backend(pid) FROM pg_stat_activity " "WHERE datname = :db AND pid <> pg_backend_pid()" ), {"db": url.database}, ) conn.execute(text(f"DROP DATABASE IF EXISTS {url.database}")) @pytest.fixture(scope="session") def raw_rowcount() -> int: """Nombre de lignes attendues dans les CSV bruts.""" source = Path("data/raw/extrait_sirh.csv") return pd.read_csv(source).shape[0]