soulsync/tests/quality/test_search_mode.py
dev d484046523 feat(downloads): best-quality search mode + clearer fallback UI
Adds an opt-in search strategy toggle in the Quality Profile:

- priority (default): unchanged — first source in the hybrid chain that
  meets a quality target wins.
- best_quality: pool candidates from EVERY source per query and download
  them best→worst by actual audio quality; source order only breaks ties.

Implementation reuses existing plumbing so the retry system is untouched:
- engine.search_all_sources pools raw tracks across all configured,
  non-exhausted sources (no first-source short-circuit).
- candidates.order_candidates: new quality_first sort path — profile
  quality rank dominates, confidence/peer signals break ties. Priority
  path is byte-for-byte unchanged (regression-locked by tests).
- task_worker passes quality_first + targets through; skips the redundant
  hybrid-fallback block in best-quality mode (pool already covered it).
- Per-source retry budgets unchanged: a source that spends its budget is
  added to exhausted_download_sources and thus dropped from the whole
  pool. Independent of post_processing.retry_exhaustive.
- Query generator NOT touched.

Also clarifies the "Allow fallback" setting wording: it accepts OFF-LIST
quality as a last resort (not "walk down my list"), and notes that
lossy_copy.downsample_hires also bypasses the quality gate — the cause of
16-bit/MP3 files slipping through a 24-bit-only profile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 18:46:01 +02:00

35 lines
1.2 KiB
Python

"""core.quality.selection.load_search_mode — reads the download search
strategy from the quality profile.
'priority' → today's behaviour: first satisfying source wins.
'best_quality' → pool all sources, work best→worst by actual quality.
Default and any unknown value resolve to 'priority' so every existing
install keeps its current behaviour.
"""
import core.quality.selection as selection
import database.music_database as music_database
def _patch_profile(monkeypatch, profile):
class _FakeDB:
def get_quality_profile(self):
return profile
monkeypatch.setattr(music_database, "MusicDatabase", _FakeDB)
def test_defaults_to_priority_when_key_absent(monkeypatch):
_patch_profile(monkeypatch, {"version": 3, "ranked_targets": []})
assert selection.load_search_mode() == "priority"
def test_returns_best_quality_when_set(monkeypatch):
_patch_profile(monkeypatch, {"version": 3, "search_mode": "best_quality"})
assert selection.load_search_mode() == "best_quality"
def test_unknown_value_falls_back_to_priority(monkeypatch):
_patch_profile(monkeypatch, {"version": 3, "search_mode": "nonsense"})
assert selection.load_search_mode() == "priority"