/
/
/
1"""Tests for the Jellyfin provider."""
2
3from collections.abc import AsyncGenerator
4from typing import TYPE_CHECKING
5from unittest import mock
6
7import pytest
8from aiojellyfin.testing import FixtureBuilder
9
10from music_assistant.mass import MusicAssistant
11from tests.common import get_fixtures_dir, wait_for_sync_completion
12
13if TYPE_CHECKING:
14 from music_assistant_models.config_entries import ProviderConfig
15
16
17@pytest.fixture
18async def jellyfin_provider(mass: MusicAssistant) -> AsyncGenerator[ProviderConfig]:
19 """Configure an aiojellyfin test fixture, and add a provider to mass that uses it."""
20 f = FixtureBuilder()
21 async for _, artist in get_fixtures_dir("artists", "jellyfin"):
22 f.add_json_bytes(artist)
23
24 async for _, album in get_fixtures_dir("albums", "jellyfin"):
25 f.add_json_bytes(album)
26
27 async for _, track in get_fixtures_dir("tracks", "jellyfin"):
28 f.add_json_bytes(track)
29
30 authenticate_by_name = f.to_authenticate_by_name()
31
32 with mock.patch(
33 "music_assistant.providers.jellyfin.authenticate_by_name", authenticate_by_name
34 ):
35 async with wait_for_sync_completion(mass):
36 config = await mass.config._create_provider_instance(
37 "jellyfin",
38 {},
39 # connection details are collected by the setup flow and live in setup_data
40 setup_data=mass.config._encrypt_values(
41 {
42 "url": "http://localhost",
43 "username": "username",
44 "password": "password",
45 }
46 ),
47 )
48 await mass.music.start_sync()
49
50 yield config
51
52
53@pytest.mark.usefixtures("jellyfin_provider")
54async def test_get_artist_albums(mass: MusicAssistant) -> None:
55 """Test that get_artist_albums returns albums for a real artist ID."""
56 artists = await mass.music.artists.library_items(search="Ash", summary=False)
57 ash = artists[0]
58 prov_mapping = next(m for m in ash.provider_mappings if m.provider_domain == "jellyfin")
59 albums = await mass.music.artists.get_provider_artist_albums(
60 prov_mapping.item_id, prov_mapping.provider_instance
61 )
62 assert any(album.name == "Nu-Clear Sounds" for album in albums)
63
64
65@pytest.mark.usefixtures("jellyfin_provider")
66async def test_initial_sync(mass: MusicAssistant) -> None:
67 """Test that initial sync worked."""
68 artists = await mass.music.artists.library_items(search="Ash")
69 assert artists[0].name == "Ash"
70
71 albums = await mass.music.albums.library_items(search="christmas")
72 assert albums[0].name == "This Is Christmas"
73
74 tracks = await mass.music.tracks.library_items(search="where the bands are")
75 assert tracks[0].name == "Where the Bands Are"
76 assert tracks[0].version == "2018 Version"
77