Files
alfred/tests/infrastructure/test_rule_repository.py
T

179 lines
6.6 KiB
Python

"""Tests for ``alfred.infrastructure.subtitle.rule_repository.RuleSetRepository``.
Loads/saves the SubtitleRuleSet inheritance chain from ``.alfred/`` YAML.
Coverage:
- ``TestLoad`` — no files → ``global_default``; rules.yaml override applied
on top; release_groups/{NAME}.yaml override applied;
SubtitlePreferences seeds the base when provided; full 3-level chain.
- ``TestFilterOverride`` — unknown keys discarded.
- ``TestSaveLocal`` — atomic write, merges with existing, creates .alfred/.
"""
from __future__ import annotations
from pathlib import Path
import yaml
from alfred.infrastructure.persistence.memory.ltm.components.subtitle_preferences import (
SubtitlePreferences,
)
from alfred.infrastructure.subtitle.rule_repository import (
RuleSetRepository,
_filter_override,
)
def _write(path: Path, data: dict) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(yaml.safe_dump(data), encoding="utf-8")
# --------------------------------------------------------------------------- #
# _filter_override #
# --------------------------------------------------------------------------- #
class TestFilterOverride:
def test_keeps_only_valid_keys(self):
out = _filter_override(
{
"languages": ["fra"],
"formats": ["srt"],
"types": ["standard"],
"format_priority": ["srt"],
"min_confidence": 0.8,
"unknown_key": "ignored",
"another": 42,
}
)
assert set(out) == {
"languages",
"formats",
"types",
"format_priority",
"min_confidence",
}
assert "unknown_key" not in out
def test_empty(self):
assert _filter_override({}) == {}
# --------------------------------------------------------------------------- #
# load #
# --------------------------------------------------------------------------- #
class TestLoad:
def test_no_files_returns_global_default(self, tmp_path):
repo = RuleSetRepository(tmp_path)
rs = repo.load()
# Should resolve cleanly using the hardcoded defaults.
rules = rs.resolve()
assert rules.preferred_languages # non-empty
assert rules.min_confidence > 0
def test_subtitle_preferences_override_base(self, tmp_path):
prefs = SubtitlePreferences(
languages=["jpn"], formats=["ass"], types=["standard"]
)
repo = RuleSetRepository(tmp_path)
rules = repo.load(subtitle_preferences=prefs).resolve()
assert rules.preferred_languages == ["jpn"]
assert rules.preferred_formats == ["ass"]
assert rules.allowed_types == ["standard"]
def test_local_rules_yaml_applied(self, tmp_path):
_write(
tmp_path / ".alfred" / "rules.yaml",
{"override": {"languages": ["spa"], "min_confidence": 0.95}},
)
repo = RuleSetRepository(tmp_path)
rules = repo.load().resolve()
assert rules.preferred_languages == ["spa"]
assert rules.min_confidence == 0.95
def test_release_group_override_applied(self, tmp_path):
_write(
tmp_path / ".alfred" / "release_groups" / "KONTRAST.yaml",
{"override": {"format_priority": ["ass", "srt"]}},
)
repo = RuleSetRepository(tmp_path)
rules = repo.load(release_group="KONTRAST").resolve()
assert rules.format_priority == ["ass", "srt"]
def test_full_three_level_chain(self, tmp_path):
# Base: prefs sets languages=["jpn"]
prefs = SubtitlePreferences(languages=["jpn"])
# Group: overrides format_priority
_write(
tmp_path / ".alfred" / "release_groups" / "GRP.yaml",
{"override": {"format_priority": ["ass"]}},
)
# Local: overrides min_confidence
_write(
tmp_path / ".alfred" / "rules.yaml",
{"override": {"min_confidence": 0.99}},
)
repo = RuleSetRepository(tmp_path)
rules = repo.load(release_group="GRP", subtitle_preferences=prefs).resolve()
# All three levels visible — local overrides on top
assert rules.preferred_languages == ["jpn"]
assert rules.format_priority == ["ass"]
assert rules.min_confidence == 0.99
def test_release_group_yaml_without_override_section_ignored(self, tmp_path):
_write(
tmp_path / ".alfred" / "release_groups" / "GRP.yaml",
{"name": "GRP"}, # no 'override' key
)
# Must not crash and must not introduce an intermediate node.
repo = RuleSetRepository(tmp_path)
rs = repo.load(release_group="GRP")
# No extra rule set was created → it's still the global default.
assert rs.scope.level == "global"
def test_missing_release_group_file_silently_ignored(self, tmp_path):
repo = RuleSetRepository(tmp_path)
rs = repo.load(release_group="DOES_NOT_EXIST")
assert rs.scope.level == "global"
# --------------------------------------------------------------------------- #
# save_local #
# --------------------------------------------------------------------------- #
class TestSaveLocal:
def test_creates_file(self, tmp_path):
repo = RuleSetRepository(tmp_path)
repo.save_local({"languages": ["spa"]})
path = tmp_path / ".alfred" / "rules.yaml"
assert path.is_file()
loaded = yaml.safe_load(path.read_text())
assert loaded == {"override": {"languages": ["spa"]}}
def test_merges_with_existing(self, tmp_path):
repo = RuleSetRepository(tmp_path)
repo.save_local({"languages": ["spa"]})
repo.save_local({"min_confidence": 0.8})
loaded = yaml.safe_load((tmp_path / ".alfred" / "rules.yaml").read_text())
assert loaded["override"]["languages"] == ["spa"]
assert loaded["override"]["min_confidence"] == 0.8
def test_overwrites_existing_key(self, tmp_path):
repo = RuleSetRepository(tmp_path)
repo.save_local({"languages": ["spa"]})
repo.save_local({"languages": ["jpn"]})
loaded = yaml.safe_load((tmp_path / ".alfred" / "rules.yaml").read_text())
assert loaded["override"]["languages"] == ["jpn"]
def test_temp_file_cleaned_up(self, tmp_path):
repo = RuleSetRepository(tmp_path)
repo.save_local({"languages": ["spa"]})
# No stale .tmp file
assert not (tmp_path / ".alfred" / "rules.yaml.tmp").exists()