update
This commit is contained in:
300
tests/test_mock_download.py
Normal file
300
tests/test_mock_download.py
Normal file
@@ -0,0 +1,300 @@
|
||||
"""Tests for downloading subtitles with mocked API responses."""
|
||||
|
||||
import os
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
|
||||
from jimaku_dl.downloader import JimakuDownloader
|
||||
|
||||
|
||||
class TestMockDownload:
|
||||
"""Test downloading subtitles with mocked API responses."""
|
||||
|
||||
@responses.activate
|
||||
def test_download_subtitle_flow(self, temp_dir, monkeypatch):
|
||||
"""Test the full subtitle download flow with mocked responses."""
|
||||
# Set up test environment
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
video_file = os.path.join(temp_dir, "test_video.mkv")
|
||||
with open(video_file, "w") as f:
|
||||
f.write("fake video content")
|
||||
|
||||
# Mock AniList API response with proper structure
|
||||
responses.add(
|
||||
responses.POST,
|
||||
"https://graphql.anilist.co",
|
||||
json={
|
||||
"data": {
|
||||
"Page": {
|
||||
"media": [
|
||||
{
|
||||
"id": 123456,
|
||||
"title": {
|
||||
"english": "Test Anime",
|
||||
"romaji": "Test Anime",
|
||||
"native": "テストアニメ",
|
||||
},
|
||||
"format": "TV",
|
||||
"episodes": 12,
|
||||
"seasonYear": 2023,
|
||||
"season": "WINTER",
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku search API
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/search",
|
||||
json=[
|
||||
{
|
||||
"id": 100,
|
||||
"english_name": "Test Anime",
|
||||
"japanese_name": "テストアニメ",
|
||||
}
|
||||
],
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku files API
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/100/files",
|
||||
json=[
|
||||
{
|
||||
"id": 200,
|
||||
"name": "test.srt",
|
||||
"url": "https://jimaku.cc/download/test.srt",
|
||||
}
|
||||
],
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock file download
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/download/test.srt",
|
||||
body="1\n00:00:01,000 --> 00:00:05,000\nTest subtitle",
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock the interactive menu selections
|
||||
downloader = JimakuDownloader(api_token="test_token")
|
||||
with patch.object(downloader, "fzf_menu") as mock_fzf:
|
||||
mock_fzf.side_effect = [
|
||||
"1. Test Anime - テストアニメ", # Select entry
|
||||
"1. test.srt", # Select file
|
||||
]
|
||||
|
||||
# Mock parse_filename to avoid prompting
|
||||
with patch.object(
|
||||
downloader, "parse_filename", return_value=("Test Anime", 1, 1)
|
||||
):
|
||||
# Execute the download
|
||||
result = downloader.download_subtitles(video_file)
|
||||
|
||||
# Verify the result
|
||||
assert len(result) == 1
|
||||
assert "test.srt" in result[0]
|
||||
|
||||
@responses.activate
|
||||
def test_error_handling(self, temp_dir, monkeypatch):
|
||||
"""Test error handling when AniList API fails."""
|
||||
# Set up test environment
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
video_file = os.path.join(temp_dir, "test_video.mkv")
|
||||
with open(video_file, "w") as f:
|
||||
f.write("fake video content")
|
||||
|
||||
# Mock AniList API with an error response
|
||||
responses.add(
|
||||
responses.POST,
|
||||
"https://graphql.anilist.co",
|
||||
status=404, # Simulate 404 error
|
||||
)
|
||||
|
||||
# Create downloader and attempt to download
|
||||
downloader = JimakuDownloader(api_token="test_token")
|
||||
with patch.object(
|
||||
downloader, "parse_filename", return_value=("Test Anime", 1, 1)
|
||||
):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
downloader.download_subtitles(video_file)
|
||||
|
||||
# Check for the specific error message now
|
||||
assert "Network error querying AniList API" in str(exc_info.value)
|
||||
|
||||
@responses.activate
|
||||
def test_unauthorized_api_error(self, temp_dir, monkeypatch):
|
||||
"""Test error handling when Jimaku API returns unauthorized."""
|
||||
# Set up test environment
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
video_file = os.path.join(temp_dir, "test_video.mkv")
|
||||
with open(video_file, "w") as f:
|
||||
f.write("fake video content")
|
||||
|
||||
# Mock AniList API response with success to get past that check
|
||||
responses.add(
|
||||
responses.POST,
|
||||
"https://graphql.anilist.co",
|
||||
json={
|
||||
"data": {
|
||||
"Page": {
|
||||
"media": [
|
||||
{
|
||||
"id": 123456,
|
||||
"title": {
|
||||
"english": "Test Anime",
|
||||
"romaji": "Test Anime",
|
||||
"native": "テストアニメ",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku search API with 401 unauthorized error
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/search",
|
||||
json={"error": "Unauthorized"},
|
||||
status=401,
|
||||
)
|
||||
|
||||
# Create downloader and attempt to download
|
||||
downloader = JimakuDownloader(api_token="invalid_token")
|
||||
with patch.object(
|
||||
downloader, "parse_filename", return_value=("Test Anime", 1, 1)
|
||||
):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
downloader.download_subtitles(video_file)
|
||||
|
||||
# Now check for the Jimaku API error
|
||||
assert "Error querying Jimaku API" in str(exc_info.value)
|
||||
|
||||
@responses.activate
|
||||
def test_no_subtitle_entries_found(self, temp_dir, monkeypatch):
|
||||
"""Test handling when no subtitle entries are found."""
|
||||
# Set up test environment
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
video_file = os.path.join(temp_dir, "test_video.mkv")
|
||||
with open(video_file, "w") as f:
|
||||
f.write("fake video content")
|
||||
|
||||
# Mock AniList API response with success
|
||||
responses.add(
|
||||
responses.POST,
|
||||
"https://graphql.anilist.co",
|
||||
json={
|
||||
"data": {
|
||||
"Page": {
|
||||
"media": [
|
||||
{
|
||||
"id": 123456,
|
||||
"title": {
|
||||
"english": "Test Anime",
|
||||
"romaji": "Test Anime",
|
||||
"native": "テストアニメ",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku search API with empty response (no entries)
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/search",
|
||||
json=[], # Empty array indicates no entries found
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Create downloader and attempt to download
|
||||
downloader = JimakuDownloader(api_token="test_token")
|
||||
with patch.object(
|
||||
downloader, "parse_filename", return_value=("Test Anime", 1, 1)
|
||||
):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
downloader.download_subtitles(video_file)
|
||||
|
||||
assert "No subtitle entries found" in str(exc_info.value)
|
||||
|
||||
@responses.activate
|
||||
def test_no_subtitle_files_found(self, temp_dir, monkeypatch):
|
||||
"""Test handling when no subtitle files are available for an entry."""
|
||||
# Set up test environment
|
||||
monkeypatch.setenv("TESTING", "1")
|
||||
video_file = os.path.join(temp_dir, "test_video.mkv")
|
||||
with open(video_file, "w") as f:
|
||||
f.write("fake video content")
|
||||
|
||||
# Mock AniList API response with success
|
||||
responses.add(
|
||||
responses.POST,
|
||||
"https://graphql.anilist.co",
|
||||
json={
|
||||
"data": {
|
||||
"Page": {
|
||||
"media": [
|
||||
{
|
||||
"id": 123456,
|
||||
"title": {
|
||||
"english": "Test Anime",
|
||||
"romaji": "Test Anime",
|
||||
"native": "テストアニメ",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku search API with entries
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/search",
|
||||
json=[
|
||||
{
|
||||
"id": 100,
|
||||
"english_name": "Test Anime",
|
||||
"japanese_name": "テストアニメ",
|
||||
}
|
||||
],
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Mock Jimaku files API with empty files
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"https://jimaku.cc/api/entries/100/files",
|
||||
json=[], # Empty array = no files
|
||||
status=200,
|
||||
)
|
||||
|
||||
# Create downloader and attempt to download
|
||||
downloader = JimakuDownloader(api_token="test_token")
|
||||
with patch.object(downloader, "fzf_menu") as mock_fzf:
|
||||
# Mock entry selection
|
||||
mock_fzf.return_value = "1. Test Anime - テストアニメ"
|
||||
|
||||
with patch.object(
|
||||
downloader, "parse_filename", return_value=("Test Anime", 1, 1)
|
||||
):
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
downloader.download_subtitles(video_file)
|
||||
|
||||
assert "No files found" in str(exc_info.value)
|
||||
Reference in New Issue
Block a user