from unittest.mock import AsyncMock, MagicMock, patch import pytest from src.modules.discovery import find_live_video, get_channel_info class TestFindLiveVideo: @pytest.mark.asyncio async def test_returns_video_id_when_live(self) -> None: mock_page = MagicMock() mock_video = MagicMock() mock_title = MagicMock() mock_title.get_attribute = AsyncMock(return_value="/watch?v=dQw4w9WgXcQ") mock_video.query_selector = AsyncMock(return_value=mock_title) mock_videos = [mock_video] mock_page.query_selector_all = AsyncMock(return_value=mock_videos) mock_page.close = AsyncMock() mock_page.goto = AsyncMock() mock_page.wait_for_timeout = AsyncMock() mock_browser = MagicMock() mock_browser.new_page = AsyncMock(return_value=mock_page) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=mock_browser)): result = await find_live_video("UC_test_channel", "@testchannel") assert result[0] == "dQw4w9WgXcQ" @pytest.mark.asyncio async def test_returns_none_when_no_video(self) -> None: mock_page = MagicMock() mock_page.query_selector_all = AsyncMock(return_value=[]) mock_page.close = AsyncMock() mock_page.goto = AsyncMock() mock_page.wait_for_timeout = AsyncMock() mock_browser = MagicMock() mock_browser.new_page = AsyncMock(return_value=mock_page) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=mock_browser)): with patch("yt_dlp.YoutubeDL") as mock_ytdlp: mock_ydl = MagicMock() mock_ydl.extract_info.return_value = {"_entries": []} mock_ytdlp.return_value.__enter__ = MagicMock(return_value=mock_ydl) mock_ytdlp.return_value.__exit__ = MagicMock(return_value=False) result = await find_live_video("UC_test_channel", "@testchannel") assert result[0] is None @pytest.mark.asyncio async def test_returns_none_on_error(self) -> None: mock_page = MagicMock() mock_page.goto = AsyncMock(side_effect=Exception("Connection refused")) mock_browser = MagicMock() mock_browser.new_page = AsyncMock(return_value=mock_page) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=mock_browser)): with patch("yt_dlp.YoutubeDL") as mock_ytdlp: mock_ytdlp.side_effect = Exception("yt-dlp error") result = await find_live_video("UC_test_channel", "@testchannel") assert result[0] is None @pytest.mark.asyncio async def test_includes_thumbnail(self) -> None: mock_page = MagicMock() mock_video = MagicMock() mock_title = MagicMock() mock_title.get_attribute = AsyncMock(return_value="/watch?v=dQw4w9WgXcQ") mock_thumb = MagicMock() mock_thumb.get_attribute = AsyncMock(return_value="http://thumb.png") mock_video.query_selector = AsyncMock(side_effect=[mock_title, mock_thumb]) mock_videos = [mock_video] mock_page.query_selector_all = AsyncMock(return_value=mock_videos) mock_page.close = AsyncMock() mock_page.goto = AsyncMock() mock_page.wait_for_timeout = AsyncMock() mock_browser = MagicMock() mock_browser.new_page = AsyncMock(return_value=mock_page) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=mock_browser)): result = await find_live_video("UC_test_channel", "@testchannel") assert result[0] == "dQw4w9WgXcQ" assert result[1] == "http://thumb.png" class TestGetChannelInfo: @pytest.mark.asyncio async def test_returns_none_when_no_title(self) -> None: mock_page = MagicMock() mock_page.goto = AsyncMock() mock_page.wait_for_timeout = AsyncMock() mock_page.close = AsyncMock() mock_page.query_selector = AsyncMock(return_value=None) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=MagicMock(new_page=AsyncMock(return_value=mock_page)))): result = await get_channel_info("UC_test_channel", "@testchannel") assert result is None @pytest.mark.asyncio async def test_returns_none_on_error(self) -> None: mock_page = MagicMock() mock_page.goto = AsyncMock(side_effect=Exception("Timeout")) with patch("src.modules.discovery._get_browser", new=AsyncMock(return_value=MagicMock(new_page=AsyncMock(return_value=mock_page)))): result = await get_channel_info("UC_test_channel", "@testchannel") assert result is None