Files
MoviePilot/tests/test_navidrome_module.py
2026-08-16 16:07:38 +08:00

148 lines
5.3 KiB
Python

"""Navidrome 媒体服务器模块接入测试。"""
from unittest.mock import Mock
from app import schemas
from app.runtime.extensions.module_manager import ModuleManager
from app.domain.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_discovered_without_unconfigured_activation():
"""Navidrome 始终可发现,但没有启用配置时不应创建服务资源。"""
manager = ModuleManager()
assert "NavidromeModule" in manager.get_module_ids()
assert manager.get_running_module("NavidromeModule") is None
def test_navidrome_module_ignores_non_music_media():
"""Navidrome 只管理音乐,影视存在性检查应交给其它媒体服务器。"""
from app.domain.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"