from __future__ import annotations from collections.abc import Iterator import pytest from fastapi import FastAPI from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.engine import Engine from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import StaticPool from config.database import Base from dependencies import get_unit_of_work from routes.dashboard import router as dashboard_router from routes.projects import router as projects_router from routes.scenarios import router as scenarios_router from services.unit_of_work import UnitOfWork @pytest.fixture() def engine() -> Iterator[Engine]: engine = create_engine( "sqlite+pysqlite:///:memory:", future=True, connect_args={"check_same_thread": False}, poolclass=StaticPool, ) Base.metadata.create_all(bind=engine) try: yield engine finally: Base.metadata.drop_all(bind=engine) engine.dispose() @pytest.fixture() def session_factory(engine: Engine) -> Iterator[sessionmaker]: testing_session = sessionmaker( bind=engine, expire_on_commit=False, future=True) yield testing_session @pytest.fixture() def client(session_factory: sessionmaker) -> Iterator[TestClient]: app = FastAPI() app.include_router(dashboard_router) app.include_router(projects_router) app.include_router(scenarios_router) def _override_uow() -> Iterator[UnitOfWork]: with UnitOfWork(session_factory=session_factory) as uow: yield uow app.dependency_overrides[get_unit_of_work] = _override_uow test_client = TestClient(app) try: yield test_client finally: test_client.close() class TestDashboardRoute: def test_renders_empty_state(self, client: TestClient) -> None: response = client.get("/") assert response.status_code == 200 html = response.text assert "No recent projects" in html assert "No simulation runs yet" in html assert "All scenarios look good" in html assert "—" in html # Last data import placeholder