import pytest import numpy as np from datetime import datetime, timezone from unittest.mock import AsyncMock, MagicMock, patch # Pre-import so mocker.patch can resolve the module before the test's local import import app.pipeline.processor # noqa: F401 @pytest.mark.asyncio async def test_process_utterance_known_speaker(mocker, settings, db): # Setup: insert a room and speaker with embedding db.execute("INSERT INTO rooms (name) VALUES (?)", ("Kitchen",)) db.execute("INSERT INTO speakers (name) VALUES (?)", ("Jeremy",)) db.commit() room = db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone() speaker = db.execute("SELECT id FROM speakers WHERE name='Jeremy'").fetchone() from app.pipeline.recognition import pack_embedding ref_emb = np.array([1.0] + [0.0] * 255, dtype=np.float32) db.execute( "INSERT INTO voice_embeddings (speaker_id, embedding) VALUES (?,?)", (speaker["id"], pack_embedding(ref_emb)), ) db.commit() # Mock Whisper HTTP call mocker.patch( "app.pipeline.processor.transcribe_audio", new=AsyncMock(return_value="hello world"), ) # Mock resemblyzer — return a very similar embedding query_emb = np.array([0.99] + [0.0] * 255, dtype=np.float32) mocker.patch("app.pipeline.processor.embed_audio", return_value=query_emb) # Mock clip saving mocker.patch("app.pipeline.processor.save_clip", return_value="/data/clips/test.wav") from app.pipeline.processor import process_utterance start = datetime(2026, 1, 1, 10, 0, 0, tzinfo=timezone.utc) end = datetime(2026, 1, 1, 10, 0, 3, tzinfo=timezone.utc) utterance_id = await process_utterance( room_id=room["id"], audio_bytes=b"\x00" * 100, start_time=start, end_time=end, settings=settings, db=db, ) assert utterance_id is not None row = db.execute("SELECT * FROM utterances WHERE id=?", (utterance_id,)).fetchone() assert row["transcript"] == "hello world" assert row["match_status"] == "known" assert row["speaker_id"] == speaker["id"] @pytest.mark.asyncio async def test_process_utterance_unknown_speaker(mocker, settings, db): db.execute("INSERT INTO rooms (name) VALUES (?)", ("Office",)) db.commit() room = db.execute("SELECT id FROM rooms WHERE name='Office'").fetchone() mocker.patch( "app.pipeline.processor.transcribe_audio", new=AsyncMock(return_value="test transcript"), ) mocker.patch( "app.pipeline.processor.embed_audio", return_value=np.zeros(256, dtype=np.float32), ) mocker.patch("app.pipeline.processor.save_clip", return_value="/data/clips/test.wav") from app.pipeline.processor import process_utterance start = datetime(2026, 1, 1, 10, 0, 0, tzinfo=timezone.utc) end = datetime(2026, 1, 1, 10, 0, 2, tzinfo=timezone.utc) utterance_id = await process_utterance( room_id=room["id"], audio_bytes=b"\x00" * 100, start_time=start, end_time=end, settings=settings, db=db, ) row = db.execute("SELECT * FROM utterances WHERE id=?", (utterance_id,)).fetchone() assert row["match_status"] == "unknown" assert row["speaker_id"] is None