Files
musicfetch/tests/test_actions.py

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