"""Unit tests for GET /versions/{id}/waveform endpoint — reads peaks from DB.""" import uuid from unittest.mock import AsyncMock, MagicMock, patch import pytest from rehearsalhub.db.models import AudioVersion, Member, Song def _make_member() -> MagicMock: m = MagicMock(spec=Member) m.id = uuid.uuid4() m.nc_url = "http://nc.test" m.nc_username = "user" m.nc_password = "pass" return m def _make_version(peaks=None, peaks_mini=None, has_waveform_url=False) -> MagicMock: v = MagicMock(spec=AudioVersion) v.id = uuid.uuid4() v.song_id = uuid.uuid4() v.uploaded_by = None v.waveform_url = "waveforms/test.json" if has_waveform_url else None v.waveform_peaks = peaks v.waveform_peaks_mini = peaks_mini v.cdn_hls_base = None v.nc_file_path = "/bands/test/v1.wav" return v def _make_song(band_id: uuid.UUID) -> MagicMock: s = MagicMock(spec=Song) s.id = uuid.uuid4() s.band_id = band_id return s @pytest.mark.asyncio async def test_waveform_returns_full_peaks_from_db(mock_session): """GET /versions/{id}/waveform returns 500-point peaks from DB column.""" from rehearsalhub.routers.versions import get_waveform peaks = [float(i) / 500 for i in range(500)] version = _make_version(peaks=peaks) member = _make_member() band_id = uuid.uuid4() song = _make_song(band_id) with ( patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership", return_value=(version, song)), ): result = await get_waveform(version_id=version.id, session=mock_session, current_member=member) assert result["data"] == peaks assert result["length"] == 500 assert "mini" not in result @pytest.mark.asyncio async def test_waveform_returns_mini_peaks_with_resolution_param(mock_session): """GET /versions/{id}/waveform?resolution=mini returns 100-point peaks.""" from rehearsalhub.routers.versions import get_waveform peaks_mini = [float(i) / 100 for i in range(100)] version = _make_version(peaks=[0.5] * 500, peaks_mini=peaks_mini) member = _make_member() band_id = uuid.uuid4() song = _make_song(band_id) with ( patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership", return_value=(version, song)), ): result = await get_waveform(version_id=version.id, session=mock_session, current_member=member, resolution="mini") assert result["data"] == peaks_mini assert result["length"] == 100 @pytest.mark.asyncio async def test_waveform_404_when_no_peaks_in_db(mock_session): """GET /versions/{id}/waveform returns 404 when no peaks stored yet.""" from fastapi import HTTPException from rehearsalhub.routers.versions import get_waveform version = _make_version(peaks=None, peaks_mini=None) member = _make_member() song = _make_song(uuid.uuid4()) with ( patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership", return_value=(version, song)), ): with pytest.raises(HTTPException) as exc_info: await get_waveform(version_id=version.id, session=mock_session, current_member=member) assert exc_info.value.status_code == 404 @pytest.mark.asyncio async def test_waveform_mini_404_when_no_mini_peaks(mock_session): """GET /versions/{id}/waveform?resolution=mini returns 404 when no mini peaks stored.""" from fastapi import HTTPException from rehearsalhub.routers.versions import get_waveform version = _make_version(peaks=[0.5] * 500, peaks_mini=None) member = _make_member() song = _make_song(uuid.uuid4()) with ( patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership", return_value=(version, song)), ): with pytest.raises(HTTPException) as exc_info: await get_waveform(version_id=version.id, session=mock_session, current_member=member, resolution="mini") assert exc_info.value.status_code == 404