from unittest.mock import MagicMock, patch import httpx from src.modules.discovery import find_live_video, get_channel_info def _mock_settings_with_key(): mock_settings = MagicMock() mock_settings.YOUTUBE_API_KEY = "fake-key" mock_settings.YOUTUBE_SEARCH_BASE = "https://www.googleapis.com/youtube/v3/search" mock_settings.YOUTUBE_CHANNELS_BASE = ( "https://www.googleapis.com/youtube/v3/channels" ) return mock_settings class TestFindLiveVideo: def test_returns_video_id_when_live(self) -> None: mock_response = MagicMock() mock_response.json.return_value = { "items": [ { "id": {"videoId": "dQw4w9WgXcQ"}, "snippet": {"title": "Live Lofi Stream"}, } ] } mock_response.raise_for_status.return_value = None with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = find_live_video("UC_test_channel") assert result == "dQw4w9WgXcQ" def test_returns_none_when_no_live_video(self) -> None: mock_response = MagicMock() mock_response.json.return_value = {"items": []} mock_response.raise_for_status.return_value = None with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = find_live_video("UC_test_channel") assert result is None def test_returns_none_when_no_api_key(self) -> None: mock_settings = _mock_settings_with_key() mock_settings.YOUTUBE_API_KEY = "" with patch("src.modules.discovery.settings", mock_settings): result = find_live_video("UC_test_channel") assert result is None def test_returns_none_on_http_error(self) -> None: mock_response = MagicMock() mock_response.text = "API quota exceeded" mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Forbidden", request=MagicMock(), response=mock_response ) with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = find_live_video("UC_test_channel") assert result is None def test_returns_none_on_request_error(self) -> None: with patch( "src.modules.discovery.httpx.get", side_effect=httpx.RequestError("Connection refused"), ): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = find_live_video("UC_test_channel") assert result is None class TestGetChannelInfo: def test_returns_channel_details(self) -> None: mock_response = MagicMock() mock_response.json.return_value = { "items": [ { "snippet": { "title": "Lofi Girl", "description": "Beats to relax", "thumbnails": {"default": {"url": "http://thumb.png"}}, }, "statistics": {"subscriberCount": 1000000}, } ] } mock_response.raise_for_status.return_value = None with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = get_channel_info("UC_test_channel") assert result is not None assert result["channel_id"] == "UC_test_channel" assert result["title"] == "Lofi Girl" assert result["description"] == "Beats to relax" assert result["thumbnail"] == "http://thumb.png" assert result["subscriber_count"] == 1000000 def test_returns_none_when_no_items(self) -> None: mock_response = MagicMock() mock_response.json.return_value = {"items": []} mock_response.raise_for_status.return_value = None with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = get_channel_info("UC_test_channel") assert result is None def test_returns_none_when_no_api_key(self) -> None: mock_settings = _mock_settings_with_key() mock_settings.YOUTUBE_API_KEY = "" with patch("src.modules.discovery.settings", mock_settings): result = get_channel_info("UC_test_channel") assert result is None def test_returns_none_on_error(self) -> None: with patch( "src.modules.discovery.httpx.get", side_effect=httpx.RequestError("Timeout"), ): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = get_channel_info("UC_test_channel") assert result is None def test_handles_missing_statistics(self) -> None: mock_response = MagicMock() mock_response.json.return_value = { "items": [ { "snippet": { "title": "Test Channel", "description": "Desc", "thumbnails": {"default": {"url": "http://thumb.png"}}, } } ] } mock_response.raise_for_status.return_value = None with patch("src.modules.discovery.httpx.get", return_value=mock_response): with patch("src.modules.discovery.settings", _mock_settings_with_key()): result = get_channel_info("UC_test_channel") assert result["subscriber_count"] == 0