- Extract the import pipeline, album import, staging, path, file ops, guards, runtime state, side effects, and metadata enrichment out of . - Canonicalize the refactored import path around and remove legacy , , , and request shapes from the import endpoints. - Make album and track metadata lookups follow the configured provider priority instead of hard-coding Spotify, while still falling back when needed. - Update the import routes and frontend payloads to use the new core helpers. - Add coverage for the extracted helpers and the refactored import flows. PS. apologies to anyone who might check this commit out - the intention was to start small, but things kinda snowballed out of control at some point since the logic just kept going on and on, and everything kinda had to be changed all at once for it all to make any sense
193 lines
7.8 KiB
Python
193 lines
7.8 KiB
Python
from types import SimpleNamespace
|
|
|
|
from core import metadata_service
|
|
|
|
|
|
class FakeClient:
|
|
def __init__(self, search_results=None, details=None, artist_details=None):
|
|
self.search_results = search_results or []
|
|
self.details = details or {}
|
|
self.artist_details = artist_details or {}
|
|
self.calls = []
|
|
|
|
def search_tracks(self, query, limit=1, allow_fallback=True):
|
|
self.calls.append(("search_tracks", query, limit, allow_fallback))
|
|
return self.search_results
|
|
|
|
def get_track_details(self, track_id):
|
|
self.calls.append(("get_track_details", track_id))
|
|
return self.details.get(str(track_id))
|
|
|
|
def get_artist(self, artist_id):
|
|
self.calls.append(("get_artist", artist_id))
|
|
return self.artist_details.get(str(artist_id))
|
|
|
|
|
|
def _track_result(track_id="track-1", name="Song One", artist="Artist One"):
|
|
return SimpleNamespace(
|
|
id=track_id,
|
|
name=name,
|
|
artists=[artist],
|
|
album="Album One",
|
|
duration_ms=123000,
|
|
track_number=1,
|
|
disc_number=1,
|
|
image_url="https://img.example/track.jpg",
|
|
)
|
|
|
|
|
|
def _track_details(source, track_id="track-1", name="Song One", artist_name="Artist One", artist_id="artist-1"):
|
|
return {
|
|
"id": track_id,
|
|
"name": name,
|
|
"track_number": 7,
|
|
"disc_number": 1,
|
|
"duration_ms": 210000,
|
|
"explicit": True,
|
|
"uri": f"{source}:track:{track_id}",
|
|
"artists": [{"name": artist_name, "id": artist_id}],
|
|
"album": {
|
|
"id": f"{source}-album-1",
|
|
"name": "Album One",
|
|
"release_date": "2024-01-01",
|
|
"album_type": "album",
|
|
"total_tracks": 10,
|
|
"images": [{"url": f"https://img.example/{source}-album.jpg"}],
|
|
"artists": [{"name": artist_name, "id": artist_id}],
|
|
},
|
|
}
|
|
|
|
|
|
def test_get_single_track_import_context_uses_primary_source_priority(monkeypatch):
|
|
deezer_client = FakeClient(
|
|
search_results=[_track_result(track_id="deezer-track-1")],
|
|
details={"deezer-track-1": _track_details("deezer", track_id="deezer-track-1", artist_name="Artist One", artist_id="deezer-artist-1")},
|
|
artist_details={"deezer-artist-1": {"id": "deezer-artist-1", "genres": ["electronic"]}},
|
|
)
|
|
spotify_client = FakeClient()
|
|
|
|
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "deezer")
|
|
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "spotify", "itunes"])
|
|
monkeypatch.setattr(
|
|
metadata_service,
|
|
"get_client_for_source",
|
|
lambda source: {"deezer": deezer_client, "spotify": spotify_client, "itunes": None}.get(source),
|
|
)
|
|
|
|
result = metadata_service.get_single_track_import_context("Song One", "Artist One")
|
|
|
|
assert result["success"] is True
|
|
assert result["source"] == "deezer"
|
|
assert result["source_priority"] == ["deezer", "spotify", "itunes"]
|
|
assert result["context"]["track_info"]["name"] == "Song One"
|
|
assert result["context"]["track_info"]["album_id"] == "deezer-album-1"
|
|
assert result["context"]["album"]["image_url"] == "https://img.example/deezer-album.jpg"
|
|
assert result["context"]["artist"]["genres"] == ["electronic"]
|
|
assert result["context"]["original_search_result"]["clean_title"] == "Song One"
|
|
assert deezer_client.calls == [
|
|
('search_tracks', 'artist:"Artist One" track:"Song One"', 5, True),
|
|
("get_track_details", "deezer-track-1"),
|
|
("get_artist", "deezer-artist-1"),
|
|
]
|
|
assert spotify_client.calls == []
|
|
|
|
|
|
def test_get_single_track_import_context_falls_back_to_next_source(monkeypatch):
|
|
deezer_client = FakeClient(search_results=[])
|
|
spotify_client = FakeClient(
|
|
search_results=[_track_result(track_id="spotify-track-1")],
|
|
details={"spotify-track-1": _track_details("spotify", track_id="spotify-track-1", artist_name="Artist Two", artist_id="spotify-artist-1")},
|
|
artist_details={"spotify-artist-1": {"id": "spotify-artist-1", "genres": ["indie"]}},
|
|
)
|
|
|
|
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "deezer")
|
|
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "spotify", "itunes"])
|
|
monkeypatch.setattr(
|
|
metadata_service,
|
|
"get_client_for_source",
|
|
lambda source: {"deezer": deezer_client, "spotify": spotify_client, "itunes": None}.get(source),
|
|
)
|
|
|
|
result = metadata_service.get_single_track_import_context("Song Two", "Artist Two")
|
|
|
|
assert result["success"] is True
|
|
assert result["source"] == "spotify"
|
|
assert result["context"]["track_info"]["id"] == "spotify-track-1"
|
|
assert result["context"]["album"]["name"] == "Album One"
|
|
assert deezer_client.calls == [
|
|
('search_tracks', 'artist:"Artist Two" track:"Song Two"', 5, True),
|
|
('search_tracks', 'Song Two', 5, True),
|
|
('search_tracks', 'Artist Two', 5, True),
|
|
]
|
|
assert spotify_client.calls == [
|
|
("search_tracks", "Song Two Artist Two", 5, False),
|
|
("get_track_details", "spotify-track-1"),
|
|
("get_artist", "spotify-artist-1"),
|
|
]
|
|
|
|
|
|
def test_get_single_track_import_context_uses_explicit_override_first(monkeypatch):
|
|
spotify_client = FakeClient(
|
|
details={"override-track-1": _track_details("spotify", track_id="override-track-1", artist_name="Override Artist", artist_id="spotify-artist-1")},
|
|
artist_details={"spotify-artist-1": {"id": "spotify-artist-1", "genres": ["pop"]}},
|
|
)
|
|
deezer_client = FakeClient()
|
|
|
|
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "deezer")
|
|
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "spotify", "itunes"])
|
|
monkeypatch.setattr(
|
|
metadata_service,
|
|
"get_client_for_source",
|
|
lambda source: {"deezer": deezer_client, "spotify": spotify_client, "itunes": None}.get(source),
|
|
)
|
|
|
|
result = metadata_service.get_single_track_import_context(
|
|
"Ignored Title",
|
|
"Ignored Artist",
|
|
override_id="override-track-1",
|
|
)
|
|
|
|
assert result["success"] is True
|
|
assert result["source"] == "spotify"
|
|
assert result["context"]["track_info"]["id"] == "override-track-1"
|
|
assert result["context"]["artist"]["genres"] == ["pop"]
|
|
assert spotify_client.calls == [
|
|
("get_track_details", "override-track-1"),
|
|
("get_artist", "spotify-artist-1"),
|
|
]
|
|
assert deezer_client.calls == []
|
|
|
|
|
|
def test_get_single_track_import_context_uses_explicit_override_source(monkeypatch):
|
|
itunes_client = FakeClient(
|
|
details={"override-track-2": _track_details("itunes", track_id="override-track-2", artist_name="Override Artist Two", artist_id="itunes-artist-1")},
|
|
artist_details={"itunes-artist-1": {"id": "itunes-artist-1", "genres": ["singer-songwriter"]}},
|
|
)
|
|
spotify_client = FakeClient()
|
|
deezer_client = FakeClient()
|
|
|
|
monkeypatch.setattr(metadata_service, "get_primary_source", lambda: "deezer")
|
|
monkeypatch.setattr(metadata_service, "get_source_priority", lambda primary: [primary, "spotify", "itunes"])
|
|
monkeypatch.setattr(
|
|
metadata_service,
|
|
"get_client_for_source",
|
|
lambda source: {"deezer": deezer_client, "spotify": spotify_client, "itunes": itunes_client}.get(source),
|
|
)
|
|
|
|
result = metadata_service.get_single_track_import_context(
|
|
"Ignored Title",
|
|
"Ignored Artist",
|
|
override_id="override-track-2",
|
|
override_source="itunes",
|
|
)
|
|
|
|
assert result["success"] is True
|
|
assert result["source"] == "itunes"
|
|
assert result["context"]["track_info"]["id"] == "override-track-2"
|
|
assert result["context"]["artist"]["genres"] == ["singer-songwriter"]
|
|
assert itunes_client.calls == [
|
|
("get_track_details", "override-track-2"),
|
|
("get_artist", "itunes-artist-1"),
|
|
]
|
|
assert deezer_client.calls == []
|
|
assert spotify_client.calls == []
|