Files
mitus/tests/test_manager.py

110 lines
3.9 KiB
Python

"""Tests for cht.stream.manager — StreamManager."""
import json
from unittest.mock import patch, MagicMock
import pytest
from cht.stream.manager import StreamManager
@pytest.fixture
def manager(tmp_path):
with patch("cht.stream.manager.SESSIONS_DIR", tmp_path):
mgr = StreamManager(session_id="test_session")
yield mgr
mgr.stop_all()
class TestInit:
def test_session_id_custom(self, manager):
assert manager.session_id == "test_session"
def test_recording_path_delegates_to_recorder(self, manager):
assert manager.recording_path.name == "recording_000.mp4"
def test_dirs_not_created_on_init(self, manager):
assert not manager.stream_dir.exists()
def test_relay_url_from_recorder(self, manager):
assert "4445" in manager.relay_url
class TestSetupDirs:
def test_creates_all_subdirs(self, manager):
manager.setup_dirs()
assert manager.stream_dir.is_dir()
assert manager.frames_dir.is_dir()
assert manager.transcript_dir.is_dir()
assert manager.audio_dir.is_dir()
assert manager.agent_dir.is_dir()
class TestStopAll:
def test_stop_all_calls_processor_and_recorder(self, manager):
manager.processor.stop = MagicMock()
manager.recorder.stop = MagicMock()
manager.stop_all()
manager.processor.stop.assert_called_once()
manager.recorder.stop.assert_called_once()
class TestSceneDetector:
def test_python_path_sets_processor_callback(self, manager):
"""Python path (recorder present): on_new_frames goes to processor, not recorder."""
cb = MagicMock()
manager.start_scene_detector(on_new_frames=cb)
assert manager.processor._on_new_frames is cb
def test_python_path_does_not_start_processor_scene_detector(self, manager):
"""Python path: recorder owns scene detection — processor.start_scene_detector not called."""
manager.processor.start_scene_detector = MagicMock()
manager.start_scene_detector(on_new_frames=MagicMock())
manager.processor.start_scene_detector.assert_not_called()
def test_rust_path_sets_callback_and_starts_detector(self, tmp_path):
"""Rust path (no recorder): processor owns scene detection."""
with patch("cht.stream.manager.SESSIONS_DIR", tmp_path):
mgr = StreamManager.__new__(StreamManager)
mgr.recorder = None
mgr.processor = MagicMock()
from cht.stream.manager import SCENE_THRESHOLD
cb = MagicMock()
mgr.start_scene_detector(on_new_frames=cb)
mgr.processor.set_on_new_frames.assert_called_once_with(cb)
mgr.processor.start_scene_detector.assert_called_once_with(threshold=SCENE_THRESHOLD)
def test_update_scene_threshold_restarts_recorder(self, manager):
manager.recorder.update_scene_threshold = MagicMock()
manager.update_scene_threshold(0.25)
manager.recorder.update_scene_threshold.assert_called_once_with(0.25)
class TestFromRustSession:
def test_attaches_without_recorder(self, tmp_path):
session_dir = tmp_path / "20260410_120000"
session_dir.mkdir()
(session_dir / "stream").mkdir()
mgr = StreamManager.from_rust_session(session_dir)
assert mgr.recorder is None
assert mgr.session_id == "20260410_120000"
def test_relay_url_fallback_without_recorder(self, tmp_path):
session_dir = tmp_path / "20260410_120000"
session_dir.mkdir()
(session_dir / "stream").mkdir()
mgr = StreamManager.from_rust_session(session_dir)
assert "4445" in mgr.relay_url
def test_recorder_alive_returns_true_without_recorder(self, tmp_path):
session_dir = tmp_path / "20260410_120000"
session_dir.mkdir()
(session_dir / "stream").mkdir()
mgr = StreamManager.from_rust_session(session_dir)
assert mgr.recorder_alive() is True