Files
VoiceStudio/backend/tests/test_capture_ws.py
T
Palash Debnath 8d11e19494 feat: dictation maturity + batch TTS pipeline + tests (#32)
Global Hotkey:
- Register ⌘+⇧+Space system-wide via tauri-plugin-global-shortcut
- Shows/focuses window and emits tray-dictate event from any app

Auto-Paste:
- enigo crate simulates ⌘V/Ctrl+V after transcription
- Text auto-pastes into whatever app was active before dictation

Streaming ASR:
- WebSocket endpoint /ws/transcribe for live partial transcription
- 2s buffer interval, configurable via OMNIVOICE_STREAM_INTERVAL
- CaptureButton streams audio chunks, shows italic partial text
- Falls back to HTTP POST if WebSocket unavailable

Batch TTS Pipeline:
- Replace stub worker with full pipeline:
  extract → transcribe → translate → generate → mix → export
- Per-job progress tracking (stage, percent, current_lang, segment)
- GoogleTranslator integration via deep_translator
- Download endpoint GET /batch/download/{id}/{lang}
- BatchQueue UI rewritten: progress bars, cancel/delete, downloads
- Type-safe API client (api/batch.ts)

Tests:
- 23 tests for batch endpoints + streaming ASR helpers
- Lightweight fixtures that stub GPU deps

UX (earlier sessions):
- Dual-mode ASR (Turbo MLX + WhisperX Accurate)
- Enhanced download progress (speed, ETA, bytes)
- Status bar black flash fix
- Cold-start model preloading
- Full accessibility audit (ARIA, focus-visible)
- Compact UI layout improvements
- README updated with new features
2026-04-28 18:54:26 +05:30

46 lines
1.4 KiB
Python

"""Tests for the streaming ASR WebSocket helpers.
Only tests the pure-Python helper functions (no GPU needed).
The WebSocket endpoint itself requires the full app, which we
skip in CI — it's integration-tested via the browser.
"""
import os
import sys
import pytest
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
# Stub heavy deps
import types
for mod_name in ["services.model_manager", "services.asr_backend", "services.ffmpeg_utils"]:
if mod_name not in sys.modules:
sys.modules[mod_name] = types.ModuleType(mod_name)
from api.routers.capture_ws import _chunks_to_wav, MIN_BUFFER_BYTES
class TestChunksToWav:
def test_empty_returns_none(self):
assert _chunks_to_wav([]) is None
def test_tiny_returns_none(self):
assert _chunks_to_wav([b"\x00" * 10]) is None
def test_below_100_bytes_returns_none(self):
assert _chunks_to_wav([b"\x00" * 99]) is None
class TestConstants:
def test_min_buffer_bytes_reasonable(self):
"""MIN_BUFFER_BYTES should be at least 0.25s of 16-bit mono 16kHz."""
# 16kHz * 2 bytes * 0.25s = 8000
assert MIN_BUFFER_BYTES >= 8000
def test_partial_interval_positive(self):
from api.routers.capture_ws import PARTIAL_INTERVAL_S
assert PARTIAL_INTERVAL_S > 0
def test_silence_timeout_positive(self):
from api.routers.capture_ws import SILENCE_TIMEOUT_S
assert SILENCE_TIMEOUT_S > 0