youtube_abschrift_korrigieren/tests/test_yt_untertitel.py

121 lines
4 KiB
Python
Raw Normal View History

"""Tests for yt_untertitel.py; yt-dlp is always replaced by fakes (no network)."""
import subprocess
import sys
import pytest
import yt_untertitel as yt
URL = "https://www.youtube.com/watch?v=abc123"
AUTO_ONLY = {
"id": "abc123",
"title": "Eine Rede",
"subtitles": {},
"automatic_captions": {"de-orig": [], "de": [], "en": []},
}
pytestmark = pytest.mark.usefixtures("yt_dlp_installed")
def run_main(monkeypatch, *args):
monkeypatch.setattr(sys, "argv", ["yt_untertitel.py", *map(str, args)])
yt.main()
# === Track selection ===
@pytest.mark.parametrize("info, lang, expected", [
({"subtitles": {"de": []}, "automatic_captions": {"de-orig": []}}, "de", ("de", False)),
(AUTO_ONLY, "de", ("de-orig", True)),
# "en" exists only as machine translation of the German original
(AUTO_ONLY, "en", None),
({"subtitles": None, "automatic_captions": None}, "de", None),
])
def test_choose_track(info, lang, expected):
assert yt.choose_track(info, lang) == expected
@pytest.mark.parametrize("info, expected", [
(AUTO_ONLY, "de"),
({"language": "fr", "automatic_captions": {}}, "fr"),
({"subtitles": {"en": []}}, None),
])
def test_original_language(info, expected):
assert yt.original_language(info) == expected
def test_available_tracks():
info = {"subtitles": {"fr": []}, "automatic_captions": {"de-orig": [], "de": []}}
assert yt.available_tracks(info) == (["fr"], ["de"])
# === Command line ===
def test_main_downloads_auto_original(fake_yt_dlp, tmp_path, monkeypatch, capsys):
run = fake_yt_dlp(AUTO_ONLY)
monkeypatch.setattr(yt.subprocess, "run", run)
run_main(monkeypatch, "-u", URL, "-n", "Rede", "-d", tmp_path / "neu")
assert (tmp_path / "neu" / "Rede.de-orig.vtt").is_file()
download = run.calls[1]
assert "--write-auto-subs" in download and "--write-subs" not in download
assert download[-1] == URL
out = capsys.readouterr().out
assert "automatische Untertitel „de-orig“" in out
assert "vtt2txt.py -i" in out
def test_main_prefers_manual_and_defaults_to_video_id(fake_yt_dlp, tmp_path, monkeypatch):
info = dict(AUTO_ONLY, subtitles={"de": []})
run = fake_yt_dlp(info)
monkeypatch.setattr(yt.subprocess, "run", run)
run_main(monkeypatch, "-u", URL, "-d", tmp_path)
assert (tmp_path / "abc123.de.vtt").is_file()
assert "--write-subs" in run.calls[1]
def test_main_no_matching_track(fake_yt_dlp, tmp_path, monkeypatch):
monkeypatch.setattr(yt.subprocess, "run", fake_yt_dlp(AUTO_ONLY))
with pytest.raises(SystemExit, match="Automatisch \\(Originalsprache\\): de"):
run_main(monkeypatch, "-u", URL, "-l", "en", "-d", tmp_path)
def test_main_info_error(tmp_path, monkeypatch):
def run(command, capture_output, text):
return subprocess.CompletedProcess(command, 1, "", "ERROR: Video unavailable")
monkeypatch.setattr(yt.subprocess, "run", run)
with pytest.raises(SystemExit, match="Video unavailable"):
run_main(monkeypatch, "-u", URL, "-d", tmp_path)
@pytest.mark.parametrize("kwargs, message", [
({"fail_download": True}, "HTTP Error 429"),
({"write": False}, "keine Datei"),
])
def test_main_download_errors(fake_yt_dlp, tmp_path, monkeypatch, kwargs, message):
monkeypatch.setattr(yt.subprocess, "run", fake_yt_dlp(AUTO_ONLY, **kwargs))
with pytest.raises(SystemExit, match=message):
run_main(monkeypatch, "-u", URL, "-d", tmp_path)
@pytest.mark.parametrize("args, message", [
([], "required"),
(["-u", URL, "-n", "sub/Rede"], "ohne Verzeichnis"),
(["-u", URL, "-n", ""], "ohne Verzeichnis"),
])
def test_cli_errors(monkeypatch, capsys, args, message):
with pytest.raises(SystemExit) as exc:
run_main(monkeypatch, *args)
assert exc.value.code == 2
assert message in capsys.readouterr().err
def test_cli_without_yt_dlp(monkeypatch, capsys):
monkeypatch.setattr(yt.shutil, "which", lambda name: None)
with pytest.raises(SystemExit):
run_main(monkeypatch, "-u", URL)
assert "pip install yt-dlp" in capsys.readouterr().err