import numpy as np import io import pytest import soundfile as sf from app.services.audio_loader import load_audio_bytes, chunk_audio def make_wav(duration=30.0, sr=22050) -> bytes: t = np.linspace(0, duration, int(sr * duration)) y = (np.sin(2 * np.pi * 440 * t) * 0.5).astype(np.float32) buf = io.BytesIO() sf.write(buf, y, sr, format="WAV") return buf.getvalue() def test_load_shape(): y, sr, duration = load_audio_bytes(make_wav(10.0)) assert sr == 22050 assert abs(duration - 10.0) < 0.1 assert y.ndim == 1 def test_chunk_count_60s(): sr = 22050 chunks = chunk_audio(np.zeros(sr * 60), sr, chunk_duration=10.0, overlap=0.5) assert len(chunks) == 11 # (60-10)/5 + 1 def test_chunk_keys(): sr = 22050 for c in chunk_audio(np.zeros(sr * 30), sr, chunk_duration=10.0, overlap=0.5): assert {"y", "start", "end"} == set(c.keys()) assert c["end"] > c["start"] def test_chunk_timing(): sr = 22050 chunks = chunk_audio(np.zeros(sr * 30), sr, chunk_duration=10.0, overlap=0.5) assert chunks[0]["start"] == 0.0 assert abs(chunks[0]["end"] - 10.0) < 0.01 assert abs(chunks[1]["start"] - 5.0) < 0.01 def test_chunk_shorter_than_window(): sr = 22050 chunks = chunk_audio(np.zeros(sr * 5), sr, chunk_duration=10.0, overlap=0.5) assert len(chunks) == 1 assert chunks[0]["start"] == 0.0 assert abs(chunks[0]["end"] - 5.0) < 0.01