/
/
/
1"""Unit tests for KION Music streaming quality selection."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING, Any
6
7import pytest
8from music_assistant_models.enums import ContentType
9
10from music_assistant.providers.kion_music.constants import QUALITY_HIGH, QUALITY_LOSSLESS
11from music_assistant.providers.kion_music.streaming import KionMusicStreamingManager
12
13if TYPE_CHECKING:
14 from tests.providers.kion_music.conftest import (
15 StreamingProviderStub,
16 StreamingProviderStubWithTracking,
17 )
18
19
20def _make_download_info(
21 codec: str,
22 bitrate_in_kbps: int,
23 direct_link: str = "https://example.com/track",
24) -> Any:
25 """Build DownloadInfo-like object."""
26 return type(
27 "DownloadInfo",
28 (),
29 {
30 "codec": codec,
31 "bitrate_in_kbps": bitrate_in_kbps,
32 "direct_link": direct_link,
33 },
34 )()
35
36
37@pytest.fixture
38def streaming_manager(
39 streaming_provider_stub: StreamingProviderStub,
40) -> KionMusicStreamingManager:
41 """Create streaming manager with real stub (no Mock)."""
42 return KionMusicStreamingManager(streaming_provider_stub) # type: ignore[arg-type]
43
44
45@pytest.fixture
46def streaming_manager_with_tracking(
47 streaming_provider_stub_with_tracking: StreamingProviderStubWithTracking,
48) -> KionMusicStreamingManager:
49 """Create streaming manager with tracking logger for assertions."""
50 return KionMusicStreamingManager(streaming_provider_stub_with_tracking) # type: ignore[arg-type]
51
52
53def test_select_best_quality_lossless_returns_flac(
54 streaming_manager: KionMusicStreamingManager,
55) -> None:
56 """When preferred_quality is 'lossless' and list has MP3 and FLAC, FLAC is selected."""
57 mp3 = _make_download_info("mp3", 320, "https://example.com/track.mp3")
58 flac = _make_download_info("flac", 0, "https://example.com/track.flac")
59 download_infos = [mp3, flac]
60
61 result = streaming_manager._select_best_quality(download_infos, QUALITY_LOSSLESS)
62
63 assert result is not None
64 assert result.codec == "flac"
65 assert result.direct_link == "https://example.com/track.flac"
66
67
68def test_select_best_quality_high_returns_highest_bitrate(
69 streaming_manager: KionMusicStreamingManager,
70) -> None:
71 """When preferred is 'high' and list has MP3 and FLAC, highest bitrate is selected."""
72 mp3 = _make_download_info("mp3", 320, "https://example.com/track.mp3")
73 flac = _make_download_info("flac", 0, "https://example.com/track.flac")
74 download_infos = [mp3, flac]
75
76 result = streaming_manager._select_best_quality(download_infos, QUALITY_HIGH)
77
78 assert result is not None
79 assert result.codec == "mp3"
80 assert result.bitrate_in_kbps == 320
81
82
83def test_select_best_quality_label_lossless_flac_returns_flac(
84 streaming_manager: KionMusicStreamingManager,
85) -> None:
86 """When preferred_quality is UI label 'Lossless (FLAC)', FLAC is selected."""
87 mp3 = _make_download_info("mp3", 320, "https://example.com/track.mp3")
88 flac = _make_download_info("flac", 0, "https://example.com/track.flac")
89 download_infos = [mp3, flac]
90
91 result = streaming_manager._select_best_quality(download_infos, "Lossless (FLAC)")
92
93 assert result is not None
94 assert result.codec == "flac"
95
96
97def test_select_best_quality_lossless_no_flac_returns_fallback(
98 streaming_manager_with_tracking: KionMusicStreamingManager,
99) -> None:
100 """When lossless requested but no FLAC in list, returns best available (fallback)."""
101 mp3 = _make_download_info("mp3", 320, "https://example.com/track.mp3")
102 download_infos = [mp3]
103
104 result = streaming_manager_with_tracking._select_best_quality(download_infos, QUALITY_LOSSLESS)
105
106 assert result is not None
107 assert result.codec == "mp3"
108 assert streaming_manager_with_tracking.provider.logger._warning_count == 1 # type: ignore[attr-defined]
109
110
111def test_select_best_quality_empty_list_returns_none(
112 streaming_manager: KionMusicStreamingManager,
113) -> None:
114 """Empty download_infos returns None."""
115 result = streaming_manager._select_best_quality([], QUALITY_LOSSLESS)
116 assert result is None
117
118
119def test_select_best_quality_none_preferred_returns_highest_bitrate(
120 streaming_manager: KionMusicStreamingManager,
121) -> None:
122 """When preferred_quality is None, returns highest bitrate."""
123 mp3 = _make_download_info("mp3", 320, "https://example.com/track.mp3")
124 flac = _make_download_info("flac", 0, "https://example.com/track.flac")
125 download_infos = [mp3, flac]
126
127 result = streaming_manager._select_best_quality(download_infos, None)
128
129 assert result is not None
130 assert result.codec == "mp3"
131 assert result.bitrate_in_kbps == 320
132
133
134def test_get_content_type_flac_mp4_returns_flac(
135 streaming_manager: KionMusicStreamingManager,
136) -> None:
137 """flac-mp4 codec from get-file-info is mapped to ContentType.FLAC."""
138 assert streaming_manager._get_content_type("flac-mp4") == ContentType.FLAC
139 assert streaming_manager._get_content_type("FLAC-MP4") == ContentType.FLAC
140