7bc50fd5b8
Captures 5 canonical releases from /mnt/testipool/downloads as parametrized fixtures under tests/fixtures/releases/easy/. Each fixture declares the release name, expected ParsedRelease fields, original tree, and the future routing (library / torrents / seed_hardlinks) for the upcoming organize_media refactor. Today only the 'parsed' section is asserted; tree is materialized into a tmp_path to catch typos. Routing is captured ahead of the planner work — it becomes verifiable once organize_media lands. Cases: back_in_action (movie), slow_horses_single_ep (TV single), foundation_season_pack (S02 + .nfo noise), long_walk_with_noise (movie + KONTRAST.TOP.txt), sinners_yts (YTS bracket-heavy + Subs/ dir). Also tracks CHANGELOG.md under [Unreleased] / Added.
61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
"""Fixture discovery and materialization helpers for release fixtures.
|
|
|
|
Each fixture is a directory under ``tests/fixtures/releases/<bucket>/<case>/``
|
|
containing one ``expected.yaml`` file. See ``releases/README.md`` for the
|
|
schema.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
FIXTURES_ROOT = Path(__file__).parent
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ReleaseFixture:
|
|
"""A loaded fixture, ready to be materialized into a temp dir."""
|
|
|
|
name: str # "<bucket>/<case>", e.g. "easy/back_in_action"
|
|
path: Path # directory containing expected.yaml
|
|
data: dict # parsed YAML contents
|
|
|
|
@property
|
|
def release_name(self) -> str:
|
|
return self.data["release_name"]
|
|
|
|
@property
|
|
def expected_parsed(self) -> dict:
|
|
return self.data.get("parsed", {})
|
|
|
|
@property
|
|
def tree(self) -> list[str]:
|
|
return self.data.get("tree", [])
|
|
|
|
@property
|
|
def routing(self) -> dict:
|
|
return self.data.get("routing", {})
|
|
|
|
def materialize(self, root: Path) -> None:
|
|
"""Create the fixture's ``tree`` as empty files/dirs under ``root``."""
|
|
for entry in self.tree:
|
|
target = root / entry
|
|
if entry.endswith("/"):
|
|
target.mkdir(parents=True, exist_ok=True)
|
|
else:
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.touch()
|
|
|
|
|
|
def discover_fixtures() -> list[ReleaseFixture]:
|
|
"""Find all ``expected.yaml`` files under FIXTURES_ROOT."""
|
|
fixtures = []
|
|
for yaml_path in sorted(FIXTURES_ROOT.glob("*/*/expected.yaml")):
|
|
data = yaml.safe_load(yaml_path.read_text())
|
|
name = f"{yaml_path.parent.parent.name}/{yaml_path.parent.name}"
|
|
fixtures.append(ReleaseFixture(name=name, path=yaml_path.parent, data=data))
|
|
return fixtures
|