109 lines
3.4 KiB
Python
109 lines
3.4 KiB
Python
"""Tests for LibraryService._resolve_album_tracks and resolve_tracks_batch."""
|
|
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from api.v1.schemas.library import TrackResolveRequest, TrackResolveResponse, ResolvedTrack
|
|
from services.library_service import LibraryService
|
|
|
|
|
|
def _item(mbid: str, disc: int = 1, track: int = 1):
|
|
"""Shorthand to build a TrackResolveRequest.Item-like object."""
|
|
from api.v1.schemas.library import TrackResolveItem
|
|
return TrackResolveItem(release_group_mbid=mbid, disc_number=disc, track_number=track)
|
|
|
|
|
|
def _make_service(
|
|
*,
|
|
local_service=None,
|
|
jf_service=None,
|
|
nd_service=None,
|
|
preferences=None,
|
|
cache=None,
|
|
):
|
|
lidarr_repo = MagicMock()
|
|
library_db = MagicMock()
|
|
memory_cache = cache or MagicMock()
|
|
disk_cache = MagicMock()
|
|
prefs = preferences or MagicMock()
|
|
audiodb_image_service = MagicMock()
|
|
cover_repo = MagicMock()
|
|
|
|
service = LibraryService(
|
|
lidarr_repo=lidarr_repo,
|
|
library_db=library_db,
|
|
cover_repo=cover_repo,
|
|
preferences_service=prefs,
|
|
memory_cache=memory_cache,
|
|
disk_cache=disk_cache,
|
|
audiodb_image_service=audiodb_image_service,
|
|
local_files_service=local_service,
|
|
jellyfin_library_service=jf_service,
|
|
navidrome_library_service=nd_service,
|
|
)
|
|
return service
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_tracks_batch_empty_items():
|
|
service = _make_service()
|
|
result = await service.resolve_tracks_batch([])
|
|
assert isinstance(result, TrackResolveResponse)
|
|
assert result.items == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_tracks_batch_respects_max_items():
|
|
service = _make_service()
|
|
items = [_item(f"mbid-{i}", track=i) for i in range(60)]
|
|
|
|
cache = MagicMock()
|
|
cache.get = AsyncMock(return_value=None)
|
|
cache.set = AsyncMock()
|
|
service._memory_cache = cache
|
|
|
|
local_service = MagicMock()
|
|
local_match = MagicMock()
|
|
local_match.found = False
|
|
local_match.tracks = []
|
|
local_service.match_album_by_mbid = AsyncMock(return_value=local_match)
|
|
service._local_files_service = local_service
|
|
|
|
prefs = MagicMock()
|
|
prefs.get_navidrome_connection_raw = MagicMock(side_effect=Exception("unconfigured"))
|
|
prefs.get_jellyfin_connection = MagicMock(side_effect=Exception("unconfigured"))
|
|
service._preferences_service = prefs
|
|
|
|
result = await service.resolve_tracks_batch(items)
|
|
assert len(result.items) <= 50
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_tracks_batch_missing_mbid_returns_base():
|
|
service = _make_service()
|
|
items = [_item("", disc=1, track=1)]
|
|
|
|
result = await service.resolve_tracks_batch(items)
|
|
assert len(result.items) == 1
|
|
assert result.items[0].source is None
|
|
assert result.items[0].stream_url is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_resolve_tracks_batch_uses_cache_hit():
|
|
cache = MagicMock()
|
|
cached_map = {"1:1": ("local", "file-123", "flac", 240.0)}
|
|
cache.get = AsyncMock(return_value=cached_map)
|
|
cache.set = AsyncMock()
|
|
|
|
service = _make_service(cache=cache)
|
|
items = [_item("mbid-abc", disc=1, track=1)]
|
|
|
|
result = await service.resolve_tracks_batch(items)
|
|
assert len(result.items) == 1
|
|
assert result.items[0].source == "local"
|
|
assert result.items[0].stream_url == "/api/v1/stream/local/file-123"
|
|
assert result.items[0].format == "flac"
|
|
assert result.items[0].duration == 240.0
|