"""Integration tests for API endpoints.""" from importlib import metadata import pytest from fastapi.testclient import TestClient from backend.main import app, compatibility_status client = TestClient(app) @pytest.mark.integration class TestAPIIntegration: """Integration tests for API endpoints.""" def test_health_check(self) -> None: """Test API health check endpoint.""" response = client.get("/health") assert response.status_code == 200 assert response.json() == {"status": "healthy"} def test_root_endpoint(self) -> None: """Test root endpoint.""" response = client.get("/") assert response.status_code == 200 assert response.json() == {"message": "Plex Playlist Backend API"} def test_startup_rejects_invalid_runtime_policy( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Startup should fail fast when compatibility policy is invalid.""" monkeypatch.setenv("BACKEND_REQUIRED_PYTHON", "99.0") with pytest.raises(RuntimeError), TestClient(app): pass monkeypatch.delenv("BACKEND_REQUIRED_PYTHON", raising=False) def test_compatibility_endpoint_reports_policy_status( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Compatibility endpoint should expose runtime and pinning policy status.""" monkeypatch.setenv("BACKEND_REQUIRED_PYTHON", "3.14") with TestClient(app) as local_client: response = local_client.get("/compatibility") assert response.status_code == 200 payload = response.json() assert payload["ok"] is True assert payload["required_python"] == "3.14" assert "current_python" in payload assert payload["python_policy_valid"] is True assert "required_packages" in payload assert payload["required_packages"]["fastapi"] == "0.120.2" assert payload["required_packages"]["uvicorn"] == "0.38.0" assert payload["package_errors"] == {} monkeypatch.delenv("BACKEND_REQUIRED_PYTHON", raising=False) def test_startup_rejects_malformed_required_python( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Startup should fail fast when Python policy is not strict major.minor.""" monkeypatch.setenv("BACKEND_REQUIRED_PYTHON", "3.14.1") with pytest.raises(RuntimeError), TestClient(app): pass monkeypatch.delenv("BACKEND_REQUIRED_PYTHON", raising=False) def test_compatibility_status_handles_missing_package_metadata( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Compatibility checks should handle missing package metadata gracefully.""" def raise_not_found(_: str) -> str: raise metadata.PackageNotFoundError("fake") monkeypatch.setattr("backend.main._installed_version", raise_not_found) status = compatibility_status() package_checks = status["package_checks"] package_errors = status["package_errors"] assert status["ok"] is False assert isinstance(package_checks, dict) assert isinstance(package_errors, dict) assert package_checks["fastapi"] is False assert package_checks["uvicorn"] is False assert "fastapi" in package_errors assert "uvicorn" in package_errors