# tests/unit/test_agent_config.py """ Tests unitaires pour la convention de configuration agent (INC-1 a INC-7). Verifie que : - STREAMING_ENDPOINT contient /api/v1/traces/stream - SERVER_BASE est l'URL sans /api/v1 (pour /health) - Le health check utilise la racine, pas /api/v1 - OLLAMA_HOST est separe de SERVER_URL """ import os import pytest class TestAgentConfig: """Tests de la resolution d'URL dans agent_v1.config.""" def test_streaming_endpoint_includes_api_v1(self, monkeypatch): """STREAMING_ENDPOINT doit contenir /api/v1/traces/stream.""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") # Recharger le module config pour prendre en compte la variable import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert "/api/v1/traces/stream" in config.STREAMING_ENDPOINT assert config.STREAMING_ENDPOINT == "http://192.168.1.40:5005/api/v1/traces/stream" def test_streaming_endpoint_default(self, monkeypatch): """Endpoint par defaut (localhost:5005).""" monkeypatch.delenv("RPA_SERVER_URL", raising=False) import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert config.STREAMING_ENDPOINT == "http://localhost:5005/api/v1/traces/stream" def test_server_base_strips_api_v1(self, monkeypatch): """SERVER_BASE doit etre l'URL sans /api/v1.""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert config.SERVER_BASE == "http://192.168.1.40:5005" assert "/api/v1" not in config.SERVER_BASE def test_server_base_https_domain(self, monkeypatch): """SERVER_BASE avec un domaine HTTPS (reverse proxy).""" monkeypatch.setenv( "RPA_SERVER_URL", "https://lea.labs.laurinebazin.design/api/v1" ) import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert config.SERVER_BASE == "https://lea.labs.laurinebazin.design" def test_health_url_is_root_not_api_v1(self, monkeypatch): """Le health check doit etre sur SERVER_BASE/health (racine).""" monkeypatch.setenv( "RPA_SERVER_URL", "https://lea.labs.laurinebazin.design/api/v1" ) import importlib from agent_v0.agent_v1 import config importlib.reload(config) health_url = f"{config.SERVER_BASE}/health" assert health_url == "https://lea.labs.laurinebazin.design/health" assert "/api/v1/health" not in health_url def test_ollama_host_separate_from_server(self, monkeypatch): """OLLAMA_HOST est independant de SERVER_URL.""" monkeypatch.setenv( "RPA_SERVER_URL", "https://lea.labs.laurinebazin.design/api/v1" ) monkeypatch.delenv("RPA_OLLAMA_HOST", raising=False) import importlib from agent_v0.agent_v1 import config importlib.reload(config) # Par defaut, Ollama est en local assert config.OLLAMA_HOST == "localhost" def test_ollama_host_custom(self, monkeypatch): """OLLAMA_HOST peut etre configure separement.""" monkeypatch.setenv("RPA_OLLAMA_HOST", "192.168.1.40") import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert config.OLLAMA_HOST == "192.168.1.40" def test_no_double_api_v1(self, monkeypatch): """Aucune URL ne doit contenir /api/v1/api/v1 (double prefixe).""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") import importlib from agent_v0.agent_v1 import config importlib.reload(config) all_urls = [ config.SERVER_URL, config.SERVER_BASE, config.STREAMING_ENDPOINT, config.UPLOAD_ENDPOINT, ] for url in all_urls: assert "/api/v1/api/v1" not in url, f"Double /api/v1 dans : {url}" class TestServerClientUrls: """Tests de la resolution d'URL dans lea_ui.server_client.""" def test_stream_url_includes_api_v1(self, monkeypatch): """_stream_url doit contenir /api/v1.""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") from agent_v0.lea_ui.server_client import LeaServerClient client = LeaServerClient() assert "/api/v1" in client._stream_url assert client._stream_url.endswith("/api/v1") def test_stream_base_no_api_v1(self, monkeypatch): """_stream_base ne doit PAS contenir /api/v1.""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") from agent_v0.lea_ui.server_client import LeaServerClient client = LeaServerClient() assert "/api/v1" not in client._stream_base def test_health_on_root(self, monkeypatch): """Le health check doit pointer sur la racine.""" monkeypatch.setenv( "RPA_SERVER_URL", "https://lea.labs.laurinebazin.design/api/v1" ) from agent_v0.lea_ui.server_client import LeaServerClient client = LeaServerClient() health_url = f"{client._stream_base}/health" assert health_url == "https://lea.labs.laurinebazin.design/health" def test_workflows_url_no_double_api_v1(self, monkeypatch): """L'URL workflows ne doit pas avoir /api/v1/api/v1.""" monkeypatch.setenv("RPA_SERVER_URL", "http://192.168.1.40:5005/api/v1") from agent_v0.lea_ui.server_client import LeaServerClient client = LeaServerClient() workflows_url = f"{client._stream_url}/traces/stream/workflows" assert "/api/v1/api/v1" not in workflows_url assert workflows_url == "http://192.168.1.40:5005/api/v1/traces/stream/workflows" class TestScenarios: """Validation des 3 scenarios de deploiement.""" @pytest.mark.parametrize( "server_url,expected_stream,expected_base,expected_health", [ # Scenario 1 : LAN interne ( "http://192.168.1.40:5005/api/v1", "http://192.168.1.40:5005/api/v1/traces/stream", "http://192.168.1.40:5005", "http://192.168.1.40:5005/health", ), # Scenario 2 : Internet via NPM ( "https://lea.labs.laurinebazin.design/api/v1", "https://lea.labs.laurinebazin.design/api/v1/traces/stream", "https://lea.labs.laurinebazin.design", "https://lea.labs.laurinebazin.design/health", ), # Scenario 3 : Dev local (defaut) ( "http://localhost:5005/api/v1", "http://localhost:5005/api/v1/traces/stream", "http://localhost:5005", "http://localhost:5005/health", ), ], ids=["lan", "internet", "localhost"], ) def test_scenario_urls( self, monkeypatch, server_url, expected_stream, expected_base, expected_health ): """Valider la matrice URL pour chaque scenario de deploiement.""" monkeypatch.setenv("RPA_SERVER_URL", server_url) import importlib from agent_v0.agent_v1 import config importlib.reload(config) assert config.STREAMING_ENDPOINT == expected_stream assert config.SERVER_BASE == expected_base assert f"{config.SERVER_BASE}/health" == expected_health