"""Tests for Jellyfin client.""" from unittest.mock import Mock, patch import pytest import requests from tvh2jellyfin.jellyfin import JellyfinClient, JellyfinConfig class TestJellyfinConfig: """Tests for JellyfinConfig dataclass.""" def test_config_defaults(self): """Test default values.""" config = JellyfinConfig( url="http://localhost:8096", api_key="test_key", ) assert config.library_id is None assert config.enabled is True def test_config_with_library_id(self): """Test config with specific library ID.""" config = JellyfinConfig( url="http://localhost:8096", api_key="test_key", library_id="abc123", ) assert config.library_id == "abc123" class TestJellyfinClient: """Tests for Jellyfin API client.""" @pytest.fixture def config(self): return JellyfinConfig( url="http://localhost:8096", api_key="test_api_key", ) @pytest.fixture def config_with_library(self): return JellyfinConfig( url="http://localhost:8096", api_key="test_api_key", library_id="lib123", ) @pytest.fixture def client(self, config): return JellyfinClient(config) @pytest.fixture def client_with_library(self, config_with_library): return JellyfinClient(config_with_library) def test_url_normalization(self): """Test that trailing slashes are removed from URL.""" config = JellyfinConfig( url="http://localhost:8096/", api_key="test_key", ) client = JellyfinClient(config) assert client.base_url == "http://localhost:8096" def test_headers_set(self, client): """Test that auth headers are set correctly.""" assert client.session.headers["X-MediaBrowser-Token"] == "test_api_key" assert client.session.headers["Content-Type"] == "application/json" @patch("requests.Session.get") def test_test_connection_success(self, mock_get, client): """Test successful connection test.""" mock_get.return_value.json.return_value = { "ServerName": "Test Server", "Version": "10.8.0", } mock_get.return_value.raise_for_status = Mock() result = client.test_connection() assert result is True mock_get.assert_called_once() assert "/System/Info" in mock_get.call_args[0][0] @patch("requests.Session.get") def test_test_connection_failure(self, mock_get, client): """Test connection test failure.""" mock_get.side_effect = requests.exceptions.ConnectionError("Connection refused") result = client.test_connection() assert result is False @patch("requests.Session.post") def test_trigger_library_scan_full(self, mock_post, client): """Test triggering full library scan.""" mock_post.return_value.raise_for_status = Mock() result = client.trigger_library_scan() assert result is True mock_post.assert_called_once() assert "/Library/Refresh" in mock_post.call_args[0][0] @patch("requests.Session.post") def test_trigger_library_scan_specific_library(self, mock_post, client_with_library): """Test triggering scan for specific library.""" mock_post.return_value.raise_for_status = Mock() result = client_with_library.trigger_library_scan() assert result is True mock_post.assert_called_once() assert "/Items/lib123/Refresh" in mock_post.call_args[0][0] @patch("requests.Session.post") def test_trigger_library_scan_failure(self, mock_post, client): """Test library scan trigger failure.""" mock_post.side_effect = requests.exceptions.RequestException("API error") result = client.trigger_library_scan() assert result is False @patch("requests.Session.get") def test_get_libraries_success(self, mock_get, client): """Test getting list of libraries.""" mock_get.return_value.json.return_value = [ {"Name": "TV Shows", "ItemId": "tv123"}, {"Name": "Movies", "ItemId": "mov456"}, ] mock_get.return_value.raise_for_status = Mock() result = client.get_libraries() assert len(result) == 2 assert result[0] == {"name": "TV Shows", "id": "tv123"} assert result[1] == {"name": "Movies", "id": "mov456"} @patch("requests.Session.get") def test_get_libraries_failure(self, mock_get, client): """Test getting libraries when API fails.""" mock_get.side_effect = requests.exceptions.RequestException("API error") result = client.get_libraries() assert result == []