Spaces:
Build error
Build error
"""Unit tests for AudioContent value object.""" | |
import pytest | |
from src.domain.models.audio_content import AudioContent | |
class TestAudioContent: | |
"""Test cases for AudioContent value object.""" | |
def test_valid_audio_content_creation(self): | |
"""Test creating valid AudioContent instance.""" | |
audio_data = b"fake_audio_data" | |
audio = AudioContent( | |
data=audio_data, | |
format="wav", | |
sample_rate=44100, | |
duration=10.5, | |
filename="test.wav" | |
) | |
assert audio.data == audio_data | |
assert audio.format == "wav" | |
assert audio.sample_rate == 44100 | |
assert audio.duration == 10.5 | |
assert audio.filename == "test.wav" | |
assert audio.size_bytes == len(audio_data) | |
assert audio.is_valid_format is True | |
def test_audio_content_without_filename(self): | |
"""Test creating AudioContent without filename.""" | |
audio = AudioContent( | |
data=b"fake_audio_data", | |
format="mp3", | |
sample_rate=22050, | |
duration=5.0 | |
) | |
assert audio.filename is None | |
assert audio.format == "mp3" | |
def test_empty_audio_data_raises_error(self): | |
"""Test that empty audio data raises ValueError.""" | |
with pytest.raises(ValueError, match="Audio data cannot be empty"): | |
AudioContent( | |
data=b"", | |
format="wav", | |
sample_rate=44100, | |
duration=10.0 | |
) | |
def test_non_bytes_audio_data_raises_error(self): | |
"""Test that non-bytes audio data raises TypeError.""" | |
with pytest.raises(TypeError, match="Audio data must be bytes"): | |
AudioContent( | |
data="not_bytes", # type: ignore | |
format="wav", | |
sample_rate=44100, | |
duration=10.0 | |
) | |
def test_unsupported_format_raises_error(self): | |
"""Test that unsupported format raises ValueError.""" | |
with pytest.raises(ValueError, match="Unsupported audio format: xyz"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="xyz", | |
sample_rate=44100, | |
duration=10.0 | |
) | |
def test_supported_formats(self): | |
"""Test all supported audio formats.""" | |
supported_formats = ['wav', 'mp3', 'flac', 'ogg'] | |
for fmt in supported_formats: | |
audio = AudioContent( | |
data=b"fake_audio_data", | |
format=fmt, | |
sample_rate=44100, | |
duration=10.0 | |
) | |
assert audio.format == fmt | |
assert audio.is_valid_format is True | |
def test_negative_sample_rate_raises_error(self): | |
"""Test that negative sample rate raises ValueError.""" | |
with pytest.raises(ValueError, match="Sample rate must be positive"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=-1, | |
duration=10.0 | |
) | |
def test_zero_sample_rate_raises_error(self): | |
"""Test that zero sample rate raises ValueError.""" | |
with pytest.raises(ValueError, match="Sample rate must be positive"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=0, | |
duration=10.0 | |
) | |
def test_sample_rate_too_low_raises_error(self): | |
"""Test that sample rate below 8000 raises ValueError.""" | |
with pytest.raises(ValueError, match="Sample rate must be between 8000 and 192000 Hz"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=7999, | |
duration=10.0 | |
) | |
def test_sample_rate_too_high_raises_error(self): | |
"""Test that sample rate above 192000 raises ValueError.""" | |
with pytest.raises(ValueError, match="Sample rate must be between 8000 and 192000 Hz"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=192001, | |
duration=10.0 | |
) | |
def test_valid_sample_rate_boundaries(self): | |
"""Test valid sample rate boundaries.""" | |
# Test minimum valid sample rate | |
audio_min = AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=8000, | |
duration=10.0 | |
) | |
assert audio_min.sample_rate == 8000 | |
# Test maximum valid sample rate | |
audio_max = AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=192000, | |
duration=10.0 | |
) | |
assert audio_max.sample_rate == 192000 | |
def test_negative_duration_raises_error(self): | |
"""Test that negative duration raises ValueError.""" | |
with pytest.raises(ValueError, match="Duration must be positive"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=-1.0 | |
) | |
def test_zero_duration_raises_error(self): | |
"""Test that zero duration raises ValueError.""" | |
with pytest.raises(ValueError, match="Duration must be positive"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=0.0 | |
) | |
def test_duration_too_long_raises_error(self): | |
"""Test that duration over 1 hour raises ValueError.""" | |
with pytest.raises(ValueError, match="Audio duration cannot exceed 1 hour"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=3601.0 # 1 hour + 1 second | |
) | |
def test_valid_duration_boundary(self): | |
"""Test valid duration boundary (exactly 1 hour).""" | |
audio = AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=3600.0 # Exactly 1 hour | |
) | |
assert audio.duration == 3600.0 | |
def test_empty_filename_raises_error(self): | |
"""Test that empty filename raises ValueError.""" | |
with pytest.raises(ValueError, match="Filename cannot be empty string"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=10.0, | |
filename="" | |
) | |
def test_whitespace_filename_raises_error(self): | |
"""Test that whitespace-only filename raises ValueError.""" | |
with pytest.raises(ValueError, match="Filename cannot be empty string"): | |
AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=10.0, | |
filename=" " | |
) | |
def test_audio_content_is_immutable(self): | |
"""Test that AudioContent is immutable (frozen dataclass).""" | |
audio = AudioContent( | |
data=b"fake_audio_data", | |
format="wav", | |
sample_rate=44100, | |
duration=10.0 | |
) | |
with pytest.raises(AttributeError): | |
audio.format = "mp3" # type: ignore | |
def test_size_bytes_property(self): | |
"""Test size_bytes property returns correct value.""" | |
test_data = b"test_audio_data_123" | |
audio = AudioContent( | |
data=test_data, | |
format="wav", | |
sample_rate=44100, | |
duration=10.0 | |
) | |
assert audio.size_bytes == len(test_data) |