159 lines
5.8 KiB
Python
159 lines
5.8 KiB
Python
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
|