"""Tests unitaires pour les utilitaires de masquage des secrets. Ce module vérifie que les fonctions de masquage des URLs, des en-têtes et des secrets dans les textes fonctionnent correctement, sans fuite d'informations sensibles. """ from __future__ import annotations from pydantic import SecretStr from pronote_sync.utils.redaction import redact_exception, redact_secrets, redact_url def test_redact_url_with_sensitive_query_param() -> None: """Vérifie que les paramètres sensibles dans une URL sont masqués. :return: None """ url = "https://example.fr/ical?icalsecurise=TOKEN123" # pragma: allowlist secret redacted = redact_url(url) assert "TOKEN123" not in redacted assert "REDACTED" in redacted def test_redact_url_with_embedded_auth() -> None: """Vérifie que les informations d'authentification intégrées dans une URL sont masquées. :return: None """ url = "https://user:pass@host/path" # pragma: allowlist secret redacted = redact_url(url) assert "user" not in redacted assert "pass" not in redacted assert "REDACTED" in redacted def test_redact_url_with_uppercase_scheme() -> None: """Vérifie que les URLs avec un schéma en majuscules sont traitées correctement. :return: None """ url = "HTTPS://user:pass@host/path" # pragma: allowlist secret redacted = redact_url(url) assert "user" not in redacted assert "pass" not in redacted assert "REDACTED" in redacted def test_redact_secrets_authorization_bearer() -> None: """Vérifie que les en-têtes Authorization: Bearer sont masqués. :return: None """ text = "Authorization: Bearer mytoken123" # pragma: allowlist secret redacted = redact_secrets(text) assert "mytoken123" not in redacted assert "REDACTED" in redacted def test_redact_secrets_proxy_authorization_basic() -> None: """Vérifie que les en-têtes Proxy-Authorization: Basic sont masqués. :return: None """ text = "Proxy-Authorization: Basic dXNlcjpwYXNz" # pragma: allowlist secret redacted = redact_secrets(text) assert "dXNlcjpwYXNz" not in redacted assert "REDACTED" in redacted def test_redact_secrets_lowercase_authorization() -> None: """Vérifie que les en-têtes authorization en minuscules sont masqués. :return: None """ text = "authorization: Bearer tok" # pragma: allowlist secret redacted = redact_secrets(text) assert "tok" not in redacted assert "REDACTED" in redacted def test_redact_secrets_text_key_value() -> None: """Vérifie que les affectations clé=valeur dans du texte sont masquées. :return: None """ text = "password=mysecret" # pragma: allowlist secret redacted = redact_secrets(text) assert "mysecret" not in redacted assert "REDACTED" in redacted def test_redact_secrets_json_key_value() -> None: """Vérifie que les secrets dans du JSON sont masqués. :return: None """ text = '{"api_key": "myapikey"}' # pragma: allowlist secret redacted = redact_secrets(text) assert "myapikey" not in redacted assert "REDACTED" in redacted def test_redact_exception() -> None: """Vérifie que les exceptions contenant des secrets sont masquées. :return: None """ exc = Exception("Authorization: Bearer leaked_token") # pragma: allowlist secret redacted_msg = redact_exception(exc) assert "leaked_token" not in redacted_msg assert "REDACTED" in redacted_msg def test_redact_url_preserves_host_and_path() -> None: """Vérifie que l'hôte et le chemin d'une URL sont préservés après masquage. :return: None """ url = "https://user:pass@example.fr/path?icalsecurise=tok" # pragma: allowlist secret redacted = redact_url(url) assert "example.fr" in redacted assert "/path" in redacted assert "user" not in redacted assert "pass" not in redacted assert "tok" not in redacted # --- Tests pour redact_secrets avec extra_secrets (FIXME_M9 Point 1) --- def test_redact_secrets_with_extra_secrets_raw() -> None: """Vérifie que redact_secrets masque les secrets supplémentaires fournis sous forme brute.""" text = "text with sk-abc123" redacted = redact_secrets(text, extra_secrets=["sk-abc123"]) assert "sk-abc123" not in redacted assert "REDACTED" in redacted def test_redact_secrets_with_extra_secrets_secret_str() -> None: """Vérifie que redact_secrets masque les secrets supplémentaires fournis sous SecretStr.""" text = "text with sk-abc123" redacted = redact_secrets(text, extra_secrets=[SecretStr("sk-abc123")]) assert "sk-abc123" not in redacted assert "REDACTED" in redacted def test_redact_secrets_with_extra_secrets_empty_values() -> None: """Vérifie que redact_secrets ignore les valeurs vides dans extra_secrets.""" text = "text" redacted = redact_secrets(text, extra_secrets=[""]) assert redacted == "text" # Ensure trailing newline