Files
MoviePilot/tests/test_navidrome_module.py

145 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Navidrome 媒体服务器模块接入测试。"""
from unittest.mock import Mock
from app import schemas
from app.core.module import ModuleManager
from app.core.context import MusicInfo
from app.modules.navidrome import NavidromeModule
from app.modules.navidrome.navidrome import Navidrome
from app.schemas.types import MediaServerType, ModuleType
def test_navidrome_module_declares_media_server_identity():
"""Navidrome 应以媒体服务器身份注册,供统一媒体服务器链调用。"""
assert NavidromeModule.get_name() == "Navidrome"
assert NavidromeModule.get_type() == ModuleType.MediaServer
assert NavidromeModule.get_subtype() == MediaServerType.Navidrome
def test_navidrome_module_has_no_system_switch():
"""Navidrome 由服务配置控制启用,不能返回无效的系统开关名。"""
assert NavidromeModule().init_setting() is None
def test_navidrome_module_is_loaded_by_module_manager():
"""模块管理器应能加载 Navidrome否则媒体服务器列表里不会出现该类型。"""
assert "NavidromeModule" in ModuleManager()._running_modules
def test_navidrome_module_ignores_non_music_media():
"""Navidrome 只管理音乐,影视存在性检查应交给其它媒体服务器。"""
from app.core.context import MediaInfo
from app.schemas.types import MediaType
mediainfo = MediaInfo()
mediainfo.type = MediaType.MOVIE
assert NavidromeModule().media_exists(mediainfo) is None
def test_navidrome_refresh_requests_incremental_scan(monkeypatch):
"""音乐入库完成后应通过 Subsonic startScan 触发 Navidrome 增量扫描。"""
client = object.__new__(Navidrome)
requested = []
def fake_call(method, **kwargs):
"""记录媒体库刷新使用的 Subsonic 方法和参数。"""
requested.append((method, kwargs))
return {"status": "ok"}
monkeypatch.setattr(client, "_call", fake_call)
assert client.refresh_root_library() is True
assert requested == [("startScan", {"fullScan": False})]
def test_navidrome_search_filters_exact_album_and_song(monkeypatch):
"""Navidrome 模糊搜索结果必须按实体名称和艺术家精确过滤。"""
client = object.__new__(Navidrome)
monkeypatch.setattr(
client,
"_call",
lambda *_args, **_kwargs: {
"searchResult3": {
"album": [
{"id": "wrong", "name": "叶惠美 演唱会", "artist": "周杰伦", "songCount": 12},
{"id": "album-1", "name": "叶惠美", "artist": "周杰伦", "songCount": 11},
],
"song": [
{"id": "song-wrong", "title": "晴天 Live", "artist": "周杰伦"},
{"id": "song-1", "title": "晴天", "artist": "周杰伦"},
],
}
},
)
albums = client.search_music(album="叶惠美", artist="周杰伦")
songs = client.search_music(title="晴天", artist="周杰伦")
assert [item.item_id for item in albums] == ["album-1"]
assert albums[0].note["song_count"] == 11
assert [item.item_id for item in songs] == ["song-1"]
assert songs[0].title == "晴天"
def test_navidrome_now_playing_uses_song_title_instead_of_album(monkeypatch):
"""正在播放接口返回单曲时,仪表盘标题必须显示曲名而不是所属专辑名。"""
client = object.__new__(Navidrome)
client._play_host = "https://music.example.com"
monkeypatch.setattr(
client,
"_call",
lambda *_args, **_kwargs: {
"nowPlaying": {
"entry": [
{
"id": "song-1",
"title": "晴天",
"album": "叶惠美",
"artist": "周杰伦",
"coverArt": "cover-1",
}
]
}
},
)
monkeypatch.setattr(client, "_album_cover", lambda _item: "cover-url")
items = client.get_resume()
assert len(items) == 1
assert items[0].item_id == "song-1"
assert items[0].title == "晴天"
assert items[0].subtitle == "周杰伦"
assert items[0].image == "cover-url"
def test_navidrome_album_exists_requires_complete_track_count(monkeypatch):
"""同名专辑曲目不足时不得把整专订阅判定为已完整入库。"""
module = NavidromeModule()
service = Mock()
service.get_iteminfo.return_value = schemas.MediaServerItem(
item_id="album-1",
title="叶惠美",
item_type="音乐",
note={"artist": "周杰伦", "song_count": 10},
)
service.search_music.return_value = []
monkeypatch.setattr(module, "get_instances", lambda: {"music": service})
album = MusicInfo(
media_source="musicbrainz",
media_id="release-group-1",
music_type="album",
title="叶惠美",
artists=["周杰伦"],
total_tracks=11,
)
assert module.media_exists(album, itemid="album-1") is None
service.get_iteminfo.return_value.note["song_count"] = 11
exists = module.media_exists(album, itemid="album-1")
assert exists is not None
assert exists.itemid == "album-1"