soulsync/tests/test_metadata_service_artist_image.py
Broque Thomas 6314827e91 Fix test-order-dependent failures in new metadata_service tests
The _DummyConfigManager stubs in test_metadata_service_musicmap.py and
test_metadata_service_artist_image.py were missing get_active_media_server(),
which the existing test_metadata_service_discography.py dummy provides.

Both files install their dummy via sys.modules["config.settings"] with an
"if not in sys.modules" guard, so whichever test file loads first wins.
When the new files load alphabetically before discography, the limited
dummy persists and later tests hit AttributeError on get_active_media_server.

Adds the same get_active_media_server method to both dummies so all three
test files are equivalent and test ordering no longer affects outcomes.
2026-04-21 11:39:56 -07:00

155 lines
4.8 KiB
Python

import sys
import types
if "spotipy" not in sys.modules:
spotipy = types.ModuleType("spotipy")
class _DummySpotify:
def __init__(self, *args, **kwargs):
pass
oauth2 = types.ModuleType("spotipy.oauth2")
class _DummyOAuth:
def __init__(self, *args, **kwargs):
pass
spotipy.Spotify = _DummySpotify
oauth2.SpotifyOAuth = _DummyOAuth
oauth2.SpotifyClientCredentials = _DummyOAuth
spotipy.oauth2 = oauth2
sys.modules["spotipy"] = spotipy
sys.modules["spotipy.oauth2"] = oauth2
if "config.settings" not in sys.modules:
config_pkg = types.ModuleType("config")
settings_mod = types.ModuleType("config.settings")
class _DummyConfigManager:
def get(self, key, default=None):
return default
def get_active_media_server(self):
return "primary"
settings_mod.config_manager = _DummyConfigManager()
config_pkg.settings = settings_mod
sys.modules["config"] = config_pkg
sys.modules["config.settings"] = settings_mod
from core import metadata_service
class _FakeSpotifyClient:
def __init__(self, image_url="https://spotify.example/artist.jpg"):
self.image_url = image_url
self.calls = []
def is_spotify_authenticated(self):
return True
def get_artist(self, artist_id, allow_fallback=True):
self.calls.append((artist_id, allow_fallback))
return {
"id": artist_id,
"name": "Spotify Artist",
"images": [{"url": self.image_url}],
"genres": ["rock"],
"popularity": 80,
}
class _FakeDeezerClient:
def __init__(self, image_url="https://deezer.example/artist.jpg"):
self.image_url = image_url
self.calls = []
def get_artist(self, artist_id):
self.calls.append(artist_id)
return types.SimpleNamespace(
id=artist_id,
name="Deezer Artist",
image_url=self.image_url,
genres=["indie"],
popularity=0,
)
class _FakeItunesClient:
def __init__(self, album_art_url="https://itunes.example/artist.jpg"):
self.album_art_url = album_art_url
self.calls = []
self.album_art_calls = []
def get_artist(self, artist_id):
self.calls.append(artist_id)
return {
"id": artist_id,
"name": "iTunes Artist",
"images": [],
"genres": ["alt"],
"popularity": 0,
}
def _get_artist_image_from_albums(self, artist_id):
self.album_art_calls.append(artist_id)
return self.album_art_url
def test_get_artist_image_url_uses_primary_source_priority(monkeypatch):
deezer = _FakeDeezerClient()
spotify = _FakeSpotifyClient()
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "deezer")
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "spotify"])
monkeypatch.setattr(
metadata_service,
"get_client_for_source",
lambda source: {"deezer": deezer, "spotify": spotify}.get(source),
)
image_url = metadata_service.get_artist_image_url("artist-1")
assert image_url == "https://deezer.example/artist.jpg"
assert deezer.calls == ["artist-1"]
assert spotify.calls == []
def test_get_artist_image_url_uses_itunes_album_art_for_explicit_override(monkeypatch):
itunes = _FakeItunesClient()
spotify = _FakeSpotifyClient()
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "spotify")
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "itunes"])
monkeypatch.setattr(
metadata_service,
"get_client_for_source",
lambda source: {"itunes": itunes, "spotify": spotify}.get(source),
)
image_url = metadata_service.get_artist_image_url("12345", source_override="itunes")
assert image_url == "https://itunes.example/artist.jpg"
assert itunes.calls == ["12345"]
assert itunes.album_art_calls == ["12345"]
assert spotify.calls == []
def test_get_artist_image_url_handles_hydrabase_plugin(monkeypatch):
deezer = _FakeDeezerClient("https://deezer.example/hydra.jpg")
spotify = _FakeSpotifyClient()
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "spotify")
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "deezer"])
monkeypatch.setattr(
metadata_service,
"get_client_for_source",
lambda source: {"deezer": deezer, "spotify": spotify}.get(source),
)
image_url = metadata_service.get_artist_image_url("artist-1", source_override="hydrabase", plugin="deezer")
assert image_url == "https://deezer.example/hydra.jpg"
assert deezer.calls == ["artist-1"]
assert spotify.calls == []