"""URLs publiques dracodev par configuration — chantier dev/prod (v7.82.0). Règle vérifiée : aucun nom public codé en dur dans le code vivant ; les défauts sont les noms OFFICIELS (jamais de ``-dev`` en défaut) et chaque environnement déclare ses noms en ``-dev`` par l'environnement (``DRACO_SSO_URL``, ``DRACO_AGENT_URL``, ``TIKTAK_URL``, ``KANBANTE_URL``, ``FLOWDECK_URL``/``OAUTH_REDIRECT_URI``…). """ import pytest from app.services import draco_urls VARS = ("DRACO_SSO_URL", "DRACO_AGENT_URL", "TIKTAK_URL", "KANBANTE_URL", "FLOWDECK_URL", "OAUTH_REDIRECT_URI", "AGENT_EVENEMENTS_URL") @pytest.fixture(autouse=True) def _env_propre(monkeypatch): for v in VARS: monkeypatch.delenv(v, raising=False) def test_defauts_officiels_sans_dev(): urls = draco_urls.toutes() assert urls["obsigate"] == "https://og.dracodev.net" assert urls["agent"] == "https://agent.dracodev.net" assert urls["tiktak"] == "https://tiktak.dracodev.net" assert urls["kanbante"] == "https://kanbante.dracodev.net" assert urls["flowdeck"] == "https://flowdeck.dracodev.net" assert all("-dev" not in u for u in urls.values()) def test_surcharge_dev_par_env(monkeypatch): monkeypatch.setenv("DRACO_SSO_URL", "https://og-dev.dracodev.net") monkeypatch.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") monkeypatch.setenv("TIKTAK_URL", "https://tiktak-dev.dracodev.net") monkeypatch.setenv("KANBANTE_URL", "https://kanbante-dev.dracodev.net") monkeypatch.setenv("FLOWDECK_URL", "https://flowdeck-dev.dracodev.net") urls = draco_urls.toutes() assert urls["obsigate"] == "https://og-dev.dracodev.net" assert urls["agent"] == "https://agent-dev.dracodev.net" assert urls["tiktak"] == "https://tiktak-dev.dracodev.net" assert urls["kanbante"] == "https://kanbante-dev.dracodev.net" assert urls["flowdeck"] == "https://flowdeck-dev.dracodev.net" def test_flowdeck_url_derivée_oauth_redirect(monkeypatch): monkeypatch.setenv( "OAUTH_REDIRECT_URI", "https://flowdeck-dev.dracodev.net/auth/callback") assert draco_urls.flowdeck_url() == "https://flowdeck-dev.dracodev.net" def test_evenements_url_derivée_agent(monkeypatch): from app.services import agent_evenements monkeypatch.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") assert agent_evenements._url() == \ "https://agent-dev.dracodev.net/api/v1/evenements" monkeypatch.setenv("AGENT_EVENEMENTS_URL", "http://127.0.0.1:9/api/v1/evenements") assert agent_evenements._url() == "http://127.0.0.1:9/api/v1/evenements" def test_csp_agent_depuis_config(client, monkeypatch): monkeypatch.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") r = client.get("/") csp = r.headers.get("content-security-policy", "") assert "https://agent-dev.dracodev.net" in csp assert "connect-src 'self' https://agent-dev.dracodev.net" in csp assert "frame-src 'self' https://agent-dev.dracodev.net" in csp assert "https://agent.dracodev.net " not in csp.replace( "https://agent-dev.dracodev.net", "") def test_parse_deep_link_dev_et_officiel(monkeypatch): from app.services.external_refs import parse_deep_link monkeypatch.setenv("TIKTAK_URL", "https://tiktak-dev.dracodev.net") monkeypatch.setenv("DRACO_SSO_URL", "https://og-dev.dracodev.net") # Hôte configuré (dev)… assert parse_deep_link("https://tiktak-dev.dracodev.net/?task=7")[:3] == \ ("tiktak", "task", "7") assert parse_deep_link("https://og-dev.dracodev.net/#file=P:A.md")[:3] == \ ("obsigate", "note", "P:A.md") # …et hôte officiel toujours reconnu (références déjà stockées). assert parse_deep_link("https://tiktak.dracodev.net/?task=7")[:3] == \ ("tiktak", "task", "7") assert parse_deep_link("https://og.dracodev.net/#file=P:A.md")[:3] == \ ("obsigate", "note", "P:A.md") def test_url_affichage_reecrit_hote_sans_toucher_stockage(monkeypatch): from app.services.external_refs import url_affichage monkeypatch.setenv("TIKTAK_URL", "https://tiktak-dev.dracodev.net") stockee = "https://tiktak.dracodev.net/?task=42" assert url_affichage(stockee) == "https://tiktak-dev.dracodev.net/?task=42" # La fonction est pure : la valeur d'entrée (celle en base) ne bouge pas. assert stockee == "https://tiktak.dracodev.net/?task=42" assert url_affichage("https://example.com/x") == "https://example.com/x" def test_preset_tiktak_depuis_config(monkeypatch): from app.services import connectors assert connectors.PRESETS["tiktak"]["url"] == \ "https://tiktak.dracodev.net/mcp" monkeypatch.setenv("TIKTAK_URL", "https://tiktak-dev.dracodev.net") assert connectors.PRESETS["tiktak"]["url"] == \ "https://tiktak-dev.dracodev.net/mcp" def test_bouton_sso_login_depuis_config(monkeypatch): from app.routers.auth import _sso_login_url assert _sso_login_url() == ( "https://og.dracodev.net/sso/authorize?return_to=" "https%3A%2F%2Fflowdeck.dracodev.net%2Fauth%2Fdraco") monkeypatch.setenv("DRACO_SSO_URL", "https://og-dev.dracodev.net") monkeypatch.setenv( "OAUTH_REDIRECT_URI", "https://flowdeck-dev.dracodev.net/auth/callback") assert _sso_login_url() == ( "https://og-dev.dracodev.net/sso/authorize?return_to=" "https%3A%2F%2Fflowdeck-dev.dracodev.net%2Fauth%2Fdraco")