"""Tests — cookies Secure, CORS same-origin implicite, avertissement bind (ROADMAP #87 T3). - `is_secure_cookies()` suit `OBSIGATE_SECURE_COOKIES` (défaut `false` : compatibilité logins en HTTP local — les navigateurs ignorent les cookies `Secure` en clair). - Aucun en-tête CORS permissif n'est émis : sans `CORSMiddleware`, les navigateurs appliquent le same-origin par défaut (politique explicite par l'absence — vérifiée ici pour qu'un ajout futur de CORS soit conscient). """ from __future__ import annotations def test_secure_cookies_default_false(monkeypatch): """Défaut `false` (logins HTTP locaux préservés).""" from backend.auth.router import is_secure_cookies monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False) assert is_secure_cookies() is False def test_secure_cookies_opt_in(monkeypatch): """`OBSIGATE_SECURE_COOKIES=true` → flag actif (insensible à la casse).""" from backend.auth.router import is_secure_cookies for value in ("true", "True", "TRUE", "1", "yes"): monkeypatch.setenv("OBSIGATE_SECURE_COOKIES", value) assert is_secure_cookies() is (value.lower() == "true") def test_no_cors_headers_on_api(client): """Pas de `Access-Control-Allow-Origin` : same-origin imposé par le navigateur.""" resp = client.get("/api/health") assert resp.status_code == 200 assert "access-control-allow-origin" not in {k.lower() for k in resp.headers} def test_no_cors_headers_on_public_share(client): """Idem sur la page publique de partage.""" resp = client.get("/s/jeton-inexistant") assert resp.status_code == 404 assert "access-control-allow-origin" not in {k.lower() for k in resp.headers} def test_security_headers_present(client): """En-têtes de durcissement posés par le middleware (non-régression).""" resp = client.get("/api/health") assert resp.headers.get("x-content-type-options") == "nosniff" assert resp.headers.get("x-frame-options") == "SAMEORIGIN" csp = resp.headers.get("content-security-policy", "") assert "object-src 'none'" in csp assert "frame-ancestors 'self'" in csp