mirror of
https://github.com/beetbox/beets.git
synced 2026-02-09 00:41:57 +01:00
284 lines
9 KiB
Python
284 lines
9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from copy import deepcopy
|
|
from typing import TYPE_CHECKING
|
|
|
|
import pytest
|
|
|
|
from beets.autotag import AlbumMatch
|
|
from beets.autotag.distance import Distance
|
|
from beets.autotag.hooks import AlbumInfo, TrackInfo
|
|
from beets.library import Item
|
|
from beets.test.helper import PluginMixin
|
|
from beetsplug.musicbrainz import MusicBrainzPlugin, PseudoAlbumInfo
|
|
|
|
if TYPE_CHECKING:
|
|
import pathlib
|
|
|
|
from beetsplug._typing import JSONDict
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def rsrc_dir(pytestconfig: pytest.Config):
|
|
return pytestconfig.rootpath / "test" / "rsrc" / "musicbrainz"
|
|
|
|
|
|
@pytest.fixture
|
|
def official_release(rsrc_dir: pathlib.Path) -> JSONDict:
|
|
info_json = (rsrc_dir / "official_release.json").read_text(encoding="utf-8")
|
|
return json.loads(info_json)
|
|
|
|
|
|
@pytest.fixture
|
|
def pseudo_release(rsrc_dir: pathlib.Path) -> JSONDict:
|
|
info_json = (rsrc_dir / "pseudo_release.json").read_text(encoding="utf-8")
|
|
return json.loads(info_json)
|
|
|
|
|
|
@pytest.fixture
|
|
def official_release_info() -> AlbumInfo:
|
|
return AlbumInfo(
|
|
tracks=[TrackInfo(title="百花繚乱")],
|
|
album_id="official",
|
|
album="百花繚乱",
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def pseudo_release_info() -> AlbumInfo:
|
|
return AlbumInfo(
|
|
tracks=[TrackInfo(title="In Bloom")],
|
|
album_id="pseudo",
|
|
album="In Bloom",
|
|
)
|
|
|
|
|
|
@pytest.mark.usefixtures("config")
|
|
class TestPseudoAlbumInfo:
|
|
def test_album_id_always_from_pseudo(
|
|
self, official_release_info: AlbumInfo, pseudo_release_info: AlbumInfo
|
|
):
|
|
info = PseudoAlbumInfo(pseudo_release_info, official_release_info)
|
|
info.use_official_as_ref()
|
|
assert info.album_id == "pseudo"
|
|
|
|
def test_get_attr_from_pseudo(
|
|
self, official_release_info: AlbumInfo, pseudo_release_info: AlbumInfo
|
|
):
|
|
info = PseudoAlbumInfo(pseudo_release_info, official_release_info)
|
|
info.use_pseudo_as_ref()
|
|
assert info.album == "In Bloom"
|
|
|
|
def test_get_attr_from_official(
|
|
self, official_release_info: AlbumInfo, pseudo_release_info: AlbumInfo
|
|
):
|
|
info = PseudoAlbumInfo(pseudo_release_info, official_release_info)
|
|
info.use_official_as_ref()
|
|
assert info.album == info.get_official_release().album
|
|
|
|
def test_determine_best_ref(
|
|
self, official_release_info: AlbumInfo, pseudo_release_info: AlbumInfo
|
|
):
|
|
info = PseudoAlbumInfo(
|
|
pseudo_release_info, official_release_info, data_source="test"
|
|
)
|
|
item = Item(title="百花繚乱")
|
|
|
|
assert info.determine_best_ref([item]) == "official"
|
|
|
|
info.use_pseudo_as_ref()
|
|
assert info.data_source == "test"
|
|
|
|
|
|
class TestMBPseudoMixin(PluginMixin):
|
|
plugin = "musicbrainz"
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def patch_get_release(
|
|
self,
|
|
monkeypatch,
|
|
official_release: JSONDict,
|
|
pseudo_release: JSONDict,
|
|
):
|
|
def mock_get_release(_, album_id: str, **kwargs):
|
|
if album_id == official_release["id"]:
|
|
return deepcopy(official_release)
|
|
else:
|
|
return deepcopy(pseudo_release)
|
|
|
|
monkeypatch.setattr(
|
|
"beetsplug._utils.musicbrainz.MusicBrainzAPI.get_release",
|
|
mock_get_release,
|
|
)
|
|
|
|
@pytest.fixture(scope="class")
|
|
def plugin_config(self):
|
|
return {"pseudo_releases": {"scripts": ["Latn", "Dummy"]}}
|
|
|
|
@pytest.fixture
|
|
def musicbrainz_plugin(self, plugin_config) -> MusicBrainzPlugin:
|
|
self.config[self.plugin].set(plugin_config)
|
|
return MusicBrainzPlugin()
|
|
|
|
@staticmethod
|
|
def get_album_info(
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
raw: JSONDict,
|
|
) -> AlbumInfo:
|
|
if info := musicbrainz_plugin.album_for_id(raw["id"]):
|
|
return info
|
|
else:
|
|
raise AssertionError("AlbumInfo is None")
|
|
|
|
|
|
class TestMBPseudoReleases(TestMBPseudoMixin):
|
|
def test_scripts_init(self, musicbrainz_plugin: MusicBrainzPlugin):
|
|
assert musicbrainz_plugin._scripts == ["Latn", "Dummy"]
|
|
|
|
def test_album_info_for_pseudo_release(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
pseudo_release: JSONDict,
|
|
):
|
|
album_info = self.get_album_info(musicbrainz_plugin, pseudo_release)
|
|
assert isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
assert album_info.albumstatus == "Official"
|
|
|
|
@pytest.mark.parametrize(
|
|
"json_key",
|
|
[
|
|
"type",
|
|
"direction",
|
|
"release",
|
|
],
|
|
)
|
|
def test_interception_skip_when_rel_values_dont_match(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
json_key: str,
|
|
):
|
|
for r in official_release["release-relations"]:
|
|
del r[json_key]
|
|
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert not isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
|
|
def test_interception_skip_when_script_doesnt_match(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
):
|
|
for r in official_release["release-relations"]:
|
|
r["release"]["text-representation"]["script"] = "Null"
|
|
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert not isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
|
|
def test_interception_skip_when_relations_missing(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
):
|
|
del official_release["release-relations"]
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert not isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
|
|
def test_interception(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
):
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
|
|
def test_final_adjustment_skip(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
):
|
|
match = AlbumMatch(
|
|
distance=Distance(),
|
|
info=AlbumInfo(tracks=[], data_source="mb"),
|
|
mapping={},
|
|
extra_items=[],
|
|
extra_tracks=[],
|
|
)
|
|
musicbrainz_plugin._adjust_final_album_match(match)
|
|
|
|
def test_final_adjustment(
|
|
self,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release_info: AlbumInfo,
|
|
pseudo_release_info: AlbumInfo,
|
|
):
|
|
pseudo_album_info = PseudoAlbumInfo(
|
|
pseudo_release=pseudo_release_info,
|
|
official_release=official_release_info,
|
|
data_source=musicbrainz_plugin.data_source,
|
|
)
|
|
pseudo_album_info.use_official_as_ref()
|
|
|
|
item = Item()
|
|
item["title"] = "百花繚乱"
|
|
|
|
match = AlbumMatch(
|
|
distance=Distance(),
|
|
info=pseudo_album_info,
|
|
mapping={item: pseudo_album_info.tracks[0]},
|
|
extra_items=[],
|
|
extra_tracks=[],
|
|
)
|
|
|
|
musicbrainz_plugin._adjust_final_album_match(match)
|
|
|
|
assert match.info.data_source == "MusicBrainz"
|
|
assert match.info.album_id == "pseudo"
|
|
assert match.info.album == "In Bloom"
|
|
|
|
|
|
class TestMBPseudoReleasesCustomTagsOnly(TestMBPseudoMixin):
|
|
@pytest.fixture(scope="class")
|
|
def plugin_config(self):
|
|
return {
|
|
"pseudo_releases": {
|
|
"scripts": ["Latn", "Dummy"],
|
|
"custom_tags_only": True,
|
|
}
|
|
}
|
|
|
|
def test_custom_tags(
|
|
self,
|
|
config,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
):
|
|
config["import"]["languages"] = []
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert not isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
assert album_info["album_transl"] == "In Bloom"
|
|
assert album_info["album_artist_transl"] == "Lilas Ikuta"
|
|
assert album_info.tracks[0]["title_transl"] == "In Bloom"
|
|
assert album_info.tracks[0]["artist_transl"] == "Lilas Ikuta"
|
|
|
|
def test_custom_tags_with_import_languages(
|
|
self,
|
|
config,
|
|
musicbrainz_plugin: MusicBrainzPlugin,
|
|
official_release: JSONDict,
|
|
):
|
|
config["import"]["languages"] = []
|
|
config["import"]["languages"] = ["en", "jp"]
|
|
album_info = self.get_album_info(musicbrainz_plugin, official_release)
|
|
assert not isinstance(album_info, PseudoAlbumInfo)
|
|
assert album_info.data_source == "MusicBrainz"
|
|
assert album_info["album_transl"] == "In Bloom"
|
|
assert album_info["album_artist_transl"] == "Lilas Ikuta"
|
|
assert album_info.tracks[0]["title_transl"] == "In Bloom"
|
|
assert album_info.tracks[0]["artist_transl"] == "Lilas Ikuta"
|