"""Tests for duty_teller.utils.http_client (safe_urlopen scheme check)."""

from unittest.mock import MagicMock, patch

import pytest
from urllib.request import Request

from duty_teller.utils.http_client import safe_urlopen


def test_safe_urlopen_rejects_file_scheme():
    """safe_urlopen: file:// URL raises ValueError and does not call urlopen."""
    req = Request("file:///etc/passwd")
    with patch("duty_teller.utils.http_client.urlopen") as mock_urlopen:
        with pytest.raises(ValueError, match="scheme not allowed"):
            with safe_urlopen(req, timeout=5):
                pass
    mock_urlopen.assert_not_called()


def test_safe_urlopen_rejects_ftp_scheme():
    """safe_urlopen: ftp:// URL raises ValueError and does not call urlopen."""
    req = Request("ftp://example.com/file.txt")
    with patch("duty_teller.utils.http_client.urlopen") as mock_urlopen:
        with pytest.raises(ValueError, match="scheme not allowed"):
            with safe_urlopen(req, timeout=5):
                pass
    mock_urlopen.assert_not_called()


def test_safe_urlopen_allows_https():
    """safe_urlopen: https:// URL is allowed and urlopen is called."""
    req = Request("https://api.telegram.org/bot123/setChatMenuButton")
    mock_resp = MagicMock()
    mock_resp.__enter__ = MagicMock(return_value=mock_resp)
    mock_resp.__exit__ = MagicMock(return_value=False)
    with patch(
        "duty_teller.utils.http_client.urlopen", return_value=mock_resp
    ) as mock_urlopen:
        with safe_urlopen(req, timeout=10) as resp:
            assert resp is mock_resp
    mock_urlopen.assert_called_once_with(req, timeout=10)


def test_safe_urlopen_allows_http_when_in_allowed_schemes():
    """safe_urlopen: http:// URL is allowed when allowed_schemes includes http."""
    req = Request("http://localhost:8080/health")
    mock_resp = MagicMock()
    mock_resp.__enter__ = MagicMock(return_value=mock_resp)
    mock_resp.__exit__ = MagicMock(return_value=False)
    with patch(
        "duty_teller.utils.http_client.urlopen", return_value=mock_resp
    ) as mock_urlopen:
        with safe_urlopen(req, timeout=5, allowed_schemes=("https", "http")) as resp:
            assert resp is mock_resp
    mock_urlopen.assert_called_once_with(req, timeout=5)
