"""URLs publiques de l'écosystème par configuration — #223 (dev/prod). Règle : aucun nom public de l'écosystème n'est figé dans le code vivant. Défauts = noms **officiels** (production future) ; le dev déclare ses noms en ``-dev`` dans son seul ``.env`` (``DRACO_*_URL`` / ``AGENT_EVENEMENTS_URL``). On vérifie ici la config centralisée, la dérivation de l'URL d'événements du journal, la reconnaissance des liens profonds des deux environnements et la reconstruction des URL d'affichage des références croisées. """ import pytest from backend import draco_config @pytest.fixture() def env_propre(monkeypatch): """Aucune variable d'URL d'écosystème posée (défauts officiels).""" for nom in ( "DRACO_AGENT_URL", "DRACO_OBSIGATE_URL", "DRACO_FLOWDECK_URL", "DRACO_TIKTAK_URL", "DRACO_KANBANTE_URL", "DRACO_GITEA_URL", "AGENT_EVENEMENTS_URL", ): monkeypatch.delenv(nom, raising=False) return monkeypatch def test_defauts_officiels_sans_dev(env_propre): assert draco_config.agent_url() == "https://agent.dracodev.net" assert draco_config.app_url("tiktak") == "https://tiktak.dracodev.net" assert draco_config.app_url("obsigate") == "https://og.dracodev.net" assert draco_config.app_url("flowdeck") == "https://flowdeck.dracodev.net" assert draco_config.app_url("kanbante") == "https://kanbante.dracodev.net" assert draco_config.app_url("gitea") == "https://git.dracodev.net" for url in draco_config.urls_publiques().values(): assert "-dev" not in url def test_agent_derive_des_evenements(env_propre): """Sans DRACO_AGENT_URL, l'origine suit AGENT_EVENEMENTS_URL — la configuration réelle du poste (dev inclus).""" env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://agent-dev.dracodev.net/api/v1/evenements") assert draco_config.agent_url() == "https://agent-dev.dracodev.net" assert draco_config.agent_origine() == "https://agent-dev.dracodev.net" def test_agent_explicite_prime(env_propre): env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://agent-dev.dracodev.net/api/v1/evenements") env_propre.setenv("DRACO_AGENT_URL", "https://agent.example.net/") assert draco_config.agent_url() == "https://agent.example.net" # ------------------------------------------------- BUG-120 : dérivation sœurs def test_soeurs_derivees_depuis_agent_dev(env_propre): """BUG-120 : avec **seul** ``AGENT_EVENEMENTS_URL`` en ``-dev`` posé (aucune ``DRACO__URL``), les URL sœurs servies suivent l'environnement de l'agent ; Gitea ne bouge jamais.""" env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://agent-dev.dracodev.net/api/v1/evenements") urls = draco_config.urls_publiques() assert urls["agent"] == "https://agent-dev.dracodev.net" assert urls["obsigate"] == "https://og-dev.dracodev.net" assert urls["flowdeck"] == "https://flowdeck-dev.dracodev.net" assert urls["tiktak"] == "https://tiktak-dev.dracodev.net" assert urls["kanbante"] == "https://kanbante-dev.dracodev.net" assert urls["gitea"] == "https://git.dracodev.net" def test_soeurs_derivees_depuis_draco_agent_url(env_propre): """BUG-120 : la dérivation lit l'agent via ``agent_url()`` — un ``DRACO_AGENT_URL`` en ``-dev`` suffit aussi.""" env_propre.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") assert draco_config.app_url("tiktak") == "https://tiktak-dev.dracodev.net" assert draco_config.app_url("obsigate") == "https://og-dev.dracodev.net" def test_soeur_explicite_prime_sur_derivation(env_propre): """BUG-120 : une ``DRACO__URL`` explicite gagne toujours sur la dérivation d'environnement ; les autres sœurs dérivent.""" env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://agent-dev.dracodev.net/api/v1/evenements") env_propre.setenv("DRACO_TIKTAK_URL", "https://taches.example.net/") assert draco_config.app_url("tiktak") == "https://taches.example.net" assert draco_config.app_url("flowdeck") == "https://flowdeck-dev.dracodev.net" assert draco_config.app_url("kanbante") == "https://kanbante-dev.dracodev.net" @pytest.mark.parametrize("evenements", [ "https://agent.example.net/api/v1/evenements", # autre domaine "https://agent-dev.example.com/api/v1/evenements", # suffixe hors dracodev.net "http://deepin.lab.home:8790/api/v1/evenements", # nom LAN + port "http://192.168.30.101:8790/api/v1/evenements", # IP + port "https://agent-dev.dracodev.net:8790/api/v1/evenements", # port exotique ]) def test_agent_hors_motif_aucune_derivation(env_propre, evenements): """BUG-120 : hôte d'agent hors motif ``agent.dracodev.net`` → **aucune dérivation** (jamais de lien deviné), défauts officiels.""" env_propre.setenv("AGENT_EVENEMENTS_URL", evenements) urls = draco_config.urls_publiques() assert urls["obsigate"] == "https://og.dracodev.net" assert urls["flowdeck"] == "https://flowdeck.dracodev.net" assert urls["tiktak"] == "https://tiktak.dracodev.net" assert urls["kanbante"] == "https://kanbante.dracodev.net" assert urls["gitea"] == "https://git.dracodev.net" def test_agent_prod_suffixe_vide_defauts_officiels(env_propre): """BUG-120 : hôte d'agent prod (suffixe vide) → les sœurs dérivées sont exactement les défauts officiels.""" env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://agent.dracodev.net/api/v1/evenements") for app, defaut in draco_config.DEFAUTS.items(): assert draco_config.app_url(app) == defaut def test_journal_url_suit_la_config(env_propre): from backend import agent_journal assert agent_journal._url() == "https://agent.dracodev.net/api/v1/evenements" env_propre.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") assert agent_journal._url() == "https://agent-dev.dracodev.net/api/v1/evenements" env_propre.setenv( "AGENT_EVENEMENTS_URL", "https://autre.example.net/api/v1/evenements") assert agent_journal._url() == "https://autre.example.net/api/v1/evenements" # ------------------------------------------------------------ liens profonds def test_parse_hotes_configures(env_propre): """Un lien collé depuis l'environnement dev (hôtes déclarés dans son .env) est reconnu, comme un lien officiel.""" from backend.external_refs import parse_deep_link env_propre.setenv("DRACO_TIKTAK_URL", "https://tiktak-dev.dracodev.net") env_propre.setenv("DRACO_OBSIGATE_URL", "https://og-dev.dracodev.net") assert parse_deep_link("https://tiktak-dev.dracodev.net/?task=5") == ( "tiktak", "task", "5", "TikTak · tâche 5") assert parse_deep_link("https://og-dev.dracodev.net/#file=v:Dossier/Note.md") == ( "obsigate", "note", "v:Dossier/Note.md", "ObsiGate · Note.md") # L'officiel reste reconnu en parallèle (lien venu de la prod). assert parse_deep_link("https://tiktak.dracodev.net/?task=5") is not None def test_url_affichage_reconstruite_depuis_config(env_propre, tmp_path): """#223 : la référence stockée garde son URL absolue d'origine (aucune migration), mais l'URL **servie** est reconstruite depuis la config courante.""" from backend.external_refs import add_ref, build_deep_link, list_refs env_propre.setenv("OBSIGATE_EXTERNAL_REFS_DIR", str(tmp_path / "refs")) assert build_deep_link("tiktak", "task", "42") == \ "https://tiktak.dracodev.net/?task=42" assert build_deep_link("kanbante", "card", "Projets/obsigate#7") == \ "https://git.dracodev.net/Projets/obsigate/issues/7" assert build_deep_link("obsigate", "note", "v:Dossier/Note.md") == \ "https://og.dracodev.net/#file=v:Dossier%2FNote.md" env_propre.setenv("DRACO_TIKTAK_URL", "https://tiktak-dev.dracodev.net") ref = add_ref("alice", "Vault", "N.md", "tiktak", "task", "42", "https://tiktak.dracodev.net/?task=42", "TikTak · tâche 42") assert ref["target_url"] == "https://tiktak.dracodev.net/?task=42" # stocké tel quel servies = list_refs("alice", "Vault", "N.md") assert servies[0]["target_url"] == "https://tiktak-dev.dracodev.net/?task=42" # ------------------------------------------------------------ injection hôte def test_index_injecte_draco_urls(client, env_propre): """L'hôte sert index.html avec window.DRACO_URLS issu de sa config. BUG-120 : l'agent en ``-dev`` entraîne les sœurs en ``-dev`` (dérivation d'environnement) — avant, ``tiktak`` restait en prod. """ env_propre.setenv("DRACO_AGENT_URL", "https://agent-dev.dracodev.net") resp = client.get("/") assert resp.status_code == 200 assert "window.DRACO_URLS" in resp.text assert '"agent": "https://agent-dev.dracodev.net"' in resp.text assert '"tiktak": "https://tiktak-dev.dracodev.net"' in resp.text assert '"gitea": "https://git.dracodev.net"' in resp.text