138 lines
5.8 KiB
Python
138 lines
5.8 KiB
Python
import pytest
|
|
|
|
from server import actions, mf
|
|
|
|
|
|
def make_yt_hit():
|
|
return mf.Hit(source="youtube", kind="track", title="Together",
|
|
artist="Avril Lavigne", album="Under My Skin", year="2004",
|
|
payload={"videoId": "abc"})
|
|
|
|
|
|
def make_lidarr_album_hit():
|
|
return mf.Hit(source="lidarr", kind="album", title="Under My Skin",
|
|
artist="Avril Lavigne", album="Under My Skin", year="2004",
|
|
payload={"album": {"id": 5, "title": "Under My Skin"}})
|
|
|
|
|
|
def test_started_message_mentions_source_and_title():
|
|
msg = actions.started_message(make_yt_hit())
|
|
assert "Together" in msg
|
|
assert "Avril Lavigne" in msg
|
|
assert "YouTube" in msg
|
|
|
|
|
|
def test_done_message_mentions_title():
|
|
msg = actions.done_message(make_yt_hit())
|
|
assert "Together" in msg
|
|
assert "Avril Lavigne" in msg
|
|
|
|
|
|
def test_messages_use_only_first_artist():
|
|
hit = mf.Hit(source="youtube", kind="track", title="Under My Skin",
|
|
artist="SLVMLORD, James John, BobbyGee", album="X", year="",
|
|
payload={"videoId": "abc"})
|
|
for msg in (actions.started_message(hit), actions.done_message(hit),
|
|
actions.failed_message(hit)):
|
|
assert "SLVMLORD" in msg
|
|
assert "James John" not in msg
|
|
assert "BobbyGee" not in msg
|
|
|
|
|
|
def test_perform_youtube_calls_act_youtube(monkeypatch):
|
|
calls = {}
|
|
monkeypatch.setattr(mf, "act_youtube",
|
|
lambda hit, root, quality, dry_run: calls.update(hit=hit, root=root, quality=quality))
|
|
hit = make_yt_hit()
|
|
result = actions.perform_fetch(hit, [hit], quality="best", root="/media/music")
|
|
assert calls["quality"] == "best"
|
|
assert result["path"] == "/media/music/Avril Lavigne/youtube"
|
|
assert result["lidarr_album_id"] is None
|
|
|
|
|
|
def _release(guid="g1"):
|
|
return {"guid": guid, "indexerId": 2, "title": "Avril-Under_My_Skin",
|
|
"size": 312 * 1024 * 1024, "seeders": 24, "indexer": "Redacted",
|
|
"quality": {"quality": {"name": "FLAC"}}}
|
|
|
|
|
|
@pytest.fixture
|
|
def in_library(monkeypatch):
|
|
"""Lidarr holds the artist and the album."""
|
|
monkeypatch.setattr(mf, "ensure_album", lambda album, root, search_all, dry_run: {
|
|
"album": {"id": 5}, "album_id": 5, "artist_name": "Avril Lavigne",
|
|
"album_title": "Under My Skin", "artist_state": "existing",
|
|
"album_state": "existing"})
|
|
|
|
|
|
def test_perform_lidarr_album_offers_choices_by_default(monkeypatch, in_library):
|
|
monkeypatch.setattr(mf, "list_releases", lambda album_id, **kw: [_release("a"), _release("b")])
|
|
monkeypatch.setattr(mf, "grab_release", lambda *a, **kw: (_ for _ in ()).throw(
|
|
AssertionError("must not grab before the user picks")))
|
|
hit = make_lidarr_album_hit()
|
|
result = actions.perform_fetch(hit, [hit], quality="best", root="/media/music")
|
|
assert result["outcome"] == "choices"
|
|
assert [c["n"] for c in result["choices"]] == [1, 2]
|
|
assert result["pending"] == [_release("a"), _release("b")]
|
|
assert result["lidarr_album_id"] == 5
|
|
|
|
|
|
def test_perform_lidarr_album_auto_grabs_the_best_release(monkeypatch, in_library):
|
|
grabbed = {}
|
|
monkeypatch.setattr(mf, "list_releases", lambda album_id, **kw: [_release("best"), _release("b")])
|
|
monkeypatch.setattr(mf, "grab_release",
|
|
lambda rel, dry_run=False: grabbed.update(guid=rel["guid"]) or True)
|
|
hit = make_lidarr_album_hit()
|
|
result = actions.perform_fetch(hit, [hit], quality="best", root="/media/music", auto=True)
|
|
assert result["outcome"] == "album_grabbed"
|
|
assert grabbed["guid"] == "best"
|
|
assert not result.get("choices")
|
|
|
|
|
|
def test_perform_lidarr_album_fallsthrough_to_youtube(monkeypatch, in_library):
|
|
monkeypatch.setattr(mf, "list_releases", lambda album_id, **kw: [])
|
|
yt_calls = {}
|
|
monkeypatch.setattr(mf, "act_youtube",
|
|
lambda hit, root, quality, dry_run: yt_calls.update(hit=hit))
|
|
lidarr_hit = make_lidarr_album_hit()
|
|
yt_hit = make_yt_hit()
|
|
result = actions.perform_fetch(lidarr_hit, [lidarr_hit, yt_hit],
|
|
quality="best", root="/media/music")
|
|
assert yt_calls["hit"] is yt_hit
|
|
assert result["outcome"] == "youtube_fallback"
|
|
assert result["path"] == "/media/music/Avril Lavigne/youtube"
|
|
|
|
|
|
def test_perform_lidarr_album_reports_no_release_without_a_fallback(monkeypatch, in_library):
|
|
monkeypatch.setattr(mf, "list_releases", lambda album_id, **kw: [])
|
|
hit = make_lidarr_album_hit()
|
|
result = actions.perform_fetch(hit, [hit], quality="best", root="/media/music")
|
|
assert result["outcome"] == "no_release"
|
|
|
|
|
|
def test_perform_lidarr_album_skips_youtube_when_not_allowed(monkeypatch, in_library):
|
|
monkeypatch.setattr(mf, "list_releases", lambda album_id, **kw: [])
|
|
monkeypatch.setattr(mf, "act_youtube", lambda *a, **kw: (_ for _ in ()).throw(
|
|
AssertionError("source=lidarr must not use YouTube")))
|
|
lidarr_hit = make_lidarr_album_hit()
|
|
result = actions.perform_fetch(lidarr_hit, [lidarr_hit, make_yt_hit()],
|
|
quality="best", root="/media/music",
|
|
allow_youtube=False)
|
|
assert result["outcome"] == "no_release"
|
|
|
|
|
|
def test_perform_lidarr_album_raises_when_the_album_is_not_in_lidarr(monkeypatch):
|
|
monkeypatch.setattr(mf, "ensure_album", lambda album, root, search_all, dry_run: {
|
|
"album": None, "album_id": None, "artist_name": "Avril Lavigne",
|
|
"album_title": "Under My Skin", "artist_state": "existing",
|
|
"album_state": "missing"})
|
|
hit = make_lidarr_album_hit()
|
|
with pytest.raises(RuntimeError, match="no album called"):
|
|
actions.perform_fetch(hit, [hit], quality="best", root="/media/music")
|
|
|
|
|
|
def test_failed_message_mentions_title_and_artist():
|
|
msg = actions.failed_message(make_yt_hit())
|
|
assert "Together" in msg
|
|
assert "Avril Lavigne" in msg
|