mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-09-24 22:05:20 +01:00
This adds in rtorrent for https://github.com/calibrain/shelfmark/issues/420 The one weird thing I noticed is that the download path needs to be the same for both (that's not how I typically set it up) But it definitely adds to rtorrent and gives progress. **rTorrent client integration:** * Added a new `RTorrentClient` class in `shelfmark/release_sources/prowlarr/clients/rtorrent.py` that implements the download client interface for rTorrent using XML-RPC, supporting adding, removing, and querying torrent status. * Registered the rTorrent client in the client registry in `shelfmark/release_sources/prowlarr/clients/__init__.py`. **Settings and configuration:** * Extended the Prowlarr client settings UI and backend (`shelfmark/release_sources/prowlarr/settings.py`) to add rTorrent as a selectable client, provide rTorrent-specific configuration fields (URL, username, password, label, download directory), and implement a connection test action. [[1]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R390) [[2]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R539-R582) [[3]](diffhunk://#diff-052272b85804cb61162870f262cc7544ef321596ff3ebf08117a6c25afaa3ec5R198-R225) **Test environment and scripts:** * Updated `docker-compose.test-clients.yml` to add an rTorrent service for local testing, including configuration, ports, and documentation updates. [[1]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R17-L19) [[2]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R39) [[3]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R66) [[4]](diffhunk://#diff-a9fe4200dec6a29947e21c338305d04c8b64a7bddd9b0e519f4ab5382c478ba6R164-R181) * Enhanced `scripts/test_clients.py` to include rTorrent in the test suite, with logic for connecting, adding, and removing torrents via XML-RPC. [[1]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR26) [[2]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR57) [[3]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR88-R90) [[4]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR395-R468) [[5]](diffhunk://#diff-c7146552cddc9665e380aec1473363fd8592535ab85f06443478464da8f5a99eR492) Closes https://github.com/calibrain/shelfmark/issues/420
Test Suite
This directory contains the test suite for Shelfmark. Tests are organized by scope and component.
Quick Start
# Run all unit tests (fast, no external dependencies)
docker exec test-cwabd python3 -m pytest tests/ -v -m "not integration and not e2e"
# Run E2E API tests
docker exec test-cwabd python3 -m pytest tests/e2e/ -v -m e2e
# Run everything except integration tests
docker exec test-cwabd python3 -m pytest tests/ -v -m "not integration"
Test Structure
tests/
├── e2e/ # End-to-end API tests
│ ├── conftest.py # Fixtures (APIClient, DownloadTracker)
│ ├── test_api.py # Core API endpoint tests
│ ├── test_download_flow.py # Full download journey tests
│ └── test_prowlarr_flow.py # Prowlarr-specific tests
│
├── prowlarr/ # Prowlarr plugin tests
│ ├── conftest.py # Shared fixtures
│ ├── test_clients.py # DownloadClient base, registry, DownloadStatus
│ ├── test_qbittorrent_client.py # qBittorrent client unit tests
│ ├── test_transmission_client.py # Transmission client unit tests
│ ├── test_nzbget_client.py # NZBGet client unit tests
│ ├── test_sabnzbd_client.py # SABnzbd client unit tests
│ ├── test_handler.py # ProwlarrHandler unit tests
│ ├── test_torrent_utils.py # Bencode, hash extraction, URL parsing
│ ├── test_bencode.py # Bencode encoding/decoding
│ ├── test_source.py # Release source (size parsing, format detection)
│ ├── test_cache.py # Release cache
│ ├── test_integration_clients.py # Integration tests (require Docker stack)
│ └── test_integration_handler.py # Handler integration tests
│
└── README.md # This file
Test Types
Unit Tests
Fast tests that mock external dependencies. Run these frequently during development.
docker exec test-cwabd python3 -m pytest tests/prowlarr/ -v -m "not integration"
What they test:
- Download client logic (status mapping, URL handling, error cases)
- Bencode encoding/decoding for torrent files
- Hash extraction from magnet links and .torrent files
- Protocol detection (torrent vs usenet)
- Release cache operations
- Handler download flow logic
E2E Tests
Test the full application through its HTTP API. Require the app to be running.
docker exec test-cwabd python3 -m pytest tests/e2e/ -v -m e2e
What they test:
- Health check endpoint
- Configuration endpoint
- Metadata provider search (Hardcover, etc.)
- Release source listing
- Download queue operations (add, cancel, reorder, clear)
- Settings API
- Prowlarr integration
Integration Tests
Test against real services (qBittorrent, Transmission, etc.). Require the full Docker test stack.
# Start the test stack first
docker compose -f docker-compose.test-clients.yml up -d
# Run integration tests
docker exec test-cwabd python3 -m pytest tests/prowlarr/ -v -m integration
What they test:
- Real connections to download clients
- Adding/removing actual torrents
- Status polling from real clients
Test Markers
| Marker | Description | When to Skip |
|---|---|---|
integration |
Requires running services (qBittorrent, etc.) | Default skip with -m "not integration" |
e2e |
End-to-end API tests | When app isn't running |
slow |
Tests that take longer (network calls, polling) | Quick feedback with -m "not slow" |
Common Commands
# Run specific test file
docker exec test-cwabd python3 -m pytest tests/prowlarr/test_clients.py -v
# Run specific test class
docker exec test-cwabd python3 -m pytest tests/e2e/test_api.py::TestHealthEndpoint -v
# Run specific test
docker exec test-cwabd python3 -m pytest tests/e2e/test_api.py::TestHealthEndpoint::test_health_returns_ok -v
# Run with short traceback (cleaner output)
docker exec test-cwabd python3 -m pytest tests/ -v --tb=short -m "not integration"
# Run and stop on first failure
docker exec test-cwabd python3 -m pytest tests/ -v -x -m "not integration"
# Run with coverage (if pytest-cov installed)
docker exec test-cwabd python3 -m pytest tests/ --cov=shelfmark -m "not integration"
Writing New Tests
Unit Test Example
from unittest.mock import MagicMock, patch
class TestMyFeature:
def test_something(self, monkeypatch):
# Mock config values
monkeypatch.setattr(
"shelfmark.module.config.get",
lambda key, default="": {"KEY": "value"}.get(key, default),
)
# Test your code
result = my_function()
assert result == expected
E2E Test Example
import pytest
from .conftest import APIClient, DownloadTracker
@pytest.mark.e2e
class TestMyEndpoint:
def test_endpoint_works(self, api_client: APIClient):
resp = api_client.get("/api/my-endpoint")
assert resp.status_code == 200
def test_with_cleanup(self, api_client: APIClient, download_tracker: DownloadTracker):
# Track IDs for automatic cleanup after test
download_tracker.track("some-id")
# ... test code ...
Test Fixtures
E2E Fixtures (tests/e2e/conftest.py)
| Fixture | Scope | Description |
|---|---|---|
api_client |
session | HTTP client for API calls |
download_tracker |
function | Tracks downloads for cleanup |
server_config |
session | Cached server configuration |
Prowlarr Fixtures (tests/prowlarr/conftest.py)
| Fixture | Scope | Description |
|---|---|---|
transmission_client |
module | Real Transmission client (integration) |
qbittorrent_client |
module | Real qBittorrent client (integration) |
deluge_client |
module | Real Deluge client (integration) |
nzbget_client |
module | Real NZBGet client (integration) |
sabnzbd_client |
module | Real SABnzbd client (integration) |
Expected Skips
Some tests skip when external services aren't available. This is normal:
- "No metadata providers available" - Metadata provider not responding
- "Prowlarr not configured" - Prowlarr settings not set up
- "No releases found" - No indexers configured in Prowlarr
- "Legacy search source unavailable" - Direct download source offline
- "Transmission/qBittorrent not available" - Docker test stack not running
Troubleshooting
Tests can't connect to app
# Check the app is running
docker ps | grep test-cwabd
# Check app logs
docker logs test-cwabd
Import errors
# Make sure you're running inside the container
docker exec test-cwabd python3 -m pytest ...
# Not from your local machine
pytest ... # This won't work
Integration tests failing
# Make sure test stack is running
docker compose -f docker-compose.test-clients.yml up -d
# Check client containers
docker ps | grep -E "qbittorrent|transmission|deluge|nzbget|sabnzbd"
Stale test data
# Clear the queue between test runs
docker exec test-cwabd python3 -c "
from shelfmark.core.queue import book_queue
book_queue.clear()
"