146 lines
5.7 KiB
Python
146 lines
5.7 KiB
Python
import server.mf # noqa: F401 — loads musicfetch, registers musicfetch_core
|
|
import musicfetch_core as mf
|
|
|
|
|
|
class _FakeResp:
|
|
def __init__(self, status, payload):
|
|
self.status_code = status
|
|
self._payload = payload
|
|
|
|
def json(self):
|
|
return self._payload
|
|
|
|
|
|
FULL = {
|
|
"entityUniqueId": "SPOTIFY_SONG::abc",
|
|
"entitiesByUniqueId": {
|
|
"SPOTIFY_SONG::abc": {
|
|
"title": "Bloom",
|
|
"artistName": "ODESZA",
|
|
"thumbnailUrl": "https://img/cover.jpg",
|
|
}
|
|
},
|
|
"linksByPlatform": {
|
|
"youtubeMusic": {"url": "https://music.youtube.com/watch?v=YYY"},
|
|
"youtube": {"url": "https://youtube.com/watch?v=YYY"},
|
|
},
|
|
}
|
|
|
|
|
|
def test_odesli_resolve_full(monkeypatch):
|
|
monkeypatch.setattr(mf.requests, "get", lambda *a, **k: _FakeResp(200, FULL))
|
|
r = mf.odesli_resolve("https://open.spotify.com/track/abc")
|
|
assert r.title == "Bloom"
|
|
assert r.artist == "ODESZA"
|
|
assert r.thumb == "https://img/cover.jpg"
|
|
assert r.youtube_url == "https://music.youtube.com/watch?v=YYY"
|
|
|
|
|
|
def test_odesli_resolve_prefers_ytmusic_then_youtube(monkeypatch):
|
|
payload = {**FULL, "linksByPlatform": {"youtube": {"url": "https://youtube.com/watch?v=ZZZ"}}}
|
|
monkeypatch.setattr(mf.requests, "get", lambda *a, **k: _FakeResp(200, payload))
|
|
r = mf.odesli_resolve("https://open.spotify.com/track/abc")
|
|
assert r.youtube_url == "https://youtube.com/watch?v=ZZZ"
|
|
|
|
|
|
def test_odesli_resolve_no_youtube_link(monkeypatch):
|
|
payload = {**FULL, "linksByPlatform": {}}
|
|
monkeypatch.setattr(mf.requests, "get", lambda *a, **k: _FakeResp(200, payload))
|
|
r = mf.odesli_resolve("https://open.spotify.com/track/abc")
|
|
assert r.youtube_url == ""
|
|
assert r.title == "Bloom"
|
|
|
|
|
|
def test_odesli_resolve_non_200_returns_none(monkeypatch):
|
|
monkeypatch.setattr(mf.requests, "get", lambda *a, **k: _FakeResp(429, {}))
|
|
assert mf.odesli_resolve("https://open.spotify.com/track/abc") is None
|
|
|
|
|
|
def test_odesli_resolve_malformed_returns_none(monkeypatch):
|
|
monkeypatch.setattr(mf.requests, "get", lambda *a, **k: _FakeResp(200, {"nope": 1}))
|
|
assert mf.odesli_resolve("https://open.spotify.com/track/abc") is None
|
|
|
|
|
|
def test_odesli_resolve_network_error_returns_none(monkeypatch):
|
|
def boom(*a, **k):
|
|
raise mf.RequestException("down")
|
|
monkeypatch.setattr(mf.requests, "get", boom)
|
|
assert mf.odesli_resolve("https://open.spotify.com/track/abc") is None
|
|
|
|
|
|
def test_is_direct_url_youtube():
|
|
assert mf._is_direct_url("https://music.youtube.com/watch?v=abc")
|
|
assert mf._is_direct_url("https://www.youtube.com/watch?v=abc")
|
|
assert mf._is_direct_url("https://youtu.be/abc")
|
|
|
|
|
|
def test_is_direct_url_soundcloud():
|
|
assert mf._is_direct_url("https://soundcloud.com/dj/track")
|
|
|
|
|
|
def test_is_direct_url_other_platforms_false():
|
|
assert not mf._is_direct_url("https://open.spotify.com/track/abc")
|
|
assert not mf._is_direct_url("https://music.apple.com/us/album/x/1?i=2")
|
|
assert not mf._is_direct_url("https://tidal.com/browse/track/123")
|
|
|
|
|
|
def test_is_direct_url_youtube_playlist_true():
|
|
assert mf._is_direct_url("https://www.youtube.com/playlist?list=PLabc")
|
|
|
|
|
|
def _resolved(yt="https://music.youtube.com/watch?v=YYY"):
|
|
return mf.Resolved(title="Bloom", artist="ODESZA",
|
|
thumb="https://img/cover.jpg", youtube_url=yt)
|
|
|
|
|
|
def test_resolve_link_hits_builds_query_and_exact_yt(monkeypatch):
|
|
monkeypatch.setattr(mf, "odesli_resolve", lambda url: _resolved())
|
|
lid = mf.Hit(source="lidarr", kind="album", title="A Moment Apart",
|
|
artist="ODESZA", album="A Moment Apart", year="2017",
|
|
payload={"album": {"id": 9}})
|
|
monkeypatch.setattr(mf, "lidarr_search", lambda q, limit: [lid])
|
|
query, hits = mf.resolve_link_hits("https://open.spotify.com/track/abc", 10)
|
|
assert query == "ODESZA - Bloom"
|
|
assert hits[0].source == "lidarr"
|
|
yt = hits[-1]
|
|
assert yt.source == "youtube" and yt.kind == "track"
|
|
assert yt.title == "Bloom" and yt.artist == "ODESZA"
|
|
assert yt.payload["url"] == "https://music.youtube.com/watch?v=YYY"
|
|
|
|
|
|
def test_resolve_link_hits_no_yt_link_lidarr_only(monkeypatch):
|
|
monkeypatch.setattr(mf, "odesli_resolve", lambda url: _resolved(yt=""))
|
|
lid = mf.Hit(source="lidarr", kind="album", title="X", artist="ODESZA",
|
|
payload={"album": {"id": 9}})
|
|
monkeypatch.setattr(mf, "lidarr_search", lambda q, limit: [lid])
|
|
query, hits = mf.resolve_link_hits("https://open.spotify.com/track/abc", 10)
|
|
assert all(h.source == "lidarr" for h in hits)
|
|
|
|
|
|
def test_resolve_link_hits_odesli_miss_raises(monkeypatch):
|
|
import pytest
|
|
monkeypatch.setattr(mf, "odesli_resolve", lambda url: None)
|
|
with pytest.raises(mf.OdesliError):
|
|
mf.resolve_link_hits("https://open.spotify.com/track/abc", 10)
|
|
|
|
|
|
def test_handle_link_miss_prints_and_returns(monkeypatch, capsys):
|
|
monkeypatch.setattr(mf, "odesli_resolve", lambda url: None)
|
|
mf.handle_link("https://open.spotify.com/track/abc", "/m", "best",
|
|
False, True, False, 10)
|
|
out = capsys.readouterr()
|
|
assert "Couldn't resolve" in (out.err + out.out)
|
|
|
|
|
|
def test_handle_link_dispatches_chosen(monkeypatch):
|
|
monkeypatch.setattr(mf, "odesli_resolve", lambda url: _resolved())
|
|
monkeypatch.setattr(mf, "lidarr_search", lambda q, limit: [])
|
|
chosen = {}
|
|
monkeypatch.setattr(mf, "pick", lambda hits, q, ni, yf: hits[0])
|
|
monkeypatch.setattr(mf, "_dispatch_chosen",
|
|
lambda c, hits, root, quality, dry, lo, sa: chosen.update(c=c, root=root))
|
|
mf.handle_link("https://open.spotify.com/track/abc", "/m", "best",
|
|
False, True, False, 10)
|
|
assert chosen["c"].source == "youtube"
|
|
assert chosen["root"] == "/m"
|