115 lines
4.6 KiB
Python
115 lines
4.6 KiB
Python
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 |