soulsync/tests/test_video_download_config.py
BoulderBadgeDad 4d45cc614f video downloads (phase 3): source mode + hybrid chain (soulseek/torrent/usenet only)
Video-specific Download Source section: a mode dropdown limited to Soulseek / Torrent /
Usenet / Hybrid (no streaming sources — those are music-only). In hybrid mode, a chain
builder lists the three sources with arrow-reorder + enable toggles (best-first), and
NO album-level/track-level badges (a music-only concept, per spec).

- core/video/download_config.py: pure normalize for download_mode + hybrid_order
  (validates to the 3 sources, dedupes, never empties); stored in video_settings.
- /api/video/downloads/config GET/POST now carries download_mode + hybrid_order
  alongside the folders.
- video-settings.js: dropdown + hybrid rows render/reorder/toggle, show the hybrid
  container only in hybrid mode, save on change. Reuses the .vq-row styling.

7 tests (6 pure + 1 API). Next: the shared slskd connection block (reads/writes the
music config_manager so both sides share one slskd) + confirming the shared Indexers tab.
2026-06-19 00:15:13 -07:00

68 lines
2.3 KiB
Python

"""Video download source-config — pure normalize for mode + hybrid chain
(soulseek/torrent/usenet only), isolated from music."""
from __future__ import annotations
import json
from core.video.download_config import (
MODES,
SOURCES,
load,
normalize_hybrid_order,
normalize_mode,
save,
)
def test_modes_are_video_only():
assert SOURCES == ("soulseek", "torrent", "usenet")
assert MODES == ("soulseek", "torrent", "usenet", "hybrid")
def test_normalize_mode():
assert normalize_mode("torrent") == "torrent"
assert normalize_mode("HYBRID") == "hybrid"
assert normalize_mode("spotify") == "soulseek" # music sources rejected
assert normalize_mode(None) == "soulseek"
assert normalize_mode("") == "soulseek"
def test_normalize_hybrid_order_filters_dedupes_defaults():
assert normalize_hybrid_order(["torrent", "usenet"]) == ["torrent", "usenet"]
assert normalize_hybrid_order(["torrent", "torrent", "spotify"]) == ["torrent"]
assert normalize_hybrid_order([]) == ["soulseek"] # never empty
assert normalize_hybrid_order("garbage") == ["soulseek"]
# Accepts a JSON string (as stored in the KV table).
assert normalize_hybrid_order(json.dumps(["usenet", "soulseek"])) == ["usenet", "soulseek"]
class _FakeDB:
def __init__(self):
self._kv = {}
def get_setting(self, key, default=None):
return self._kv.get(key, default)
def set_setting(self, key, value):
self._kv[key] = value
def test_load_defaults():
assert load(_FakeDB()) == {"download_mode": "soulseek", "hybrid_order": ["soulseek"]}
def test_save_validates_and_roundtrips():
db = _FakeDB()
out = save(db, {"download_mode": "hybrid", "hybrid_order": ["torrent", "bogus", "torrent", "usenet"]})
assert out == {"download_mode": "hybrid", "hybrid_order": ["torrent", "usenet"]}
assert load(db) == out # persisted + reloads identically
def test_save_ignores_absent_keys():
db = _FakeDB()
save(db, {"download_mode": "usenet"})
assert load(db)["download_mode"] == "usenet"
save(db, {"hybrid_order": ["soulseek", "torrent"]}) # mode key absent → unchanged
assert load(db)["download_mode"] == "usenet"
assert load(db)["hybrid_order"] == ["soulseek", "torrent"]