refactor: noms publics dracodev par configuration (dev/prod)
Aucun nom public d'une autre app dracodev n'est codé en dur dans le code vivant : nouveau module app/services/draco_urls.py (env > config > défaut officiel, jamais de -dev en défaut). CSP connect-src/frame-src, bouton SSO ObsiGate, révocations SSO, événements agent, preset MCP TikTak, barre commune, panneau Spark (injection hôte DRACO_PANNEAU_CONFIG), refs croisées (hôte configuré + officiel reconnus, URL d'affichage reconstruite, aucune donnée stockée migrée), User-Agent OG, liens Gitea. Variables ajoutées DRACO_AGENT_URL/TIKTAK_URL/KANBANTE_URL/FLOWDECK_URL, réutilisées DRACO_SSO_URL/OAUTH_REDIRECT_URI/AGENT_EVENEMENTS_URL/GITEA_URL/APP_BASE_URL. Version 7.82.0.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""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")
|
||||
Reference in New Issue
Block a user