"""Secret-redaction helper regression tests.

Locks in the patterns that surface from real provider error paths:
Telegram bot URLs in aiohttp.ClientError messages, Authorization Bearer
tokens in Matrix/ntfy responses, Discord/Slack webhook tokens, URL
userinfo, and common ?token= query params.
"""

from __future__ import annotations

import pytest

from notify_bridge_core.notifications.redact import redact, redact_exc


@pytest.mark.parametrize(
    "raw,expected_substr,not_in",
    [
        (
            "Cannot connect to host api.telegram.org/bot1234567:AABBCC-secret-token/sendMessage",
            "api.telegram.org/bot***",
            "AABBCC-secret-token",
        ),
        (
            "Authorization: Bearer ey.JhbGciOiJIUzI1NiJ9.payload.sig",
            "Bearer ***",
            "ey.JhbGciOiJIUzI1NiJ9",
        ),
        (
            "POST https://discord.com/api/webhooks/12345/abcdefg-token failed",
            "discord.com/api/webhooks/12345/***",
            "abcdefg-token",
        ),
        (
            "POST https://hooks.slack.com/services/T01/B02/zzzzz failed",
            "hooks.slack.com/services/T01/B02/***",
            "zzzzz",
        ),
        (
            "fetch http://user:supersecret@example.com/foo",
            "http://***@example.com/foo",
            "supersecret",
        ),
        (
            "https://api.example.com/x?token=mytoken123&extra=ok",
            "token=***",
            "mytoken123",
        ),
    ],
)
def test_redact_known_secrets(raw: str, expected_substr: str, not_in: str) -> None:
    out = redact(raw)
    assert expected_substr in out
    assert not_in not in out


def test_redact_idempotent() -> None:
    once = redact("Bearer abcdefghij1234567890")
    twice = redact(once)
    assert once == twice


def test_redact_exc_returns_str() -> None:
    err = RuntimeError("Bearer abcdefghij1234567890")
    out = redact_exc(err)
    assert isinstance(out, str)
    assert "Bearer ***" in out
    assert "abcdefghij1234567890" not in out


def test_redact_handles_non_string() -> None:
    # Coercion path should not raise.
    out = redact(12345)  # type: ignore[arg-type]
    assert out == "12345"
