from __future__ import annotations import os import subprocess import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] MEDIA_HOOK = PROJECT_ROOT / "packaging" / "runtime_media_smoke.py" def read(relative_path: str) -> str: return (PROJECT_ROOT / relative_path).read_text(encoding="utf-8") def test_spec_explicitly_collects_qt_multimedia_and_installs_frozen_gate() -> None: spec = read("packaging/doctor_workstation.spec") assert '"PySide6.QtMultimedia"' in spec assert '"PySide6.QtMultimediaWidgets"' in spec assert "qt_multimedia_hiddenimports" in spec assert "runtime_hooks=[str(MEDIA_SMOKE_HOOK)]" in spec assert "Qt6Multimedia*.dll/.dylib/framework" in spec assert "plugins/multimedia" in spec def test_media_runtime_hook_is_inert_without_gate_argument() -> None: result = subprocess.run( [sys.executable, "-I", "-S", str(MEDIA_HOOK)], cwd=PROJECT_ROOT, capture_output=True, text=True, timeout=10, check=False, ) assert result.returncode == 0, result.stderr def test_media_runtime_hook_fails_when_frozen_components_cannot_import() -> None: result = subprocess.run( [sys.executable, "-I", "-S", str(MEDIA_HOOK), "--media-smoke-test"], cwd=PROJECT_ROOT, capture_output=True, text=True, timeout=10, check=False, ) assert result.returncode == 70 assert "Qt multimedia smoke gate failed" in result.stderr def test_media_runtime_hook_constructs_player_and_video_widget_offscreen( tmp_path: Path, ) -> None: environment = os.environ.copy() environment.update( { "QT_QPA_PLATFORM": "offscreen", "QT_LOGGING_RULES": "qt.multimedia.*=false", "XDG_CONFIG_HOME": str(tmp_path / "config"), "XDG_CACHE_HOME": str(tmp_path / "cache"), } ) result = subprocess.run( [sys.executable, str(MEDIA_HOOK), "--media-smoke-test"], cwd=tmp_path, env=environment, capture_output=True, text=True, timeout=30, check=False, ) assert result.returncode == 0, result.stdout + result.stderr assert "Frozen Qt multimedia smoke gate passed" in result.stdout def test_windows_build_checks_files_and_runs_media_gate_before_release_archive() -> None: build = read("scripts/build_windows.ps1") package = read("scripts/package_windows.ps1") for required_name in ( "QtMultimedia.pyd", "QtMultimediaWidgets.pyd", "Qt6Multimedia.dll", "Qt6MultimediaWidgets.dll", "ffmpegmediaplugin.dll", "windowsmediaplugin.dll", ): assert required_name in build assert "Assert-FrozenMultimedia -Artifact $Artifact" in build assert build.index('Argument "--media-smoke-test"') < build.index('Write-Host "Build complete') assert "packaging\\runtime_media_smoke.py" in package assert package.index("& $BuildScript") < package.index("Compress-Archive") def test_macos_build_checks_modules_frameworks_plugins_and_runs_gate_before_zip() -> None: build = read("scripts/build_macos.sh") package = read("scripts/package_macos.sh") entry_check = read("scripts/check_macos_entrypoints.sh") for contract in ( "QtMultimedia*.so", "QtMultimediaWidgets*.so", "QtMultimedia.framework", "QtMultimediaWidgets.framework", "*Qt6Multimedia*.dylib", "*/plugins/multimedia", "*mediaplugin*.dylib", "--media-smoke-test", ): assert contract in build assert build.index('"--media-smoke-test"') < build.index('echo "Build complete') assert package.index('build_macos.sh"') < package.index("/usr/bin/ditto -c -k") assert 'check_macos_entrypoints.sh"' in package assert 'index_mode" == "100755"' in entry_check