/
/
/
1"""Tests for Audiobookshelf provider initialization."""
2
3from unittest.mock import AsyncMock, Mock, patch
4
5import pytest
6from music_assistant_models.enums import MediaType, ProviderFeature
7
8from music_assistant.models.music_provider import MusicProvider
9from music_assistant.providers.audiobookshelf import Audiobookshelf
10from music_assistant.providers.audiobookshelf.helpers import LibraryHelper
11
12
13def test_supported_features_before_async_init(provider: Audiobookshelf) -> None:
14 """Provider features are available before asynchronous initialization."""
15 assert ProviderFeature.PLAYLIST_CREATE_AUDIOBOOKS in provider.supported_features
16
17
18@pytest.mark.asyncio
19async def test_sync_library_clears_stale_library_ids(provider: Audiobookshelf) -> None:
20 """sync_library removes stale library IDs that no longer exist on ABS."""
21 assert "lib1" in provider.libraries.audiobooks
22 provider.libraries.podcasts["pod_stale"] = LibraryHelper(name="Stale Podcast")
23
24 mock_library = Mock()
25 mock_library.id_ = "pod_lib_1"
26 mock_library.name = "Podcasts"
27 mock_library.media_type = "podcast"
28 provider._client.get_all_libraries = AsyncMock(return_value=[mock_library]) # type: ignore[method-assign]
29 provider._client.get_library_narrators = AsyncMock(return_value=[]) # type: ignore[method-assign]
30 provider._client.get_my_user = AsyncMock() # type: ignore[method-assign]
31 provider.mass.cache.set = AsyncMock() # type: ignore[method-assign]
32 provider.mass.music.get_playlog_provider_item_ids = AsyncMock(return_value=set()) # type: ignore[method-assign]
33
34 with patch.object(MusicProvider, "sync_library", AsyncMock()):
35 await provider.sync_library(MediaType.AUDIOBOOK)
36
37 assert len(provider.libraries.audiobooks) == 0
38 # Only audiobooks are cleared â podcasts dict is untouched by an AUDIOBOOK sync
39 assert "pod_stale" in provider.libraries.podcasts
40
41
42@pytest.mark.asyncio
43async def test_sync_library_keys_prunes_stale_and_adds_new(provider: Audiobookshelf) -> None:
44 """_sync_library_keys removes stale keys and adds new ones, preserving item_ids."""
45 provider.libraries.audiobooks["stale_book"] = LibraryHelper(name="Stale Book")
46 provider.libraries.audiobooks["existing_book"] = LibraryHelper(
47 name="Existing Book", item_ids={"id_a", "id_b"}
48 )
49 provider.libraries.podcasts["stale_pod"] = LibraryHelper(name="Stale Podcast")
50
51 current_book = Mock()
52 current_book.id_ = "existing_book"
53 current_book.name = "Existing Book"
54 current_book.media_type = "book"
55 current_pod = Mock()
56 current_pod.id_ = "new_pod"
57 current_pod.name = "New Podcast"
58 current_pod.media_type = "podcast"
59
60 provider._sync_library_keys([current_book, current_pod])
61
62 assert list(provider.libraries.audiobooks.keys()) == ["existing_book"]
63 assert provider.libraries.audiobooks["existing_book"].item_ids == {"id_a", "id_b"}
64 assert list(provider.libraries.podcasts.keys()) == ["new_pod"]
65