Initialize the stentor-gateway project with WebSocket-based voice pipeline orchestrating STT → Agent → TTS via OpenAI-compatible APIs. - Add FastAPI app with WebSocket endpoint for audio streaming - Add pipeline orchestration (stt_client, tts_client, agent_client) - Add Pydantic Settings configuration and message models - Add audio utilities for PCM/WAV conversion and resampling - Add health check endpoints - Add Dockerfile and pyproject.toml with dependencies - Add initial test suite (pipeline, STT, TTS, WebSocket) - Add comprehensive README covering gateway and ESP32 ear design - Clean up .gitignore for Python/uv project
90 lines
3.0 KiB
Python
90 lines
3.0 KiB
Python
"""Tests for the Speaches STT client."""
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
from stentor.audio import pcm_to_wav
|
|
from stentor.stt_client import STTClient
|
|
|
|
|
|
class TestSTTClient:
|
|
"""Tests for STTClient."""
|
|
|
|
@pytest.fixture
|
|
def stt_client(self, settings):
|
|
"""Create an STT client with a mock HTTP client."""
|
|
http_client = httpx.AsyncClient()
|
|
return STTClient(settings, http_client)
|
|
|
|
async def test_transcribe_success(self, settings, sample_pcm, httpx_mock):
|
|
"""Test successful transcription."""
|
|
httpx_mock.add_response(
|
|
url=f"{settings.stt_url}/v1/audio/transcriptions",
|
|
method="POST",
|
|
json={"text": "Hello world"},
|
|
)
|
|
|
|
async with httpx.AsyncClient() as http_client:
|
|
client = STTClient(settings, http_client)
|
|
wav_data = pcm_to_wav(sample_pcm)
|
|
result = await client.transcribe(wav_data)
|
|
|
|
assert result == "Hello world"
|
|
|
|
async def test_transcribe_with_language(self, settings, sample_pcm, httpx_mock):
|
|
"""Test transcription with explicit language."""
|
|
httpx_mock.add_response(
|
|
url=f"{settings.stt_url}/v1/audio/transcriptions",
|
|
method="POST",
|
|
json={"text": "Bonjour le monde"},
|
|
)
|
|
|
|
async with httpx.AsyncClient() as http_client:
|
|
client = STTClient(settings, http_client)
|
|
wav_data = pcm_to_wav(sample_pcm)
|
|
result = await client.transcribe(wav_data, language="fr")
|
|
|
|
assert result == "Bonjour le monde"
|
|
|
|
async def test_transcribe_empty_result(self, settings, sample_pcm, httpx_mock):
|
|
"""Test transcription returning empty text."""
|
|
httpx_mock.add_response(
|
|
url=f"{settings.stt_url}/v1/audio/transcriptions",
|
|
method="POST",
|
|
json={"text": " "},
|
|
)
|
|
|
|
async with httpx.AsyncClient() as http_client:
|
|
client = STTClient(settings, http_client)
|
|
wav_data = pcm_to_wav(sample_pcm)
|
|
result = await client.transcribe(wav_data)
|
|
|
|
assert result == ""
|
|
|
|
async def test_is_available_success(self, settings, httpx_mock):
|
|
"""Test availability check when service is up."""
|
|
httpx_mock.add_response(
|
|
url=f"{settings.stt_url}/v1/models",
|
|
method="GET",
|
|
json={"models": []},
|
|
)
|
|
|
|
async with httpx.AsyncClient() as http_client:
|
|
client = STTClient(settings, http_client)
|
|
available = await client.is_available()
|
|
|
|
assert available is True
|
|
|
|
async def test_is_available_failure(self, settings, httpx_mock):
|
|
"""Test availability check when service is down."""
|
|
httpx_mock.add_exception(
|
|
httpx.ConnectError("Connection refused"),
|
|
url=f"{settings.stt_url}/v1/models",
|
|
)
|
|
|
|
async with httpx.AsyncClient() as http_client:
|
|
client = STTClient(settings, http_client)
|
|
available = await client.is_available()
|
|
|
|
assert available is False
|