"""Phase 1 component test: VideoEngine skeleton + config gate. Verifies: - ``ModelManager`` can be imported and constructed. - When ``config.video.enabled=false``, ``_load_video`` skips and leaves ``video_engine=None`` (existing voice path unaffected). - When ``config.video.enabled=true``, a ``VideoEngine`` instance is created and ``is_ready()`` returns False (no models loaded yet). Does NOT load Wan2.2 or MuseTalk — this test is safe to run on any machine with the python deps installed (no GPU needed). Run inside Docker: docker compose exec voice-chat python -m tests.component.test_01_video_skeleton """ from __future__ import annotations import sys from server.models import ModelManager from server.video import VideoConfig, VideoEngine from tests.component._common import get_logger log = get_logger("test_01") def run(): # --- disabled path --- log.info("[case 1] config.video.enabled=False → engine skipped") mgr = ModelManager() # Monkey-patch the config module to simulate disabled import server.config as cfgmod original = cfgmod.config cfgmod.config = {"video": {"enabled": False}, **{k: v for k, v in original.items() if k != "video"}} try: mgr._load_video() assert mgr.video_engine is None, "video_engine should be None when disabled" log.info(" PASS: video_engine is None") finally: cfgmod.config = original # --- enabled path (no models loaded) --- log.info("[case 2] config.video.enabled=True → engine created, not ready") mgr2 = ModelManager() cfgmod.config = { **original, "video": {"enabled": True, "mode": "reflective", "loras": []}, } try: mgr2._load_video() assert mgr2.video_engine is not None, "video_engine should be created" assert isinstance(mgr2.video_engine, VideoEngine) assert mgr2.video_engine.is_ready() is False log.info(" PASS: engine=%s, ready=%s", type(mgr2.video_engine).__name__, mgr2.video_engine.is_ready()) finally: cfgmod.config = original log.info("ALL PASSED") if __name__ == "__main__": try: run() sys.exit(0) except AssertionError as e: log.error("FAILED: %s", e) sys.exit(1)