Files
flowdeck/tests/test_draco_alertes.py
T
bruno ce2ac08dd3
FlowDeck CI / lint (push) Failing after 4s
FlowDeck CI / test (push) Failing after 2s
FlowDeck CI / docker (push) Skipped
FlowDeck CI / lint (pull_request) Failing after 2s
FlowDeck CI / test (pull_request) Failing after 1s
FlowDeck CI / docker (pull_request) Skipped
Chantier 5 (fusion #69/#71) : alertes en onglets + onglet Console Spark : test pytest chantier 5
2026-10-28 13:51:31 -04:00

85 lines
3.8 KiB
Python

"""Fusion #69 — Alertes unifiées (chantier 2 + chantier 5, Flowdeck).
Source réelle de Flowdeck : GET /api/notifications (non lues =
actives, `url` relative pour le lien profond), déjà exposée et
inchangée ici. Couverts : placeholder Alertes disparu, module servi,
CSP connect-src avec les origines soeurs, CORS (origines soeurs
ajoutées à allow_origins ; tiers sans en-tête).
"""
SOEURS = ("https://og.dracodev.net", "https://flowdeck.dracodev.net",
"https://tiktak.dracodev.net", "https://kanbante.dracodev.net")
def test_barre_alertes_sans_placeholder_et_module_servi(client):
# Les pages applicatives authentifiées ne sont pas atteignables
# telles quelles dans la sandbox (l'écran de connexion est servi
# pour "/" comme pour "/dashboard") : on vérifie donc le gabarit
# livré lui-même, plus les fichiers statiques servis.
from pathlib import Path
gabarit = Path("app/templates/_draco_bar.html").read_text()
assert "Alertes unifiées : arrive avec la fédération" not in gabarit
assert "draco-alertes.js" in gabarit
assert "draco-alertes.css" in gabarit
assert "DRACO_ALERTES.open()" in gabarit
js = client.get("/static/js/draco-alertes.js")
assert js.status_code == 200
assert "DRACO_ALERTES" in js.text
assert "api/notifications" in js.text
css = client.get("/static/css/draco-alertes.css")
assert css.status_code == 200
assert "draco-alertes-overlay" in css.text
def test_csp_connect_src_contient_les_soeurs(client):
# La CSP est posée sur toute réponse HTML, y compris l'écran de
# connexion servi ici : elle prouve les origines soeurs en
# connect-src pour les pages de l'hôte.
r = client.get("/")
csp = r.headers.get("content-security-policy", "")
assert "connect-src" in csp
for origine in SOEURS:
assert origine in csp, csp
def test_notifications_api_et_cors_soeur(client):
r = client.get("/api/notifications")
assert r.status_code == 200
body = r.json()
assert isinstance(body["notifications"], list)
assert "unread" in body
r2 = client.options("/api/notifications",
headers={"Origin": "https://tiktak.dracodev.net",
"Access-Control-Request-Method": "GET"})
assert r2.headers.get("access-control-allow-origin") == "https://tiktak.dracodev.net"
assert r2.headers.get("access-control-allow-credentials") == "true"
r3 = client.get("/api/notifications",
headers={"Origin": "https://tiktak.dracodev.net"})
assert r3.headers.get("access-control-allow-origin") == "https://tiktak.dracodev.net"
r4 = client.options("/api/notifications",
headers={"Origin": "https://evil.example",
"Access-Control-Request-Method": "GET"})
assert "access-control-allow-origin" not in r4.headers
def test_chantier5_onglet_console_spark_et_alertes_onglets(client):
"""Chantier 5 : onglet Console Spark en dernier dans la barre
(gabarit lu, pages authentifiées inatteignables en sandbox comme
pour le test #69), et vue Alertes en onglets (module + styles)."""
from pathlib import Path
gabarit = Path("app/templates/_draco_bar.html").read_text()
nav = gabarit.split('<nav class="draco-apptabs"')[1].split("</nav>")[0]
assert nav.index('data-app="kanbante"') < nav.index('data-app="agent"')
assert "Console Spark" in nav
js = client.get("/static/js/draco-alertes.js")
assert js.status_code == 200
assert "draco-alertes-tab" in js.text
assert "historique" in js.text
assert "source indisponible" in js.text
css = client.get("/static/css/draco-alertes.css")
assert css.status_code == 200
assert "draco-alertes-tab" in css.text
assert "draco-alertes-filtre" in css.text