mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-09-24 21:00:31 +01:00
Fix torrent post-import category follow-ups and clear the lint backlog (#1154)
rTorrent set_category and remove now uppercase the info hash, which reaches us lowercase while rTorrent's XML-RPC lookups are case sensitive. remove() had this bug before #1148, making PROWLARR_TORRENT_ACTION=remove a silent no-op for rTorrent. Transmission set_category appends the post-import label instead of replacing the whole label list. The unsupported-client path in post_process_cleanup logs at debug instead of warning, so Real-Debrid and AllDebrid users stop seeing a warning on every successful import. The Real-Debrid and AllDebrid clients now follow the conventions used by the other clients (_raise_runtime_error helpers, narrow error tuples, ClassVar, Path.open), and register_client is generic over a TypeVar bound to DownloadClient so decorated classes keep their concrete type. make fix and the lint, format and typecheck targets all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
10554444a9
commit
21f2b6b95c
@@ -33,8 +33,9 @@ def test_set_category_updates_custom1_label():
|
||||
client = RTorrentClient.__new__(RTorrentClient)
|
||||
client._rpc = MagicMock()
|
||||
|
||||
# rTorrent lookups are case sensitive and info hashes reach us lowercase.
|
||||
assert client.set_category("abc123", "imported") is True
|
||||
client._rpc.d.custom1.set.assert_called_once_with("abc123", "imported")
|
||||
client._rpc.d.custom1.set.assert_called_once_with("ABC123", "imported")
|
||||
|
||||
|
||||
class TestRTorrentClientIsConfigured:
|
||||
@@ -779,8 +780,9 @@ class TestRTorrentClientRemove:
|
||||
result = client.remove("abc123def456", delete_files=False)
|
||||
|
||||
assert result is True
|
||||
mock_rpc.d.stop.assert_called_once_with("abc123def456")
|
||||
mock_rpc.d.erase.assert_called_once_with("abc123def456")
|
||||
# rTorrent lookups are case sensitive and info hashes reach us lowercase.
|
||||
mock_rpc.d.stop.assert_called_once_with("ABC123DEF456")
|
||||
mock_rpc.d.erase.assert_called_once_with("ABC123DEF456")
|
||||
|
||||
def test_remove_with_files(self, monkeypatch):
|
||||
"""Test torrent removal with file deletion."""
|
||||
@@ -813,8 +815,8 @@ class TestRTorrentClientRemove:
|
||||
result = client.remove("abc123def456", delete_files=True)
|
||||
|
||||
assert result is True
|
||||
mock_rpc.d.delete_tied.assert_called_once_with("abc123def456")
|
||||
mock_rpc.d.erase.assert_called_once_with("abc123def456")
|
||||
mock_rpc.d.delete_tied.assert_called_once_with("ABC123DEF456")
|
||||
mock_rpc.d.erase.assert_called_once_with("ABC123DEF456")
|
||||
|
||||
def test_remove_failure(self, monkeypatch):
|
||||
"""Test failed torrent removal."""
|
||||
|
||||
@@ -776,6 +776,8 @@ class TestMamLanguageCoverage:
|
||||
}
|
||||
for tag, expected in cases.items():
|
||||
assert _extract_mam_language(f"Book [{tag} / M4B]") == expected, tag
|
||||
|
||||
|
||||
class _MultiIndexerClient:
|
||||
"""Torznab client where each indexer entry returns its own result set.
|
||||
|
||||
|
||||
@@ -68,11 +68,27 @@ def create_mock_transmission_rpc_module():
|
||||
return mock_module
|
||||
|
||||
|
||||
def test_set_category_replaces_labels():
|
||||
def _transmission_client_with_labels(labels):
|
||||
from shelfmark.download.clients.transmission import TransmissionClient
|
||||
|
||||
client = TransmissionClient.__new__(TransmissionClient)
|
||||
client._client = MagicMock()
|
||||
client._client.get_torrent.return_value = types.SimpleNamespace(labels=labels)
|
||||
return client
|
||||
|
||||
|
||||
def test_set_category_appends_to_existing_labels():
|
||||
client = _transmission_client_with_labels(["books", "seeding"])
|
||||
|
||||
assert client.set_category("abc123", "imported") is True
|
||||
client._client.change_torrent.assert_called_once_with(
|
||||
ids="abc123",
|
||||
labels=["books", "seeding", "imported"],
|
||||
)
|
||||
|
||||
|
||||
def test_set_category_adds_label_when_torrent_has_none():
|
||||
client = _transmission_client_with_labels([])
|
||||
|
||||
assert client.set_category("abc123", "imported") is True
|
||||
client._client.change_torrent.assert_called_once_with(
|
||||
@@ -81,6 +97,21 @@ def test_set_category_replaces_labels():
|
||||
)
|
||||
|
||||
|
||||
def test_set_category_is_a_noop_when_label_already_present():
|
||||
client = _transmission_client_with_labels(["books", "imported"])
|
||||
|
||||
assert client.set_category("abc123", "imported") is True
|
||||
client._client.change_torrent.assert_not_called()
|
||||
|
||||
|
||||
def test_set_category_does_not_clobber_labels_when_lookup_fails():
|
||||
client = _transmission_client_with_labels([])
|
||||
client._client.get_torrent.side_effect = ValueError("boom")
|
||||
|
||||
assert client.set_category("abc123", "imported") is False
|
||||
client._client.change_torrent.assert_not_called()
|
||||
|
||||
|
||||
class TestTransmissionClientIsConfigured:
|
||||
"""Tests for TransmissionClient.is_configured()."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user