Fix: Use info hash for clients (#495)

Passes prowlarr's info hash to download client, existing behavior as
fallback
This commit is contained in:
Alex
2026-01-19 20:23:45 +00:00
committed by GitHub
parent 8470095534
commit a030bca5d3
13 changed files with 227 additions and 25 deletions
+7 -7
View File
@@ -151,7 +151,7 @@ class TestDownloadStatus:
file_path=None,
)
with pytest.raises(AttributeError):
status.progress = 75.0
setattr(status, "progress", 75.0)
def test_download_status_state_value_with_unknown_string(self):
"""Test state_value with an unknown state string."""
@@ -212,7 +212,7 @@ class TestClientRegistry:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
@@ -245,7 +245,7 @@ class TestClientRegistry:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
@@ -269,7 +269,7 @@ class TestClientRegistry:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
@@ -301,7 +301,7 @@ class TestClientRegistry:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
@@ -325,7 +325,7 @@ class TestClientRegistry:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
@@ -377,7 +377,7 @@ class TestDownloadClientInterface:
def test_connection(self):
return True, "OK"
def add_download(self, url, name, category="test"):
def add_download(self, url, name, category=None, expected_hash=None, **kwargs):
return "id"
def get_status(self, download_id):
+8 -1
View File
@@ -82,7 +82,14 @@ class MockClient(DownloadClient):
def test_connection(self) -> Tuple[bool, str]:
return True, "Mock client connected"
def add_download(self, url: str, name: str, category: str = "cwabd") -> str:
def add_download(
self,
url: str,
name: str,
category: Optional[str] = None,
expected_hash: Optional[str] = None,
**kwargs,
) -> str:
if self.add_download_error:
raise self.add_download_error
download_id = f"mock-{len(self.downloads)}"
+3 -2
View File
@@ -395,8 +395,9 @@ class TestQBittorrentIntegration:
assert 0 <= status.progress <= 100
valid_states = {"downloading", "complete", "error", "seeding", "paused", "queued", "fetching_metadata", "stalled"}
assert status.state.value in valid_states
valid_states = {"downloading", "complete", "error", "seeding", "paused", "queued", "fetching_metadata", "stalled", "checking"}
state_value = status.state.value if hasattr(status.state, "value") else status.state
assert state_value in valid_states
assert isinstance(status.complete, bool)
finally:
+51
View File
@@ -10,6 +10,7 @@ from unittest.mock import MagicMock, patch
import pytest
from shelfmark.release_sources.prowlarr.clients import DownloadStatus
from shelfmark.release_sources.prowlarr.clients.torrent_utils import TorrentInfo
class MockTorrent:
@@ -465,6 +466,56 @@ class TestQBittorrentClientAddDownload:
assert result == "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0"
assert mock_client_instance._session.get.call_count >= 1
def test_add_download_uses_expected_hash_without_fetch(self, monkeypatch):
"""Skip proxy fetch when expected hash is provided for URL torrents."""
config_values = {
"QBITTORRENT_URL": "http://localhost:8080",
"QBITTORRENT_USERNAME": "admin",
"QBITTORRENT_PASSWORD": "password",
"QBITTORRENT_CATEGORY": "test",
}
monkeypatch.setattr(
"shelfmark.release_sources.prowlarr.clients.qbittorrent.config.get",
lambda key, default="": config_values.get(key, default),
)
expected_hash = "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0"
mock_torrent = MockTorrent(hash_val=expected_hash)
mock_client_instance = MagicMock()
mock_client_instance.torrents_add.return_value = "Ok."
mock_client_instance.torrents_info.return_value = [mock_torrent]
mock_client_instance._session.get.return_value = create_mock_session_response({}, status_code=200)
mock_client_class = MagicMock(return_value=mock_client_instance)
with patch.dict('sys.modules', {'qbittorrentapi': MagicMock(Client=mock_client_class)}):
import importlib
import shelfmark.release_sources.prowlarr.clients.qbittorrent as qb_module
importlib.reload(qb_module)
with patch(
"shelfmark.release_sources.prowlarr.clients.qbittorrent.extract_torrent_info",
autospec=True,
) as mock_extract:
mock_extract.return_value = TorrentInfo(
info_hash=expected_hash,
torrent_data=None,
is_magnet=False,
magnet_url=None,
)
client = qb_module.QBittorrentClient()
result = client.add_download(
"http://example.com/test.torrent",
"Test Download",
expected_hash=expected_hash,
)
assert result == expected_hash
mock_extract.assert_called_once_with(
"http://example.com/test.torrent",
expected_hash=expected_hash,
)
def test_add_download_creates_category(self, monkeypatch):
"""Test that add_download creates category if needed."""
config_values = {