"""Basic Auth opzionale del servizio web. `get_settings()` è lru_cache: ogni test imposta le env, pulisce la cache e ricrea l'app perché il middleware legga la configurazione corrente. """ import base64 import pytest from fastapi.testclient import TestClient from config.runtime.settings import get_settings from web.app import create_app def _auth_header(user: str, password: str) -> dict: token = base64.b64encode(f"{user}:{password}".encode()).decode() return {"Authorization": f"Basic {token}"} @pytest.fixture() def configure(monkeypatch): """Imposta le env di auth, pulisce la cache settings e ricrea l'app.""" def _make(enabled: bool, user: str = "", password: str = "") -> TestClient: monkeypatch.setenv("BASIC_AUTH_ENABLED", "true" if enabled else "false") monkeypatch.setenv("BASIC_AUTH_USER", user) monkeypatch.setenv("BASIC_AUTH_PASS", password) get_settings.cache_clear() return TestClient(create_app()) yield _make get_settings.cache_clear() def test_disabled_allows_without_credentials(configure): client = configure(enabled=False) assert client.get("/healthz").status_code == 200 assert client.get("/").status_code == 200 def test_enabled_rejects_missing_credentials(configure): client = configure(enabled=True, user="demo", password="secret") res = client.get("/") assert res.status_code == 401 assert res.headers.get("WWW-Authenticate", "").lower().startswith("basic") def test_enabled_rejects_wrong_credentials(configure): client = configure(enabled=True, user="demo", password="secret") res = client.get("/", headers=_auth_header("demo", "wrong")) assert res.status_code == 401 def test_enabled_accepts_correct_credentials(configure): client = configure(enabled=True, user="demo", password="secret") res = client.get("/", headers=_auth_header("demo", "secret")) assert res.status_code == 200 def test_healthz_bypasses_auth(configure): client = configure(enabled=True, user="demo", password="secret") assert client.get("/healthz").status_code == 200 def test_enabled_without_credentials_fails_fast(configure, monkeypatch): monkeypatch.setenv("BASIC_AUTH_ENABLED", "true") monkeypatch.setenv("BASIC_AUTH_USER", "") monkeypatch.setenv("BASIC_AUTH_PASS", "") get_settings.cache_clear() with pytest.raises(RuntimeError): create_app()