feat(release): InspectedResult.recommended_action centralizes exclusion decision
Add a derived 'recommended_action' property on InspectedResult that collapses the orchestrator's go / wait / skip decision into one value: - 'skip' → no main_video, or media_type == 'other' - 'ask_user' → media_type == 'unknown', or road == 'path_of_pain' - 'process' → confident parse with a main video on disk The ordering is part of the contract (skip > ask_user > process) — documented in the property docstring. Until now every consumer (workflows, the agent, the orchestrator sketch) had to re-derive this from the road / media_type / main_video triple, with subtle drift between sites. One place, one rule. Exposed through the analyze_release tool so the LLM can route on it. Spec YAML updated to describe the new field. Suite: 1083 passed (+6 new tests in tests/application/test_inspect.py covering the four branches and the precedence rules).
This commit is contained in:
@@ -263,3 +263,94 @@ class TestFrozen:
|
||||
pass
|
||||
else: # pragma: no cover
|
||||
raise AssertionError("InspectedResult should be frozen")
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# recommended_action #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class TestRecommendedAction:
|
||||
"""``recommended_action`` collapses the orchestrator's go / wait /
|
||||
skip decision into a single property. The check ordering is part
|
||||
of the contract (skip wins over ask_user, ask_user wins over
|
||||
process) — see the property docstring."""
|
||||
|
||||
def test_skip_when_no_main_video(self, tmp_path: Path) -> None:
|
||||
# Folder with no video at all → main_video is None → skip.
|
||||
folder = tmp_path / _MOVIE_NAME
|
||||
folder.mkdir()
|
||||
(folder / "readme.txt").write_text("hi")
|
||||
|
||||
result = inspect_release(_MOVIE_NAME, folder, _KB, _RaisingProber())
|
||||
|
||||
assert result.main_video is None
|
||||
assert result.recommended_action == "skip"
|
||||
|
||||
def test_skip_when_media_type_other(self, tmp_path: Path) -> None:
|
||||
# Folder with only non-video files (ISO) → media_type == "other"
|
||||
# AND main_video is None (find_main_video filters by video ext).
|
||||
# Both branches resolve to "skip"; this asserts the contract holds.
|
||||
folder = tmp_path / _MOVIE_NAME
|
||||
folder.mkdir()
|
||||
(folder / "disc.iso").write_bytes(b"")
|
||||
|
||||
result = inspect_release(_MOVIE_NAME, folder, _KB, _RaisingProber())
|
||||
|
||||
assert result.parsed.media_type == "other"
|
||||
assert result.recommended_action == "skip"
|
||||
|
||||
def test_ask_user_when_media_type_unknown(self, tmp_path: Path) -> None:
|
||||
# Mixed video + non-video → detect_media_type returns "unknown".
|
||||
folder = tmp_path / _MOVIE_NAME
|
||||
folder.mkdir()
|
||||
(folder / "movie.mkv").write_bytes(b"")
|
||||
(folder / "extras.iso").write_bytes(b"")
|
||||
|
||||
result = inspect_release(
|
||||
_MOVIE_NAME, folder, _KB, _StubProber(_media_info_1080p_h264())
|
||||
)
|
||||
|
||||
assert result.parsed.media_type == "unknown"
|
||||
assert result.recommended_action == "ask_user"
|
||||
|
||||
def test_ask_user_when_path_of_pain_road(self, tmp_path: Path) -> None:
|
||||
# Malformed name (forbidden chars) → road == "path_of_pain".
|
||||
name = "garbage@#%name"
|
||||
folder = tmp_path / "release"
|
||||
folder.mkdir()
|
||||
(folder / "movie.mkv").write_bytes(b"")
|
||||
|
||||
result = inspect_release(
|
||||
name, folder, _KB, _StubProber(_media_info_1080p_h264())
|
||||
)
|
||||
|
||||
assert result.report.road == "path_of_pain"
|
||||
# main_video is found but the road still flags uncertainty.
|
||||
assert result.main_video is not None
|
||||
assert result.recommended_action == "ask_user"
|
||||
|
||||
def test_process_for_confident_movie(self, tmp_path: Path) -> None:
|
||||
folder = tmp_path / _MOVIE_NAME
|
||||
folder.mkdir()
|
||||
(folder / "movie.mkv").write_bytes(b"")
|
||||
|
||||
result = inspect_release(
|
||||
_MOVIE_NAME, folder, _KB, _StubProber(_media_info_1080p_h264())
|
||||
)
|
||||
|
||||
assert result.parsed.media_type == "movie"
|
||||
assert result.report.road in ("easy", "shitty")
|
||||
assert result.recommended_action == "process"
|
||||
|
||||
def test_process_for_confident_tv_show(self, tmp_path: Path) -> None:
|
||||
folder = tmp_path / _TV_NAME
|
||||
folder.mkdir()
|
||||
(folder / "episode.mkv").write_bytes(b"")
|
||||
|
||||
result = inspect_release(
|
||||
_TV_NAME, folder, _KB, _StubProber(_media_info_1080p_h264())
|
||||
)
|
||||
|
||||
assert result.parsed.media_type == "tv_show"
|
||||
assert result.recommended_action == "process"
|
||||
|
||||
Reference in New Issue
Block a user