Claude_Code / tests /messaging /test_transcription.py
Jainish1808
Move project files to repository root for Hugging Face Space
bf177ff
Raw
History Blame Contribute Delete
4.37 kB
"""Tests for voice note transcription."""
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from messaging.transcription import (
MAX_AUDIO_SIZE_BYTES,
transcribe_audio,
)
def test_transcribe_file_not_found_raises():
"""Non-existent file raises FileNotFoundError."""
with pytest.raises(FileNotFoundError, match="not found"):
transcribe_audio(Path("/nonexistent/file.ogg"), "audio/ogg")
def test_transcribe_file_too_large_raises():
"""File exceeding max size raises ValueError."""
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
f.write(b"x" * (MAX_AUDIO_SIZE_BYTES + 1))
path = Path(f.name)
try:
with pytest.raises(ValueError, match="too large"):
transcribe_audio(path, "audio/ogg", whisper_device="auto")
finally:
path.unlink(missing_ok=True)
def test_transcribe_local_success():
"""Local backend returns transcribed text."""
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
f.write(b"fake ogg content")
path = Path(f.name)
try:
mock_pipe = MagicMock()
mock_pipe.return_value = {"text": "Hello world"}
fake_audio = {"array": [0.0], "sampling_rate": 16000}
with (
patch("messaging.transcription._load_audio", return_value=fake_audio),
patch(
"messaging.transcription._get_pipeline",
return_value=mock_pipe,
),
):
result = transcribe_audio(path, "audio/ogg", whisper_model="base")
assert result == "Hello world"
mock_pipe.assert_called_once_with(
fake_audio, generate_kwargs={"language": "en", "task": "transcribe"}
)
finally:
path.unlink(missing_ok=True)
def test_transcribe_local_empty_segments_returns_no_speech():
"""Local backend with no speech returns placeholder."""
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
f.write(b"fake ogg")
path = Path(f.name)
try:
mock_pipe = MagicMock()
mock_pipe.return_value = {"text": ""}
fake_audio = {"array": [0.0], "sampling_rate": 16000}
with (
patch("messaging.transcription._load_audio", return_value=fake_audio),
patch(
"messaging.transcription._get_pipeline",
return_value=mock_pipe,
),
):
result = transcribe_audio(path, "audio/ogg", whisper_model="base")
assert result == "(no speech detected)"
finally:
path.unlink(missing_ok=True)
def test_transcribe_invalid_device_raises():
"""Invalid whisper_device raises ValueError."""
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
f.write(b"fake ogg")
path = Path(f.name)
try:
# Mock settings to return invalid device "auto"
mock_settings = MagicMock()
mock_settings.whisper_device = "auto"
mock_settings.whisper_model = "base"
# Patch _load_audio to avoid ImportError from missing librosa
# Device validation happens in _get_pipeline before torch import
with (
patch("messaging.transcription.get_settings", return_value=mock_settings),
patch("messaging.transcription._load_audio"),
pytest.raises(ValueError, match="whisper_device must be 'cpu' or 'cuda'"),
):
transcribe_audio(path, "audio/ogg", whisper_device="auto")
finally:
path.unlink(missing_ok=True)
def test_transcribe_local_import_error_raises():
"""Local backend when voice_local extra not installed raises ImportError."""
with tempfile.NamedTemporaryFile(suffix=".ogg", delete=False) as f:
f.write(b"fake ogg")
path = Path(f.name)
try:
with (
patch(
"messaging.transcription._get_pipeline",
side_effect=ImportError(
"Local Whisper requires the voice_local extra. "
"Install with: uv sync --extra voice_local"
),
),
pytest.raises(ImportError, match="voice_local extra"),
):
transcribe_audio(path, "audio/ogg", whisper_device="auto")
finally:
path.unlink(missing_ok=True)