Initial commit: TVH2Jellyfin application
A Docker-based Python application that transfers completed recordings from TVHeadend to Jellyfin media storage via SCP. Features: - Monitors TVHeadend for completed recordings via JSON API - Transfers files via SCP with SSH key authentication - Organizes files by show name - Deletes recordings from TVHeadend after successful transfer - Tracks transferred files to avoid duplicates - Dry run mode for testing without making changes
This commit is contained in:
121
tests/test_tvmaze.py
Normal file
121
tests/test_tvmaze.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""Tests for TVmaze client."""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from tvh2jellyfin.tvmaze import TVMazeClient, TVMazeConfig
|
||||
|
||||
|
||||
class TestTVMazeClient:
|
||||
"""Tests for TVmaze API client."""
|
||||
|
||||
@pytest.fixture
|
||||
def config(self):
|
||||
return TVMazeConfig(cache_ttl=3600, enabled=True)
|
||||
|
||||
@pytest.fixture
|
||||
def client(self, config):
|
||||
return TVMazeClient(config)
|
||||
|
||||
@patch("requests.Session.get")
|
||||
def test_search_series_success(self, mock_get, client):
|
||||
"""Test successful series search."""
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = {
|
||||
"id": 789,
|
||||
"name": "Coronation Street",
|
||||
}
|
||||
mock_get.return_value.raise_for_status = Mock()
|
||||
|
||||
result = client.search_series("Coronation Street")
|
||||
|
||||
assert result is not None
|
||||
assert result[0] == 789
|
||||
assert result[1] == "Coronation Street"
|
||||
|
||||
@patch("requests.Session.get")
|
||||
def test_search_series_not_found(self, mock_get, client):
|
||||
"""Test series search with 404 response."""
|
||||
mock_get.return_value.status_code = 404
|
||||
|
||||
result = client.search_series("Nonexistent Show")
|
||||
|
||||
assert result is None
|
||||
|
||||
@patch("requests.Session.get")
|
||||
def test_get_episode_by_date_success(self, mock_get, client):
|
||||
"""Test successful episode lookup by date."""
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.return_value = [
|
||||
{"season": 67, "number": 4, "name": "Episode 4"}
|
||||
]
|
||||
mock_get.return_value.raise_for_status = Mock()
|
||||
|
||||
result = client.get_episode_by_date(789, "2026-01-06", "Coronation Street")
|
||||
|
||||
assert result is not None
|
||||
assert result.season == 67
|
||||
assert result.episode == 4
|
||||
assert result.series_name == "Coronation Street"
|
||||
|
||||
@patch("requests.Session.get")
|
||||
def test_get_episode_by_date_not_found(self, mock_get, client):
|
||||
"""Test episode lookup with no results."""
|
||||
mock_get.return_value.status_code = 404
|
||||
|
||||
result = client.get_episode_by_date(789, "2026-01-01", "Coronation Street")
|
||||
|
||||
assert result is None
|
||||
|
||||
@patch("requests.Session.get")
|
||||
def test_lookup_episode_full_flow(self, mock_get, client):
|
||||
"""Test full episode lookup flow."""
|
||||
# Set up responses for search and episode lookup
|
||||
mock_get.return_value.status_code = 200
|
||||
mock_get.return_value.json.side_effect = [
|
||||
{"id": 789, "name": "Coronation Street"}, # Search response
|
||||
[{"season": 67, "number": 4, "name": "Episode 4"}], # Episode response
|
||||
]
|
||||
mock_get.return_value.raise_for_status = Mock()
|
||||
|
||||
# Timestamp for 2026-01-06
|
||||
result = client.lookup_episode("Coronation Street", 1767744000)
|
||||
|
||||
assert result is not None
|
||||
assert result.series_name == "Coronation Street"
|
||||
assert result.formatted_episode == "S67E04"
|
||||
|
||||
def test_caching_series(self, client):
|
||||
"""Test that series cache prevents duplicate calls."""
|
||||
import time
|
||||
|
||||
# Manually populate cache
|
||||
client._series_cache["coronation street"] = (789, "Coronation Street", time.time())
|
||||
|
||||
# Should use cache
|
||||
result = client.search_series("coronation street")
|
||||
|
||||
assert result == (789, "Coronation Street")
|
||||
|
||||
def test_caching_episodes(self, client):
|
||||
"""Test that episode cache prevents duplicate calls."""
|
||||
import time
|
||||
|
||||
from tvh2jellyfin.tvdb import EpisodeInfo
|
||||
|
||||
cached_episode = EpisodeInfo(
|
||||
series_id=789,
|
||||
series_name="Coronation Street",
|
||||
season=67,
|
||||
episode=4,
|
||||
episode_name="Episode 4",
|
||||
air_date="2026-01-06",
|
||||
)
|
||||
client._episode_cache["789:2026-01-06"] = (cached_episode, time.time())
|
||||
|
||||
# Should use cache
|
||||
result = client.get_episode_by_date(789, "2026-01-06", "Coronation Street")
|
||||
|
||||
assert result is not None
|
||||
assert result.season == 67
|
||||
Reference in New Issue
Block a user