soulsync/tests/test_video_search_pipeline.py
BoulderBadgeDad 44b074772b video search: evaluate/rank pipeline + mock indexer + /downloads/search
Phase 2 of live search (indexer mocked, pipeline real):
- quality_eval.evaluate_release(parsed, profile, scope, want_season/episode, size_gb)
  → {accepted, score, rejected, tier, quality_label}. Sonarr-style: rejects junk
  sources/codecs/3D, requires an ENABLED ladder tier, honours HDR-require + size caps,
  and VALIDATES scope (episode wants SxxExx, season wants the whole-season PACK, show
  wants a complete-series pack, with season/episode-number checks). Scores keepers by
  resolution/source/codec-pref/HDR/audio/repack for ranking.
- mock_search.py: deterministic stand-in indexer returning scope-shaped raw hits
  (the single swap-point for real slskd/Prowlarr).
- POST /downloads/search: mock → parse → evaluate → rank (accepted, score, seeders).

16 tests, isolation guard + ruff clean. UI wiring next.
2026-06-19 13:39:09 -07:00

69 lines
3.1 KiB
Python

"""Search pipeline — evaluate_release (accept/reject/score vs profile + scope) and
the mock indexer. Isolated from music."""
from __future__ import annotations
from core.video.mock_search import mock_search
from core.video.quality_eval import evaluate_release, tier_key
from core.video.quality_profile import default_profile
from core.video.release_parse import parse_release
def test_tier_key_mapping():
assert tier_key("web-dl", "1080p") == "web-1080p"
assert tier_key("remux", "2160p") == "remux-2160p"
assert tier_key("dvd", None) == "dvd"
assert tier_key("cam", "1080p") == "" # junk has no ladder tier
def test_evaluate_accepts_an_enabled_tier():
p = default_profile() # bluray-1080p etc. enabled, cutoff 1080p
v = evaluate_release(parse_release("Movie 2020 1080p BluRay x265-GRP"), p, scope="movie")
assert v["accepted"] is True and v["score"] > 0
assert "1080p" in v["quality_label"]
def test_evaluate_rejects_cam_and_disabled_tier():
p = default_profile()
cam = evaluate_release(parse_release("Movie 2020 HDCAM x264-CRUDE"), p, scope="movie")
assert cam["accepted"] is False and "reject list" in cam["rejected"]
# 2160p tiers are OFF by default → a 4K hit is filtered out (not enabled)
uhd = evaluate_release(parse_release("Movie 2020 2160p WEB-DL HEVC"), p, scope="movie")
assert uhd["accepted"] is False and "enabled tiers" in uhd["rejected"]
def test_evaluate_scope_validation():
p = default_profile()
# an episode hit fails a SEASON search (not a full-season pack)
ep = parse_release("Show S02E03 1080p WEB-DL x265-GRP")
assert evaluate_release(ep, p, scope="season", want_season=2)["rejected"] == "Not a full-season pack"
# the season PACK passes the season search
pack = parse_release("Show S02 1080p WEB-DL x265-GRP")
assert evaluate_release(pack, p, scope="season", want_season=2)["accepted"] is True
# wrong season is rejected
assert evaluate_release(pack, p, scope="season", want_season=5)["rejected"] == "Wrong season"
def test_evaluate_size_cap_movie_only():
p = default_profile(); p["max_movie_gb"] = 10
big = evaluate_release(parse_release("Movie 2020 1080p BluRay x265-GRP"), p, scope="movie", size_gb=14)
assert big["accepted"] is False and "size cap" in big["rejected"]
ok = evaluate_release(parse_release("Movie 2020 1080p BluRay x265-GRP"), p, scope="movie", size_gb=8)
assert ok["accepted"] is True
def test_mock_search_scopes_are_shaped_right():
movie = mock_search("movie", "The Matrix", year=1999)
assert movie and all("size_bytes" in h and "seeders" in h for h in movie)
assert "1999" in movie[0]["title"]
season = mock_search("season", "The Wire", season=2)
assert all(".S02" in h["title"] for h in season)
series = mock_search("series", "The Wire", season_end=5)
assert all("S01-S05" in h["title"] for h in series)
assert mock_search("bogus", "x") == []
def test_mock_search_is_deterministic():
a = mock_search("episode", "Severance", season=1, episode=4)
b = mock_search("episode", "Severance", season=1, episode=4)
assert a == b # no RNG → stable across calls/reloads