Files
rehearshalhub/api/tests/integration/test_versions_streaming.py
2026-03-29 20:44:23 +02:00

172 lines
6.3 KiB
Python

"""Integration tests for version streaming endpoints."""
import pytest
from unittest.mock import AsyncMock, patch, MagicMock
import httpx
from rehearsalhub.routers.versions import stream_version, get_waveform
from rehearsalhub.db.models import Member, AudioVersion
from rehearsalhub.schemas.audio_version import AudioVersionRead
@pytest.mark.asyncio
@pytest.mark.integration
async def test_stream_version_connection_error():
"""Test stream_version endpoint handles connection errors gracefully."""
# Mock dependencies
mock_session = MagicMock()
mock_member = Member(id=1, name="Test User")
# Mock version with nc_file_path
mock_version = AudioVersion(
id="test-version-id",
nc_file_path="test/path/file.mp3",
waveform_url="test/path/waveform.json"
)
# Mock the storage client to raise connection error
with patch("rehearsalhub.routers.versions.NextcloudClient") as mock_client_class:
mock_client = MagicMock()
mock_client.download = AsyncMock(side_effect=httpx.ConnectError("Connection failed"))
mock_client_class.return_value = mock_client
# Mock the membership check
with patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership",
return_value=(mock_version, None)):
from fastapi import HTTPException
with pytest.raises(HTTPException) as exc_info:
await stream_version(
version_id="test-version-id",
session=mock_session,
current_member=mock_member
)
# Should return 503 Service Unavailable
assert exc_info.value.status_code == 503
assert "Failed to connect to storage" in str(exc_info.value.detail)
@pytest.mark.asyncio
@pytest.mark.integration
async def test_stream_version_file_not_found():
"""Test stream_version endpoint handles 404 errors gracefully."""
# Mock dependencies
mock_session = MagicMock()
mock_member = Member(id=1, name="Test User")
# Mock version with nc_file_path
mock_version = AudioVersion(
id="test-version-id",
nc_file_path="test/path/file.mp3",
waveform_url="test/path/waveform.json"
)
# Mock the storage client to raise 404 error
with patch("rehearsalhub.routers.versions.NextcloudClient") as mock_client_class:
mock_client = MagicMock()
# Create mock response with 404 status
mock_response = MagicMock()
mock_response.status_code = 404
mock_response.text = "Not Found"
mock_client.download = AsyncMock(
side_effect=httpx.HTTPStatusError("Not found", request=MagicMock(), response=mock_response)
)
mock_client_class.return_value = mock_client
# Mock the membership check
with patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership",
return_value=(mock_version, None)):
from fastapi import HTTPException
with pytest.raises(HTTPException) as exc_info:
await stream_version(
version_id="test-version-id",
session=mock_session,
current_member=mock_member
)
# Should return 404 Not Found
assert exc_info.value.status_code == 404
assert "File not found in storage" in str(exc_info.value.detail)
@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_waveform_connection_error():
"""Test get_waveform endpoint handles connection errors gracefully."""
# Mock dependencies
mock_session = MagicMock()
mock_member = Member(id=1, name="Test User")
# Mock version with waveform_url
mock_version = AudioVersion(
id="test-version-id",
nc_file_path="test/path/file.mp3",
waveform_url="test/path/waveform.json"
)
# Mock the storage client to raise connection error
with patch("rehearsalhub.routers.versions.NextcloudClient") as mock_client_class:
mock_client = MagicMock()
mock_client.download = AsyncMock(side_effect=httpx.ConnectError("Connection failed"))
mock_client_class.return_value = mock_client
# Mock the membership check
with patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership",
return_value=(mock_version, None)):
from fastapi import HTTPException
with pytest.raises(HTTPException) as exc_info:
await get_waveform(
version_id="test-version-id",
session=mock_session,
current_member=mock_member
)
# Should return 503 Service Unavailable
assert exc_info.value.status_code == 503
assert "Failed to connect to storage" in str(exc_info.value.detail)
@pytest.mark.asyncio
@pytest.mark.integration
async def test_stream_version_success():
"""Test successful streaming when connection works."""
# Mock dependencies
mock_session = MagicMock()
mock_member = Member(id=1, name="Test User")
# Mock version with nc_file_path
mock_version = AudioVersion(
id="test-version-id",
nc_file_path="test/path/file.mp3",
waveform_url="test/path/waveform.json"
)
# Mock the storage client to return success
with patch("rehearsalhub.routers.versions.NextcloudClient") as mock_client_class:
mock_client = MagicMock()
mock_client.download = AsyncMock(return_value=b"audio_data")
mock_client_class.return_value = mock_client
# Mock the membership check
with patch("rehearsalhub.routers.versions._get_version_and_assert_band_membership",
return_value=(mock_version, None)):
result = await stream_version(
version_id="test-version-id",
session=mock_session,
current_member=mock_member
)
# Should return Response with audio data
assert result.status_code == 200
assert result.body == b"audio_data"
assert result.media_type == "audio/mpeg"