claude-video/tests/test_download.py
bradautomates e90ef44c32 Implement v0.3.0 reliability fixes and managed WhisperX transcription
Add opt-in local transcription with managed installation, cache warm-up,
and a one-time backend choice while preserving native-caption priority.

Correct frame timing and coverage, caption provenance and download
ownership, configuration parsing, provider pairing, and partial reports.
Update cross-host instructions, packaging, and test-gated release CI.

Validate 198 isolated tests, real local English and Spanish inference,
network-denied warm-cache inference, live captions/media, and packaging.
Record platform and account-dependent acceptance limits separately.
2026-09-12 22:09:43 +10:00

150 lines
7.4 KiB
Python

"""Bounded caption selection, argv inheritance, and download ownership."""
import json
import subprocess
from pathlib import Path
import pytest
import download
URL = 'https://example.com/video'
def _tracks(*keys):
return {k: [{'url': 'https://example.com/sub.vtt', 'ext': 'vtt'}] for k in keys}
@pytest.mark.parametrize('language', ['en', 'ko', 'pt-BR'])
def test_original_track_overrides_dubbed_metadata(language):
info = {'extractor_key': 'Youtube', 'language': 'en', 'subtitles': _tracks(language),
'automatic_captions': _tracks(f'{language}-orig', 'en', 'ko')}
track = download.select_caption(info)
assert track['key'] == language and track['kind'] == 'manual' and track['provenance'] == 'original'
info['subtitles'] = _tracks('fr')
assert download.select_caption(info)['key'] == f'{language}-orig'
def test_requested_translation_and_unknown_source():
info = {'extractor_key': 'Youtube', 'automatic_captions': _tracks('ko-orig', 'en')}
assert download.select_caption(info, 'en')['provenance'] == 'requested translation'
assert download.select_caption({'subtitles': _tracks('es')})['provenance'] == 'unknown'
assert download.select_caption(info, 'de') is None
def test_cookie_modes_and_conflict():
assert download.auth_args(cookies_from_browser='firefox:profile with spaces') == ['--no-cookies', '--cookies-from-browser', 'firefox:profile with spaces']
assert download.auth_args(cookies_file='jar.txt')[:2] == ['--no-cookies-from-browser', '--cookies']
assert download.auth_args() == []
with pytest.raises(SystemExit, match='either'):
download.auth_args('jar', 'browser')
def _fake_stages(monkeypatch, *, fail_media=False, media_path=None):
calls = []
def run(cmd):
calls.append(cmd)
template = cmd[cmd.index('-o') + 1]
directory = Path(template.rsplit('/video.', 1)[0].replace('%%', '%'))
if '--load-info-json' not in cmd and '--skip-download' in cmd:
(directory / 'video.info.json').write_text(json.dumps({'id': 'test', 'language': 'ko', 'subtitles': _tracks('ko')}))
elif '--sub-langs' in cmd:
(directory / 'video.ko.vtt').write_text('WEBVTT\n\n00:00.000 --> 00:01.000\nhello\n')
else:
if fail_media:
raise SystemExit('network failure')
path = Path(media_path) if media_path else directory / 'video.mp4'
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b'completed')
record = Path(cmd[cmd.index('--print-to-file') + 2].replace('%%', '%'))
record.write_text(json.dumps(str(path)) + '\n')
return subprocess.CompletedProcess(cmd, 0, '', '')
monkeypatch.setattr(download, '_run', run)
return calls
def test_fetch_captions_requests_one_exact_track(monkeypatch, tmp_path):
calls = _fake_stages(monkeypatch)
result = download.fetch_captions(URL, tmp_path / '100% 한 글', cookies_from_browser='firefox:profile')
download.download_url(URL, tmp_path, context=result, cookies_from_browser='firefox:profile')
metadata, captions, media = calls
assert '--no-write-subs' in metadata and '--no-write-auto-subs' in metadata
assert metadata[-2:] == ['--', URL]
assert captions[captions.index('--sub-langs') + 1] == '-all,^ko$'
assert '--load-info-json' in captions and URL not in captions
assert '--no-write-subs' in media and '--no-write-auto-subs' in media and '--sub-langs' not in media
assert all('--cookies-from-browser' in cmd and '--no-cookies' in cmd for cmd in calls)
assert Path(result['subtitle_path']).exists()
def test_failed_download_never_returns_old_media(monkeypatch, tmp_path):
(tmp_path / 'video.mp4').write_bytes(b'old source')
(tmp_path / 'video.f137.mp4').write_bytes(b'partial')
_fake_stages(monkeypatch, fail_media=True)
with pytest.raises(SystemExit, match='network'):
download.download_url(URL, tmp_path)
assert (tmp_path / 'video.mp4').read_bytes() == b'old source'
@pytest.mark.parametrize('name', ['video.f137.mp4', 'video.part'])
def test_rejects_partial_final_paths(monkeypatch, tmp_path, name):
run = tmp_path / 'run'
run.mkdir()
_fake_stages(monkeypatch, media_path=run / name)
with pytest.raises(SystemExit, match='completed'):
download.download_url(URL, tmp_path, context={'run_dir': str(run), 'info': {'title': 'test'}})
def test_rejects_outside_final_path(monkeypatch, tmp_path):
_fake_stages(monkeypatch, media_path=tmp_path / 'outside.mp4')
with pytest.raises(SystemExit, match='inside'):
download.download_url(URL, tmp_path)
@pytest.mark.parametrize('message,hint', [
('HTTP 403 forbidden', 'original error'), ('HTTP 429', 'rate limiting'),
('Sign in to continue', 'authentication'), ('No JavaScript runtime', 'Deno/EJS'),
('egress denied', 'network settings'), ('certificate verify failed', 'trusted CA'),
])
def test_network_diagnostics(message, hint):
assert hint in download.network_diagnostic(message)
def test_actual_ytdlp_exact_track_with_inherited_all(monkeypatch, tmp_path, static_clip):
"""Use the installed stable CLI offline for caption selection and final media paths."""
import shutil
if not shutil.which('yt-dlp'):
pytest.skip('yt-dlp required for offline CLI acceptance')
subs = tmp_path / 'source.vtt'
subs.write_text('WEBVTT\n\n00:00.000 --> 00:01.000\n안녕\n', encoding='utf-8')
user_cfg = Path.home() / '.config' / 'yt-dlp'
user_cfg.mkdir(parents=True)
# Redirecting typed templates must not divert watch's output.
user_cfg.joinpath('config').write_text('--enable-file-urls\n--sub-langs all\n-o "subtitle:elsewhere/sub.%(ext)s"\n', encoding='utf-8')
raw = {'id': 'offline', 'title': 'Offline', 'extractor': 'generic', 'extractor_key': 'Generic',
'webpage_url': URL, 'url': static_clip.as_uri(), 'ext': 'mp4', 'duration': 3,
'language': 'ko', 'subtitles': {'ko': [{'url': subs.as_uri(), 'ext': 'vtt'}],
'en': [{'url': (tmp_path / 'must-not-read.vtt').as_uri(), 'ext': 'vtt'}]}}
real_run = download._run
def stages(cmd):
if '--load-info-json' not in cmd and '--skip-download' in cmd:
input_info = tmp_path / 'input.info.json'
input_info.write_text(json.dumps(raw))
# Retain the actual metadata-stage flags/templates, only substitute
# an offline source for the network extractor.
return real_run([*cmd[:-2], '--load-info-json', str(input_info)])
return real_run(cmd)
monkeypatch.setattr(download, '_run', stages)
result = download.fetch_captions(URL, tmp_path / '100% 한 글')
assert not result['errors'], result['errors']
assert Path(result['subtitle_path']).read_text(encoding='utf-8').endswith('안녕\n')
assert len(list(Path(result['run_dir']).glob('*.vtt'))) == 1
assert Path(result['info_path']).name == 'video.info.json'
assert 'requested_subtitles' not in json.loads(Path(result['info_path']).read_text())
result = download.download_url(URL, tmp_path, context=result)
assert Path(result['video_path']).read_bytes() == static_clip.read_bytes()
assert not Path('elsewhere').exists()
def test_explicit_regional_language_is_not_silently_replaced():
assert download.select_caption({'subtitles': _tracks('en-US')}, 'en-GB') is None
assert download.select_caption({'subtitles': _tracks('en-US')}, 'en')['key'] == 'en-US'