diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000..244873e --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,31 @@ +"""Fixtures compartidas para tests de integración.""" + +from pathlib import Path + +import pytest + +from agentforge_core.api import deps + + +@pytest.fixture +def integration_client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): # type: ignore[no-untyped-def] + """Cliente FastAPI con env apuntando a los assets reales del repo.""" + from fastapi.testclient import TestClient + + from agentforge_core.main import create_app + + repo_root = Path(__file__).parent.parent.parent + monkeypatch.setenv("DATA_DIR", str(tmp_path)) + monkeypatch.setenv("AGENTS_DIR", str(repo_root / "agents")) + monkeypatch.setenv("POLICIES_DIR", str(repo_root / "policies")) + monkeypatch.setenv("LLM_PROVIDER", "mock") + for fn in ( + deps.get_settings, + deps.get_registry, + deps.get_policy_store, + deps.get_orchestrator, + deps.get_llm_provider, + deps.get_guardrail_engine, + ): + fn.cache_clear() + return TestClient(create_app()) diff --git a/tests/integration/test_invoke_happy_path.py b/tests/integration/test_invoke_happy_path.py new file mode 100644 index 0000000..7f5f8ca --- /dev/null +++ b/tests/integration/test_invoke_happy_path.py @@ -0,0 +1,29 @@ +"""Integration: invoca incident_analyzer real con escenario MOS (sin HITL).""" + +from pathlib import Path + +import pytest + +EXAMPLES = ( + Path(__file__).parent.parent.parent / "agents" / "incident_analyzer" / "examples" +) + + +@pytest.mark.integration +def test_happy_path_completa_sin_hitl(integration_client) -> None: # type: ignore[no-untyped-def] + payload = (EXAMPLES / "02_mos_degradation_pool_sbc.txt").read_text(encoding="utf-8") + r = integration_client.post("/agents/incident_analyzer/invoke", json={"input": payload}) + assert r.status_code == 200 + body = r.json() + assert body["status"] == "completed" + assert body["agent_name"] == "incident_analyzer" + assert body["agent_version"] in {"v1", "v2"} + assert body["final_output"]["severity"] in {"low", "medium", "high", "critical"} + # Decision_path debe contener todos los nodos. + steps = {s["step"] for s in body["decision_path"]} + assert "validate_input" in steps + assert "llm_reason" in steps + assert "validate_output" in steps + assert "propose_actions" in steps + assert "approve_gate" in steps + assert "finalize" in steps