/
/
/
1"""Shared fixtures and stubs for KION Music provider tests."""
2
3from __future__ import annotations
4
5import logging
6from typing import Any
7
8import pytest
9from music_assistant_models.enums import MediaType
10from music_assistant_models.media_items import ItemMapping
11
12
13class ProviderStub:
14 """
15 Minimal provider-like object for parser tests (no Mock).
16
17 Provides the minimal interface needed by parse_* functions.
18 """
19
20 domain = "kion_music"
21 instance_id = "kion_music_instance"
22
23 def __init__(self) -> None:
24 """Initialize stub with minimal client."""
25 self.client = type("ClientStub", (), {"user_id": 12345})()
26
27 def get_item_mapping(self, media_type: MediaType | str, key: str, name: str) -> ItemMapping:
28 """Return ItemMapping for the given media type, key and name."""
29 return ItemMapping(
30 media_type=MediaType(media_type) if isinstance(media_type, str) else media_type,
31 item_id=key,
32 provider=self.instance_id,
33 name=name,
34 )
35
36
37class _StubConfig:
38 """Minimal config stub for streaming tests."""
39
40 def get_value(self, key: str, default: Any = None) -> Any:
41 """Return default value for any key."""
42 return default
43
44
45class StreamingProviderStub:
46 """
47 Minimal provider stub for streaming tests (no Mock).
48
49 Provides the minimal interface needed by KionMusicStreamingManager.
50 """
51
52 domain = "kion_music"
53 instance_id = "kion_music_instance"
54 logger = logging.getLogger("kion_music_test_streaming")
55 config = _StubConfig()
56
57 def __init__(self) -> None:
58 """Initialize stub with minimal client."""
59 self.client = type("ClientStub", (), {"user_id": 12345})()
60 self.mass = type("MassStub", (), {})()
61 self._warning_count = 0
62
63 async def get_track(self, prov_track_id: str) -> None:
64 """Stub â not used by streaming unit tests."""
65 return
66
67 def _count_warning(self, *args: object, **kwargs: object) -> None:
68 """Track warning calls for test assertions."""
69 self._warning_count += 1
70
71
72class TrackingLogger:
73 """Logger that tracks calls for test assertions without using Mock."""
74
75 def __init__(self) -> None:
76 """Initialize with empty call counters."""
77 self._debug_count = 0
78 self._info_count = 0
79 self._warning_count = 0
80 self._error_count = 0
81
82 def debug(self, *args: object, **kwargs: object) -> None:
83 """Track debug calls."""
84 self._debug_count += 1
85
86 def info(self, *args: object, **kwargs: object) -> None:
87 """Track info calls."""
88 self._info_count += 1
89
90 def warning(self, *args: object, **kwargs: object) -> None:
91 """Track warning calls."""
92 self._warning_count += 1
93
94 def error(self, *args: object, **kwargs: object) -> None:
95 """Track error calls."""
96 self._error_count += 1
97
98
99class StreamingProviderStubWithTracking:
100 """
101 Provider stub with tracking logger for assertions.
102
103 Use this when you need to verify logging behavior.
104 """
105
106 domain = "kion_music"
107 instance_id = "kion_music_instance"
108 config = _StubConfig()
109
110 def __init__(self) -> None:
111 """Initialize stub with tracking logger."""
112 self.client = type("ClientStub", (), {"user_id": 12345})()
113 self.mass = type("MassStub", (), {})()
114 self.logger = TrackingLogger()
115
116 async def get_track(self, prov_track_id: str) -> None:
117 """Stub â not used by streaming unit tests."""
118 return
119
120
121# Minimal client-like object for kion_music de_json (library requires client, not None)
122DE_JSON_CLIENT = type("ClientStub", (), {"report_unknown_fields": False})()
123
124
125@pytest.fixture
126def provider_stub() -> ProviderStub:
127 """Return a real provider stub (no Mock)."""
128 return ProviderStub()
129
130
131@pytest.fixture
132def streaming_provider_stub() -> StreamingProviderStub:
133 """Return a streaming provider stub (no Mock)."""
134 return StreamingProviderStub()
135
136
137@pytest.fixture
138def streaming_provider_stub_with_tracking() -> StreamingProviderStubWithTracking:
139 """Return a streaming provider stub with tracking logger."""
140 return StreamingProviderStubWithTracking()
141