Files
musicseerr/backend/tests/services/test_navidrome_stream_proxy.py
T
2026-04-03 15:53:00 +01:00

95 lines
2.8 KiB
Python

"""Tests for NavidromePlaybackService.proxy_head / proxy_stream."""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from services.navidrome_playback_service import NavidromePlaybackService
from core.exceptions import ExternalServiceError
def _make_service():
repo = MagicMock()
service = NavidromePlaybackService(navidrome_repo=repo)
return service, repo
@pytest.mark.asyncio
async def test_proxy_head_returns_response():
service, repo = _make_service()
from repositories.navidrome_repository import StreamProxyResult
mock_result = StreamProxyResult(
status_code=200,
headers={"Content-Type": "audio/flac", "Content-Length": "12345"},
media_type="audio/flac",
body_chunks=None,
)
repo.proxy_head_stream = AsyncMock(return_value=mock_result)
response = await service.proxy_head("song-1")
assert response.status_code == 200
assert response.headers.get("Content-Type") == "audio/flac"
@pytest.mark.asyncio
async def test_proxy_head_raises_on_error():
service, repo = _make_service()
repo.proxy_head_stream = AsyncMock(side_effect=ExternalServiceError("Failed to reach Navidrome"))
with pytest.raises(ExternalServiceError):
await service.proxy_head("song-1")
@pytest.mark.asyncio
async def test_proxy_stream_returns_streaming_response():
service, repo = _make_service()
async def fake_chunks():
yield b"chunk1"
yield b"chunk2"
from repositories.navidrome_repository import StreamProxyResult
mock_result = StreamProxyResult(
status_code=200,
headers={"Content-Type": "audio/mpeg"},
media_type="audio/mpeg",
body_chunks=fake_chunks(),
)
repo.proxy_get_stream = AsyncMock(return_value=mock_result)
response = await service.proxy_stream("song-1", None)
assert response.status_code == 200
assert response.media_type == "audio/mpeg"
@pytest.mark.asyncio
async def test_proxy_stream_with_range_header():
service, repo = _make_service()
async def fake_chunks():
yield b"partial"
from repositories.navidrome_repository import StreamProxyResult
mock_result = StreamProxyResult(
status_code=206,
headers={"Content-Type": "audio/mpeg", "Content-Range": "bytes 0-999/5000"},
media_type="audio/mpeg",
body_chunks=fake_chunks(),
)
repo.proxy_get_stream = AsyncMock(return_value=mock_result)
response = await service.proxy_stream("song-1", "bytes=0-999")
assert response.status_code == 206
@pytest.mark.asyncio
async def test_proxy_stream_raises_416():
service, repo = _make_service()
repo.proxy_get_stream = AsyncMock(
side_effect=ExternalServiceError("416 Range not satisfiable")
)
with pytest.raises(ExternalServiceError, match="416"):
await service.proxy_stream("song-1", "bytes=9999-")