diff --git a/backend/tests/test_models.py b/backend/tests/test_models.py new file mode 100644 index 0000000..59f9892 --- /dev/null +++ b/backend/tests/test_models.py @@ -0,0 +1,144 @@ +import pytest +from datetime import datetime +from pydantic import ValidationError + +from backend.app.models import CodecType, RecorderConfig, PortStatus, SCTE35Marker + + +class TestCodecType: + """Test CodecType enum values""" + + def test_codec_type_values(self): + """Verify all codec types are defined""" + assert CodecType.PRORES.value == "prores" + assert CodecType.DNXHD.value == "dnxhd" + assert CodecType.UNCOMPRESSED.value == "uncompressed" + assert CodecType.H264.value == "h264" + + def test_codec_type_members(self): + """Verify codec type members exist""" + codec_names = {member.name for member in CodecType} + assert codec_names == {"PRORES", "DNXHD", "UNCOMPRESSED", "H264"} + + +class TestRecorderConfig: + """Test RecorderConfig model""" + + def test_recorder_config_creation(self): + """Test basic RecorderConfig instantiation""" + config = RecorderConfig( + port_index=0, + codec=CodecType.PRORES, + bitrate=100, + quality_profile="high", + recording_path="/recordings", + srt_enabled=True, + srt_destination="192.168.1.10:1234", + preview_enabled=True + ) + assert config.port_index == 0 + assert config.codec == CodecType.PRORES + assert config.bitrate == 100 + assert config.quality_profile == "high" + assert config.recording_path == "/recordings" + assert config.srt_enabled is True + assert config.srt_destination == "192.168.1.10:1234" + assert config.preview_enabled is True + + def test_recorder_config_validation_port_index(self): + """Test port_index is required""" + with pytest.raises(ValidationError): + RecorderConfig(codec=CodecType.PRORES, bitrate=100) + + def test_recorder_config_codec_enum(self): + """Test codec must be CodecType enum""" + with pytest.raises(ValidationError): + RecorderConfig( + port_index=0, + codec="invalid", + bitrate=100 + ) + + +class TestPortStatus: + """Test PortStatus model""" + + def test_port_status_creation(self): + """Test PortStatus instantiation""" + status = PortStatus( + port_index=1, + is_recording=True, + frame_count=1500, + fps=30, + bitrate_mbps=450, + uptime_seconds=120, + current_file="/recordings/port1_001.mxf", + codec=CodecType.DNXHD + ) + assert status.port_index == 1 + assert status.is_recording is True + assert status.frame_count == 1500 + assert status.fps == 30 + assert status.bitrate_mbps == 450 + assert status.uptime_seconds == 120 + assert status.current_file == "/recordings/port1_001.mxf" + assert status.codec == CodecType.DNXHD + + def test_port_status_with_defaults(self): + """Test PortStatus with minimal fields""" + status = PortStatus( + port_index=0, + is_recording=False, + frame_count=0, + fps=0, + bitrate_mbps=0, + uptime_seconds=0, + current_file="", + codec=CodecType.H264 + ) + assert status.port_index == 0 + assert status.is_recording is False + assert status.frame_count == 0 + + +class TestSCTE35Marker: + """Test SCTE35Marker model""" + + def test_scte35_marker_creation(self): + """Test SCTE35Marker instantiation""" + marker = SCTE35Marker( + event_id="ad_001", + duration_seconds=30, + out_of_network=True, + splice_immediate=False, + timestamp=datetime(2026, 4, 14, 10, 30, 0), + webhook_url="https://example.com/webhook" + ) + assert marker.event_id == "ad_001" + assert marker.duration_seconds == 30 + assert marker.out_of_network is True + assert marker.splice_immediate is False + assert isinstance(marker.timestamp, datetime) + assert marker.webhook_url == "https://example.com/webhook" + + def test_scte35_marker_timestamp_generation(self): + """Test SCTE35Marker with auto-generated timestamp""" + before = datetime.utcnow() + marker = SCTE35Marker( + event_id="ad_002", + duration_seconds=60, + out_of_network=False, + splice_immediate=True, + timestamp=datetime.utcnow(), + webhook_url="https://api.example.com/events" + ) + after = datetime.utcnow() + assert before <= marker.timestamp <= after + + def test_scte35_marker_fields_required(self): + """Test that required fields are enforced""" + with pytest.raises(ValidationError): + SCTE35Marker( + event_id="ad_003", + duration_seconds=30 + )