Ctrl K
ComunidadGuías…

backend/tests/test_ass_extraction_copy_fallback.py

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

Archivo original ↗Preguntar a KiBot
"""ASS/SSA embedded extraction prefers stream-copy and falls back safely."""

import os
from unittest.mock import MagicMock

import pytest


@pytest.mark.parametrize("extension", ["ass", "ssa"])
def test_ass_and_ssa_extraction_uses_stream_copy_first(tmp_path, app_ctx, monkeypatch, extension):
    from ass_probe import extract_subtitle_stream

    output = tmp_path / f"episode.en.{extension}"
    calls = []

    def fake_run(command, **kwargs):
        calls.append(command)
        with open(command[-1], "wb") as extracted:
            extracted.write(b"[Script Info]\nTitle: original\n")
        return MagicMock(returncode=0, stderr="")

    monkeypatch.setattr("ass_probe.subprocess.run", fake_run)
    monkeypatch.setattr(
        "ass_probe.get_settings",
        lambda: MagicMock(ffmpeg_timeout=5, embedded_extract_ass_stream_copy=True),
    )

    extract_subtitle_stream(
        str(tmp_path / "episode.mkv"),
        {"sub_index": 0, "format": extension},
        str(output),
    )

    assert len(calls) == 1
    assert calls[0][calls[0].index("-c:s") + 1] == "copy"
    assert output.read_bytes() == b"[Script Info]\nTitle: original\n"


@pytest.mark.parametrize("extension", ["ass", "ssa"])
def test_ass_and_ssa_copy_failure_retries_with_existing_encoder(
    tmp_path, app_ctx, monkeypatch, extension
):
    from ass_probe import extract_subtitle_stream

    output = tmp_path / f"episode.en.{extension}"
    calls = []

    def fake_run(command, **kwargs):
        encoder = command[command.index("-c:s") + 1]
        calls.append(encoder)
        temp_output = command[-1]
        if encoder == "copy":
            with open(temp_output, "wb") as partial:
                partial.write(b"partial copy")
            return MagicMock(returncode=1, stderr="copy not supported")

        # The failed copy's partial output must be gone before the fallback.
        assert not os.path.exists(temp_output)
        with open(temp_output, "wb") as extracted:
            extracted.write(b"[Script Info]\nTitle: encoded fallback\n")
        return MagicMock(returncode=0, stderr="")

    monkeypatch.setattr("ass_probe.subprocess.run", fake_run)
    monkeypatch.setattr(
        "ass_probe.get_settings",
        lambda: MagicMock(ffmpeg_timeout=5, embedded_extract_ass_stream_copy=True),
    )

    extract_subtitle_stream(
        str(tmp_path / "episode.mkv"),
        {"sub_index": 0, "format": extension},
        str(output),
    )

    assert calls == ["copy", "ass"]
    assert output.read_bytes() == b"[Script Info]\nTitle: encoded fallback\n"


@pytest.mark.parametrize(
    ("extension", "expected_encoder"),
    [("srt", "srt"), ("vtt", "webvtt")],
)
def test_non_ass_formats_keep_their_existing_encoder(
    tmp_path, app_ctx, monkeypatch, extension, expected_encoder
):
    from ass_probe import extract_subtitle_stream

    output = tmp_path / f"episode.en.{extension}"
    calls = []

    def fake_run(command, **kwargs):
        calls.append(command)
        with open(command[-1], "wb") as extracted:
            extracted.write(b"subtitle output")
        return MagicMock(returncode=0, stderr="")

    monkeypatch.setattr("ass_probe.subprocess.run", fake_run)
    monkeypatch.setattr(
        "ass_probe.get_settings",
        lambda: MagicMock(ffmpeg_timeout=5, embedded_extract_ass_stream_copy=True),
    )

    extract_subtitle_stream(
        str(tmp_path / "episode.mkv"),
        {"sub_index": 0, "format": extension},
        str(output),
    )

    assert len(calls) == 1
    assert calls[0][calls[0].index("-c:s") + 1] == expected_encoder
    assert output.read_bytes() == b"subtitle output"


def test_a_copy_that_times_out_is_not_retried(tmp_path, app_ctx, monkeypatch):
    import subprocess

    from ass_probe import extract_subtitle_stream

    calls = []

    def fake_run(command, **kwargs):
        calls.append(command[command.index("-c:s") + 1])
        raise subprocess.TimeoutExpired(command, kwargs.get("timeout"))

    monkeypatch.setattr("ass_probe.subprocess.run", fake_run)
    monkeypatch.setattr(
        "ass_probe.get_settings",
        lambda: MagicMock(ffmpeg_timeout=5, embedded_extract_ass_stream_copy=True),
    )

    with pytest.raises(subprocess.TimeoutExpired):
        extract_subtitle_stream(
            str(tmp_path / "episode.mkv"),
            {"sub_index": 0, "format": "ass"},
            str(tmp_path / "episode.en.ass"),
        )
    assert calls == ["copy"]


def test_stream_copy_is_opt_in(tmp_path, app_ctx, monkeypatch):
    from ass_probe import extract_subtitle_stream

    encoders = []

    def fake_run(command, **kwargs):
        encoders.append(command[command.index("-c:s") + 1])
        with open(command[-1], "wb") as extracted:
            extracted.write(b"[Script Info]\n")
        return MagicMock(returncode=0, stderr="")

    monkeypatch.setattr("ass_probe.subprocess.run", fake_run)
    monkeypatch.setattr(
        "ass_probe.get_settings",
        lambda: MagicMock(ffmpeg_timeout=5, embedded_extract_ass_stream_copy=False),
    )
    extract_subtitle_stream(
        str(tmp_path / "episode.mkv"), {"sub_index": 0}, str(tmp_path / "episode.en.ass")
    )
    assert encoders == ["ass"]