Ctrl K
ComunidadGuías…

backend/tests/test_every_new_sidecar_is_processed.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Every sidecar Sublarr writes gets the download's processing, whatever its path.

Audit #61 A24: automatic extraction processed only the primary sidecar, and a
manual single-track extraction none at all. A25: the extraction passed the
Sonarr id only, so a standalone series' own processing settings were ignored.
"""

from unittest.mock import MagicMock, patch

from services import embedded_extractor
from services.embedded_extractor import ExtractResult

SETTINGS = MagicMock(
    embedded_extract_remove_from_container=False,
    enable_subtitle_repair=False,
    target_language="de",
)


def _extract(tmp_path, item):
    video = tmp_path / "Ep.mkv"
    video.write_bytes(b"fake")
    de, en = str(tmp_path / "Ep.de.ass"), str(tmp_path / "Ep.en.ass")
    result = ExtractResult(
        any_extracted=True,
        extracted=[
            {"language": "de", "format": "ass", "sub_index": 0, "output_path": de},
            {"language": "en", "format": "ass", "sub_index": 1, "output_path": en},
        ],
        primary_output_path=de,
        primary_format="ass",
        primary_language="de",
        sidecars_trashed=0,
    )
    SETTINGS.media_path = str(tmp_path)
    with (
        patch("config.get_settings", return_value=SETTINGS),
        patch("db.wanted.get_wanted_item", return_value={"id": 1, "target_language": "de", **item}),
        patch("db.wanted.update_existing_sub"),
        patch("db.wanted.update_wanted_status"),
        patch("ass_utils.get_media_streams", return_value={"streams": []}),
        patch(
            "services.embedded_extractor.resolve_profile_for_item",
            return_value={"target_languages": ["de", "en"]},
        ),
        patch("services.embedded_extractor.extract_and_cleanup", return_value=result),
        patch("services.embedded_extractor.emit_event"),
        patch("services.embedded_extractor.log_activity"),
        patch("services.standalone_library.wanted_item_path_refusal", return_value=None),
        patch("services.processing_pipeline._run_pipeline_for_path") as pipeline,
    ):
        embedded_extractor.extract_embedded_sub(1, str(video))
    return pipeline, de, en


def test_every_extracted_language_is_processed(tmp_path):
    pipeline, de, en = _extract(tmp_path, {"sonarr_series_id": 7})

    assert sorted(c.args[0] for c in pipeline.call_args_list) == sorted([de, en])
    assert {c.kwargs["series_id"] for c in pipeline.call_args_list} == {7}


def test_a_standalone_series_passes_its_owner_key(tmp_path):
    pipeline, _, _ = _extract(tmp_path, {"standalone_series_id": 12})

    assert {c.kwargs["series_id"] for c in pipeline.call_args_list} == {-12}


def test_the_lookup_from_a_sidecar_knows_standalone_series(tmp_path):
    from services.processing_pipeline import series_key_for_sidecar

    with patch(
        "db.wanted.get_wanted_items_by_path",
        side_effect=lambda p: [{"standalone_series_id": 12}] if p.endswith("Ep.mkv") else [],
    ):
        assert series_key_for_sidecar(str(tmp_path / "Ep.de.srt")) == -12


def test_a_manual_track_extraction_is_processed(client, tmp_path):
    video = tmp_path / "Ep.mkv"
    video.write_bytes(b"fake")
    stream = {
        "index": 2,
        "codec_type": "subtitle",
        "codec_name": "ass",
        "tags": {"language": "eng"},
    }
    with (
        patch("routes.tracks._get_video_path", return_value=str(video)),
        patch("routes.tracks.get_media_streams", return_value={"streams": [stream]}),
        patch("routes.tracks.extract_subtitle_stream") as extract,
        patch("services.processing_pipeline.process_new_sidecar") as process,
    ):
        response = client.post("/api/v1/library/episodes/5/tracks/2/extract", json={})

    assert response.status_code == 200, response.get_json()
    extract.assert_called_once()
    process.assert_called_once_with(response.get_json()["output_path"])