Files
youtube-auto-dub/tests/test_web_app.py

152 lines
5.0 KiB
Python

"""Tests for the Gradio web UI command adapter."""
from __future__ import annotations
import sys
import web_app
from web_app import (
DubJob,
_job_progress,
_stage_uploaded_cookies,
build_pipeline_command,
create_app,
load_translation_settings,
save_translation_settings,
)
def test_build_pipeline_command_uses_cli_parser_defaults():
command = build_pipeline_command({"url": "https://youtube.com/watch?v=demo"})
assert command[:3] == [sys.executable, command[1], "https://youtube.com/watch?v=demo"]
assert "--lang" in command
assert command[command.index("--lang") + 1] == "es"
assert "--mix-mode" in command
assert command[command.index("--mix-mode") + 1] == "instrumental-only"
def test_build_pipeline_command_accepts_optional_settings():
command = build_pipeline_command(
{
"url": "https://youtube.com/watch?v=demo",
"lang": "fr",
"browser": "chrome",
"whisper_model": "small",
"lmstudio_base_url": "http://localhost:1234/v1",
"lmstudio_model": "gemma-custom",
"gpu": "on",
}
)
assert command[command.index("--lang") + 1] == "fr"
assert command[command.index("--browser") + 1] == "chrome"
assert command[command.index("--whisper_model") + 1] == "small"
assert command[command.index("--lmstudio-base-url") + 1] == "http://localhost:1234/v1"
assert command[command.index("--lmstudio-model") + 1] == "gemma-custom"
assert "--gpu" in command
def test_build_pipeline_command_accepts_uploaded_mp4():
command = build_pipeline_command(
{
"input_file": "C:\\videos\\demo.mp4",
"lang": "de",
}
)
assert "https://youtube.com/watch?v=demo" not in command
assert "--input-file" in command
assert command[command.index("--input-file") + 1] == "C:\\videos\\demo.mp4"
assert command[command.index("--lang") + 1] == "de"
def test_create_app_builds_gradio_blocks():
app = create_app()
assert app.title == "Gradio YouTube Auto Dub"
def test_save_and_load_translation_settings(tmp_path, monkeypatch):
settings_file = tmp_path / "web_settings.json"
monkeypatch.setattr(web_app, "SETTINGS_FILE", settings_file)
base_url, api_key, model, message = save_translation_settings(
"http://openai-compatible.local:8080/v1",
"secret-key",
"custom-model",
)
assert base_url == "http://openai-compatible.local:8080/v1"
assert api_key == "secret-key"
assert model == "custom-model"
assert str(settings_file) in message
assert load_translation_settings() == {
"base_url": "http://openai-compatible.local:8080/v1",
"api_key": "secret-key",
"model": "custom-model",
}
def test_load_translation_settings_uses_env_defaults(tmp_path, monkeypatch):
monkeypatch.setattr(web_app, "SETTINGS_FILE", tmp_path / "missing.json")
monkeypatch.setenv("LM_STUDIO_BASE_URL", "http://env-host:1234/v1")
monkeypatch.setenv("LM_STUDIO_API_KEY", "env-key")
monkeypatch.setenv("LM_STUDIO_MODEL", "env-model")
assert load_translation_settings() == {
"base_url": "http://env-host:1234/v1",
"api_key": "env-key",
"model": "env-model",
}
def test_stage_uploaded_cookies_copies_to_upload_dir(tmp_path, monkeypatch):
upload_dir = tmp_path / "uploads"
source_file = tmp_path / "cookies.txt"
source_file.write_text("# Netscape HTTP Cookie File\n", encoding="utf-8")
monkeypatch.setattr(web_app, "UPLOAD_DIR", upload_dir)
staged_path = _stage_uploaded_cookies(str(source_file))
assert staged_path.endswith(".txt")
assert staged_path != str(source_file)
assert upload_dir in web_app.Path(staged_path).parents
assert web_app.Path(staged_path).read_text(encoding="utf-8") == "# Netscape HTTP Cookie File\n"
def test_stage_uploaded_cookies_rejects_unsupported_extension(tmp_path):
source_file = tmp_path / "cookies.json"
source_file.write_text("{}", encoding="utf-8")
try:
_stage_uploaded_cookies(str(source_file))
except ValueError as exc:
assert "Expected one of" in str(exc)
else:
raise AssertionError("Expected ValueError for unsupported cookie upload")
def test_job_progress_tracks_pipeline_steps(tmp_path):
log_path = tmp_path / "job.log"
log_path.write_text("STEP 1: PREPARING CONTENT\nSTEP 2: SPEECH TRANSCRIPTION\n", encoding="utf-8")
job = DubJob(id="demo", command=[], log_path=log_path, status="running")
progress, steps_html = _job_progress(job)
assert progress == 25
assert "[done]" in steps_html
assert "[active]" in steps_html
assert "Speech transcription" in steps_html
def test_job_progress_marks_succeeded_complete(tmp_path):
log_path = tmp_path / "job.log"
log_path.write_text("", encoding="utf-8")
job = DubJob(id="demo", command=[], log_path=log_path, status="succeeded")
progress, steps_html = _job_progress(job)
assert progress == 100
assert "[todo]" not in steps_html