mirror of
https://github.com/beetbox/beets.git
synced 2026-07-16 14:07:40 -04:00
discogs: refactor and clean up tests (#6817)
- **What changed** - Simplifies `DiscogsPlugin.get_album_info` by removing a redundant "required fields" guard and relying on the plugin's normal parsing flow instead. - Reworks `test/plugins/test_discogs.py` around shared fixtures and helpers, including a common `DiscogsTestMixin`, reusable `plugin`/`plugin_config` fixtures, and a global patch for `DiscogsPlugin.setup`. - Expands and consolidates coverage for tracklist parsing, especially `_coalesce_tracks`-related behavior, `index_tracks`, grouped/sub-tracks, inherited artists, medium titles, and disambiguation handling. - **Architecture impact** - Test structure is now more modular and configuration-driven: scenarios pass settings through `plugin_config` instead of mutating global state inline. - Discogs test data now uses real `discogs_client.Release` objects via `get_release(...)` instead of the custom `Bag` stub, making tests closer to production behavior. - Repeated one-off tests were collapsed into parametrized suites, so tracklist behavior lives in one place and is easier to extend.
This commit is contained in:
@@ -237,3 +237,5 @@ ca8e9f69a8a0254aa767dc86f6d808d02f6af05d
|
||||
b1701c2e12b2de8e5462affe46ecc6816a5fc508
|
||||
# typing: type beets.dbcore.types
|
||||
ea3d6af6169d33be009b86bf5607baae7cf9652a
|
||||
# Fix #6177, remove derived types, refactor coalesce tracks
|
||||
9efe87101ce03706660129633e03147a222765cf
|
||||
|
||||
@@ -167,19 +167,6 @@ def touch(path):
|
||||
open(syspath(path), "a").close()
|
||||
|
||||
|
||||
class Bag:
|
||||
"""An object that exposes a set of fields given as keyword
|
||||
arguments. Any field not found in the dictionary appears to be None.
|
||||
Used for mocking Album objects and the like.
|
||||
"""
|
||||
|
||||
def __init__(self, **fields):
|
||||
self.fields = fields
|
||||
|
||||
def __getattr__(self, key):
|
||||
return self.fields.get(key)
|
||||
|
||||
|
||||
# Platform mocking.
|
||||
|
||||
|
||||
|
||||
@@ -345,20 +345,6 @@ class DiscogsPlugin(SearchApiMetadataSourcePlugin[IDResponse]):
|
||||
)
|
||||
return None
|
||||
|
||||
# Sanity check for required fields. The list of required fields is
|
||||
# defined at Guideline 1.3.1.a, but in practice some releases might be
|
||||
# lacking some of these fields. This function expects at least:
|
||||
# `artists` (>0), `title`, `id`, `tracklist` (>0)
|
||||
# https://www.discogs.com/help/doc/submission-guidelines-general-rules
|
||||
if not all(
|
||||
[
|
||||
result.data.get(k)
|
||||
for k in ["artists", "title", "id", "tracklist"]
|
||||
]
|
||||
):
|
||||
self._log.warning("Release does not contain the required fields")
|
||||
return None
|
||||
|
||||
artist_data = [a.data for a in result.artists]
|
||||
# Information for the album artist
|
||||
albumartist = ArtistState.from_config(
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
"""Tests for discogs plugin."""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from discogs_client import Client, Release
|
||||
|
||||
from beets import config
|
||||
from beets.library import Item
|
||||
from beets.test._common import Bag
|
||||
from beets.test.helper import TestHelper
|
||||
from beetsplug.discogs import ArtistState, DiscogsPlugin
|
||||
|
||||
_p = pytest.param
|
||||
|
||||
|
||||
def _artist(name: str, **kwargs):
|
||||
return {
|
||||
@@ -23,17 +25,49 @@ def _artist(name: str, **kwargs):
|
||||
} | kwargs
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
class TestDGAlbumInfo(TestHelper):
|
||||
def _track(title: str, position: str = "", duration: str = "", **kwargs):
|
||||
return {
|
||||
"title": title,
|
||||
"position": position,
|
||||
"duration": duration,
|
||||
"type_": "track",
|
||||
} | kwargs
|
||||
|
||||
|
||||
def get_release(data: dict[str, Any]) -> Release:
|
||||
return Release(Client("doesn't matter"), data)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _patch_discogs_setup(monkeypatch):
|
||||
"""Autouse fixture to patch DiscogsPlugin.setup for each test."""
|
||||
monkeypatch.setattr(
|
||||
"beetsplug.discogs.DiscogsPlugin.setup", lambda *_: None
|
||||
)
|
||||
|
||||
|
||||
class DiscogsTestMixin:
|
||||
@pytest.fixture
|
||||
def plugin_config(self):
|
||||
return {}
|
||||
|
||||
@pytest.fixture
|
||||
def plugin(self, plugin_config):
|
||||
plugin = DiscogsPlugin()
|
||||
plugin.config.set(plugin_config)
|
||||
return plugin
|
||||
|
||||
def _make_release(self, tracks=None):
|
||||
"""Returns a Bag that mimics a discogs_client.Release. The list
|
||||
of elements on the returned Bag is incomplete, including just
|
||||
those required for the tests on this class."""
|
||||
"""Return discogs_client.Release.
|
||||
|
||||
The returned object is incomplete, including just the fields required
|
||||
for tests in this module.
|
||||
"""
|
||||
data = {
|
||||
"id": "ALBUM ID",
|
||||
"uri": "https://www.discogs.com/release/release/13633721",
|
||||
"id": 11111111,
|
||||
"uri": "https://www.discogs.com/release/111111111",
|
||||
"title": "ALBUM TITLE",
|
||||
"year": "3001",
|
||||
"year": 3001,
|
||||
"artists": [_artist("ARTIST NAME", join=",")],
|
||||
"formats": [
|
||||
{
|
||||
@@ -46,42 +80,25 @@ class TestDGAlbumInfo(TestHelper):
|
||||
"genres": ["STYLE1", "STYLE2"],
|
||||
"styles": ["GENRE1", "GENRE2"],
|
||||
"labels": [{"name": "LABEL NAME", "catno": "CATALOG NUMBER"}],
|
||||
"tracklist": [],
|
||||
"tracklist": tracks or [],
|
||||
}
|
||||
|
||||
if tracks:
|
||||
for recording in tracks:
|
||||
data["tracklist"].append(recording)
|
||||
|
||||
return Bag(
|
||||
data=data,
|
||||
# Make some fields available as properties, as they are
|
||||
# accessed by DiscogsPlugin methods.
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
|
||||
def _make_track(self, title, position="", duration="", type_=None):
|
||||
return {
|
||||
"title": title,
|
||||
"position": position,
|
||||
"duration": duration,
|
||||
"type_": type_,
|
||||
}
|
||||
return get_release(data)
|
||||
|
||||
def _make_release_from_positions(self, positions):
|
||||
"""Return a Bag that mimics a discogs_client.Release with a
|
||||
tracklist where tracks have the specified `positions`."""
|
||||
"""Return discogs_client.Release with tracks at the given positions."""
|
||||
tracks = [
|
||||
self._make_track(f"TITLE{i}", position)
|
||||
_track(f"TITLE{i}", position)
|
||||
for (i, position) in enumerate(positions, start=1)
|
||||
]
|
||||
return self._make_release(tracks)
|
||||
|
||||
|
||||
class TestDGAlbumInfo(DiscogsTestMixin, TestHelper):
|
||||
def test_parse_media_for_tracks(self):
|
||||
tracks = [
|
||||
self._make_track("TITLE ONE", "1", "01:01"),
|
||||
self._make_track("TITLE TWO", "2", "02:02"),
|
||||
_track("TITLE ONE", "1", "01:01"),
|
||||
_track("TITLE TWO", "2", "02:02"),
|
||||
]
|
||||
release = self._make_release(tracks=tracks)
|
||||
|
||||
@@ -162,184 +179,21 @@ class TestDGAlbumInfo(TestHelper):
|
||||
assert t[3].index == 4
|
||||
assert t[3].medium_total == 1
|
||||
|
||||
def test_parse_tracklist_without_sides(self):
|
||||
"""Test standard Discogs position 12.2.9#1: "without sides"."""
|
||||
release = self._make_release_from_positions(["1", "2", "3"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
def test_parse_tracklist_with_sides(self):
|
||||
"""Test standard Discogs position 12.2.9#2: "with sides"."""
|
||||
release = self._make_release_from_positions(["A1", "A2", "B1", "B2"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1 # 2 sides = 1 LP
|
||||
assert len(d.tracks) == 4
|
||||
|
||||
def test_parse_tracklist_multiple_lp(self):
|
||||
"""Test standard Discogs position 12.2.9#3: "multiple LP"."""
|
||||
release = self._make_release_from_positions(["A1", "A2", "B1", "C1"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 2 # 3 sides = 1 LP + 1 LP
|
||||
assert len(d.tracks) == 4
|
||||
|
||||
def test_parse_tracklist_multiple_cd(self):
|
||||
"""Test standard Discogs position 12.2.9#4: "multiple CDs"."""
|
||||
release = self._make_release_from_positions(
|
||||
["1-1", "1-2", "2-1", "3-1"]
|
||||
)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 3
|
||||
assert len(d.tracks) == 4
|
||||
|
||||
def test_parse_tracklist_non_standard(self):
|
||||
"""Test non standard Discogs position."""
|
||||
release = self._make_release_from_positions(["I", "II", "III", "IV"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 4
|
||||
|
||||
def test_parse_tracklist_subtracks_dot(self):
|
||||
"""Test standard Discogs position 12.2.9#5: "sub tracks, dots"."""
|
||||
release = self._make_release_from_positions(["1", "2.1", "2.2", "3"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
release = self._make_release_from_positions(
|
||||
["A1", "A2.1", "A2.2", "A3"]
|
||||
)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
def test_parse_tracklist_subtracks_letter(self):
|
||||
"""Test standard Discogs position 12.2.9#5: "sub tracks, letter"."""
|
||||
release = self._make_release_from_positions(["A1", "A2a", "A2b", "A3"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
release = self._make_release_from_positions(
|
||||
["A1", "A2.a", "A2.b", "A3"]
|
||||
)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
def test_parse_tracklist_subtracks_extra_material(self):
|
||||
"""Test standard Discogs position 12.2.9#6: "extra material"."""
|
||||
release = self._make_release_from_positions(["1", "2", "Video 1"])
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d.mediums == 2
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
def test_parse_tracklist_subtracks_indices(self):
|
||||
"""Test parsing of subtracks that include index tracks."""
|
||||
release = self._make_release_from_positions(["", "", "1.1", "1.2"])
|
||||
# Track 1: Index track with medium title
|
||||
release.data["tracklist"][0]["title"] = "MEDIUM TITLE"
|
||||
# Track 2: Index track with track group title
|
||||
release.data["tracklist"][1]["title"] = "TRACK GROUP TITLE"
|
||||
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.mediums == 1
|
||||
assert d.tracks[0].disctitle == "MEDIUM TITLE"
|
||||
assert len(d.tracks) == 1
|
||||
assert d.tracks[0].title == "TRACK GROUP TITLE"
|
||||
|
||||
def test_parse_tracklist_subtracks_nested_logical(self):
|
||||
"""Test parsing of subtracks defined inside a index track that are
|
||||
logical subtracks (ie. should be grouped together into a single track).
|
||||
"""
|
||||
release = self._make_release_from_positions(["1", "", "3"])
|
||||
# Track 2: Index track with track group title, and sub_tracks
|
||||
release.data["tracklist"][1]["title"] = "TRACK GROUP TITLE"
|
||||
release.data["tracklist"][1]["sub_tracks"] = [
|
||||
self._make_track("TITLE ONE", "2.1", "01:01"),
|
||||
self._make_track("TITLE TWO", "2.2", "02:02"),
|
||||
]
|
||||
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 3
|
||||
assert d.tracks[1].title == "TRACK GROUP TITLE"
|
||||
|
||||
def test_parse_tracklist_subtracks_nested_physical(self):
|
||||
"""Test parsing of subtracks defined inside a index track that are
|
||||
physical subtracks (ie. should not be grouped together).
|
||||
"""
|
||||
release = self._make_release_from_positions(["1", "", "4"])
|
||||
# Track 2: Index track with track group title, and sub_tracks
|
||||
release.data["tracklist"][1]["title"] = "TRACK GROUP TITLE"
|
||||
release.data["tracklist"][1]["sub_tracks"] = [
|
||||
self._make_track("TITLE ONE", "2", "01:01"),
|
||||
self._make_track("TITLE TWO", "3", "02:02"),
|
||||
]
|
||||
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.mediums == 1
|
||||
assert len(d.tracks) == 4
|
||||
assert d.tracks[1].title == "TITLE ONE"
|
||||
assert d.tracks[2].title == "TITLE TWO"
|
||||
|
||||
def test_parse_tracklist_disctitles(self):
|
||||
"""Test parsing of index tracks that act as disc titles."""
|
||||
release = self._make_release_from_positions(
|
||||
["", "1-1", "1-2", "", "2-1"]
|
||||
)
|
||||
# Track 1: Index track with medium title (Cd1)
|
||||
release.data["tracklist"][0]["title"] = "MEDIUM TITLE CD1"
|
||||
# Track 4: Index track with medium title (Cd2)
|
||||
release.data["tracklist"][3]["title"] = "MEDIUM TITLE CD2"
|
||||
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.mediums == 2
|
||||
assert d.tracks[0].disctitle == "MEDIUM TITLE CD1"
|
||||
assert d.tracks[1].disctitle == "MEDIUM TITLE CD1"
|
||||
assert d.tracks[2].disctitle == "MEDIUM TITLE CD2"
|
||||
assert len(d.tracks) == 3
|
||||
|
||||
def test_parse_minimal_release(self):
|
||||
"""Test parsing of a release with the minimal amount of information."""
|
||||
data = {
|
||||
"id": 123,
|
||||
"uri": "https://www.discogs.com/release/123456-something",
|
||||
"tracklist": [self._make_track("A", "1", "01:01")],
|
||||
"tracklist": [_track("A", "1", "01:01")],
|
||||
"artists": [_artist("ARTIST NAME", id=321)],
|
||||
"title": "TITLE",
|
||||
}
|
||||
release = Bag(
|
||||
data=data,
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
release = get_release(data)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.artist == "ARTIST NAME"
|
||||
assert d.album == "TITLE"
|
||||
assert len(d.tracks) == 1
|
||||
|
||||
def test_parse_release_without_required_fields(self, caplog):
|
||||
"""Test parsing of a release that does not have the required fields."""
|
||||
release = Bag(data={}, refresh=lambda *args: None)
|
||||
with caplog.at_level("DEBUG"):
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
|
||||
assert d is None
|
||||
assert (
|
||||
"Release does not contain the required fields" in caplog.messages[0]
|
||||
)
|
||||
|
||||
def test_default_genre_style_settings(self):
|
||||
"""Test genre default settings, genres to genre, styles to style"""
|
||||
release = self._make_release_from_positions(["1", "2"])
|
||||
@@ -367,79 +221,215 @@ class TestDGAlbumInfo(TestHelper):
|
||||
assert d.style is None
|
||||
assert d.genres == ["GENRE1", "GENRE2"]
|
||||
|
||||
def test_strip_disambiguation(self):
|
||||
|
||||
class TestStripDisambiguation(DiscogsTestMixin):
|
||||
@pytest.fixture
|
||||
def album_info(self, plugin):
|
||||
data = {
|
||||
"id": 123,
|
||||
"uri": "https://www.discogs.com/release/123456-something",
|
||||
"tracklist": [
|
||||
{
|
||||
"title": "track",
|
||||
"position": "A",
|
||||
"type_": "track",
|
||||
"duration": "5:44",
|
||||
"artists": [_artist("TEST ARTIST (5)", id=11146)],
|
||||
}
|
||||
],
|
||||
"artists": [
|
||||
_artist("ARTIST NAME (2)", id=321, join="&"),
|
||||
_artist("OTHER ARTIST (5)", id=322),
|
||||
],
|
||||
"title": "title",
|
||||
"labels": [{"name": "LABEL NAME (5)", "catno": "catalog number"}],
|
||||
}
|
||||
return plugin.get_album_info(get_release(data))
|
||||
|
||||
@pytest.mark.parametrize("plugin_config", [{"strip_disambiguation": True}])
|
||||
def test_strip_disambiguation(self, album_info):
|
||||
"""Test removing disambiguation from all disambiguated fields."""
|
||||
data = {
|
||||
"id": 123,
|
||||
"uri": "https://www.discogs.com/release/123456-something",
|
||||
"tracklist": [
|
||||
{
|
||||
"title": "track",
|
||||
"position": "A",
|
||||
"type_": "track",
|
||||
"duration": "5:44",
|
||||
"artists": [_artist("TEST ARTIST (5)", id=11146)],
|
||||
}
|
||||
],
|
||||
"artists": [
|
||||
_artist("ARTIST NAME (2)", id=321, join="&"),
|
||||
_artist("OTHER ARTIST (5)", id=322),
|
||||
],
|
||||
"title": "title",
|
||||
"labels": [{"name": "LABEL NAME (5)", "catno": "catalog number"}],
|
||||
}
|
||||
release = Bag(
|
||||
data=data,
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.artist == "ARTIST NAME & OTHER ARTIST"
|
||||
assert d.artists == ["ARTIST NAME", "OTHER ARTIST"]
|
||||
assert d.artists_ids == ["321", "322"]
|
||||
assert d.tracks[0].artist == "TEST ARTIST"
|
||||
assert d.tracks[0].artists == ["TEST ARTIST"]
|
||||
assert d.tracks[0].artist_id == "11146"
|
||||
assert d.tracks[0].artists_ids == ["11146"]
|
||||
assert d.label == "LABEL NAME"
|
||||
assert album_info.artist == "ARTIST NAME & OTHER ARTIST"
|
||||
assert album_info.artists == ["ARTIST NAME", "OTHER ARTIST"]
|
||||
assert album_info.artists_ids == ["321", "322"]
|
||||
assert album_info.tracks[0].artist == "TEST ARTIST"
|
||||
assert album_info.tracks[0].artists == ["TEST ARTIST"]
|
||||
assert album_info.tracks[0].artist_id == "11146"
|
||||
assert album_info.tracks[0].artists_ids == ["11146"]
|
||||
assert album_info.label == "LABEL NAME"
|
||||
|
||||
def test_strip_disambiguation_false(self):
|
||||
@pytest.mark.parametrize("plugin_config", [{"strip_disambiguation": False}])
|
||||
def test_dont_strip_disambiguation(self, album_info):
|
||||
"""Test disabling disambiguation removal from all disambiguated fields."""
|
||||
config["discogs"]["strip_disambiguation"] = False
|
||||
data = {
|
||||
"id": 123,
|
||||
"uri": "https://www.discogs.com/release/123456-something",
|
||||
"tracklist": [
|
||||
{
|
||||
"title": "track",
|
||||
"position": "A",
|
||||
"type_": "track",
|
||||
"duration": "5:44",
|
||||
"artists": [_artist("TEST ARTIST (5)", id=11146)],
|
||||
}
|
||||
],
|
||||
"artists": [
|
||||
_artist("ARTIST NAME (2)", id=321, join="&"),
|
||||
_artist("OTHER ARTIST (5)", id=322),
|
||||
],
|
||||
"title": "title",
|
||||
"labels": [{"name": "LABEL NAME (5)", "catno": "catalog number"}],
|
||||
}
|
||||
release = Bag(
|
||||
data=data,
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
d = DiscogsPlugin().get_album_info(release)
|
||||
assert d.artist == "ARTIST NAME (2) & OTHER ARTIST (5)"
|
||||
assert d.artists == ["ARTIST NAME (2)", "OTHER ARTIST (5)"]
|
||||
assert d.tracks[0].artist == "TEST ARTIST (5)"
|
||||
assert d.tracks[0].artists == ["TEST ARTIST (5)"]
|
||||
assert d.label == "LABEL NAME (5)"
|
||||
config["discogs"]["strip_disambiguation"] = True
|
||||
assert album_info.artist == "ARTIST NAME (2) & OTHER ARTIST (5)"
|
||||
assert album_info.artists == ["ARTIST NAME (2)", "OTHER ARTIST (5)"]
|
||||
assert album_info.tracks[0].artist == "TEST ARTIST (5)"
|
||||
assert album_info.tracks[0].artists == ["TEST ARTIST (5)"]
|
||||
assert album_info.label == "LABEL NAME (5)"
|
||||
|
||||
|
||||
class TestTracklist(DiscogsTestMixin):
|
||||
@pytest.mark.parametrize(
|
||||
"positions,expected_mediums,expected_tracks",
|
||||
[
|
||||
_p(["1", "2", "3"], 1, 3, id="without-sides"),
|
||||
_p(["A1", "A2", "B1", "B2"], 1, 4, id="with-sides"),
|
||||
_p(["A1", "A2", "B1", "C1"], 2, 4, id="multiple-lp"),
|
||||
_p(["1-1", "1-2", "2-1", "3-1"], 3, 4, id="multiple-cd"),
|
||||
_p(["I", "II", "III", "IV"], 1, 4, id="non-standard"),
|
||||
_p(["1", "2.1", "2.2", "3"], 1, 3, id="subtracks-dot"),
|
||||
_p(["A1", "A2.1", "A2.2", "A3"], 1, 3, id="subtracks-dot-with-sides"),
|
||||
_p(["A1", "A2a", "A2b", "A3"], 1, 3, id="subtracks-letter"),
|
||||
_p(["A1", "A2.a", "A2.b", "A3"], 1, 3, id="subtracks-letter-with-dot"),
|
||||
_p(["1.1", "1.2", "2.1", "2.2"], 1, 2, id="multiple-subtrack-groups"),
|
||||
_p(["1", "2", "Video 1"], 2, 3, id="subtracks-extra-material"),
|
||||
],
|
||||
) # fmt: skip
|
||||
def test_parse_tracklist_positions(
|
||||
self, plugin, positions, expected_mediums, expected_tracks
|
||||
):
|
||||
release = self._make_release_from_positions(positions)
|
||||
d = plugin.get_album_info(release)
|
||||
|
||||
assert d.mediums == expected_mediums
|
||||
assert len(d.tracks) == expected_tracks
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"plugin_config,tracks,expected_mediums,expected_tracks",
|
||||
[
|
||||
_p(
|
||||
{"index_tracks": False},
|
||||
[
|
||||
_track("MEDIUM TITLE"),
|
||||
_track("TRACK GROUP TITLE"),
|
||||
_track("TITLE ONE", "1.1"),
|
||||
_track("TITLE TWO", "1.2"),
|
||||
],
|
||||
1,
|
||||
[("TRACK GROUP TITLE", "MEDIUM TITLE")],
|
||||
id="flat-logical-subtracks",
|
||||
),
|
||||
_p(
|
||||
{"index_tracks": False},
|
||||
[
|
||||
_track("TITLE ONE", "1"),
|
||||
_track(
|
||||
"TRACK GROUP TITLE",
|
||||
sub_tracks=[
|
||||
_track("SUBTITLE ONE", "2.1", "01:01"),
|
||||
_track("SUBTITLE TWO", "2.2", "02:02"),
|
||||
],
|
||||
),
|
||||
_track("TITLE THREE", "3"),
|
||||
],
|
||||
1,
|
||||
[
|
||||
("TITLE ONE", None),
|
||||
("TRACK GROUP TITLE", None),
|
||||
("TITLE THREE", None),
|
||||
],
|
||||
id="nested-logical-subtracks",
|
||||
),
|
||||
_p(
|
||||
{"index_tracks": False},
|
||||
[
|
||||
_track("TITLE ONE", "1"),
|
||||
_track(
|
||||
"TRACK GROUP TITLE",
|
||||
sub_tracks=[
|
||||
_track("SUBTITLE ONE", "2", "01:01"),
|
||||
_track("SUBTITLE TWO", "3", "02:02"),
|
||||
],
|
||||
),
|
||||
_track("TITLE FOUR", "4"),
|
||||
],
|
||||
1,
|
||||
[
|
||||
("TITLE ONE", None),
|
||||
("SUBTITLE ONE", None),
|
||||
("SUBTITLE TWO", None),
|
||||
("TITLE FOUR", None),
|
||||
],
|
||||
id="nested-physical-subtracks",
|
||||
),
|
||||
_p(
|
||||
{"index_tracks": True},
|
||||
[
|
||||
_track("TITLE ONE", "1"),
|
||||
_track(
|
||||
"TRACK GROUP TITLE",
|
||||
sub_tracks=[
|
||||
_track("SUBTITLE ONE", "2", "01:01"),
|
||||
_track("SUBTITLE TWO", "3", "02:02"),
|
||||
],
|
||||
),
|
||||
_track("TITLE FOUR", "4"),
|
||||
],
|
||||
1,
|
||||
[
|
||||
("TITLE ONE", None),
|
||||
("TRACK GROUP TITLE: SUBTITLE ONE", None),
|
||||
("TRACK GROUP TITLE: SUBTITLE TWO", None),
|
||||
("TITLE FOUR", None),
|
||||
],
|
||||
id="nested-physical-subtracks-with-index-tracks",
|
||||
),
|
||||
_p(
|
||||
{"index_tracks": False},
|
||||
[
|
||||
_track("MEDIUM TITLE CD1"),
|
||||
_track("TITLE ONE", "1-1"),
|
||||
_track("TITLE TWO", "1-2"),
|
||||
_track("MEDIUM TITLE CD2"),
|
||||
_track("TITLE THREE", "2-1"),
|
||||
],
|
||||
2,
|
||||
[
|
||||
("TITLE ONE", "MEDIUM TITLE CD1"),
|
||||
("TITLE TWO", "MEDIUM TITLE CD1"),
|
||||
("TITLE THREE", "MEDIUM TITLE CD2"),
|
||||
],
|
||||
id="medium-titles",
|
||||
),
|
||||
],
|
||||
) # fmt: skip
|
||||
def test_parse_tracklist_index_tracks(
|
||||
self, plugin, tracks, expected_mediums, expected_tracks
|
||||
):
|
||||
release = self._make_release(tracks)
|
||||
album = plugin.get_album_info(release)
|
||||
|
||||
assert album.mediums == expected_mediums
|
||||
assert [(t.title, t.disctitle) for t in album.tracks] == expected_tracks
|
||||
|
||||
def test_parse_tracklist_inherited_artists(self, plugin):
|
||||
"""Verify grouped tracks combine explicit and inherited artist credits.
|
||||
|
||||
This covers releases where a track group provides the default artist for
|
||||
sub-tracks that do not declare one themselves.
|
||||
|
||||
Note: this is based on the following release:
|
||||
https://www.discogs.com/release/3647530
|
||||
"""
|
||||
track_artist = "TRACK ARTIST"
|
||||
group_artist = "GROUP ARTIST"
|
||||
tracks = [
|
||||
_track(
|
||||
"TRACK GROUP TITLE",
|
||||
artists=[_artist(group_artist)],
|
||||
sub_tracks=[
|
||||
_track("TRACK ONE", "2", artists=[_artist(track_artist)]),
|
||||
_track("SUBTITLE TWO", "3"),
|
||||
],
|
||||
)
|
||||
]
|
||||
release = self._make_release(tracks)
|
||||
album = plugin.get_album_info(release)
|
||||
|
||||
assert album.mediums == 1
|
||||
assert {t.artist for t in album.tracks} == {track_artist, group_artist}
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
class TestDGSearchQuery(TestHelper):
|
||||
def test_default_search_filters_without_extra_tags(self):
|
||||
"""Discogs search uses only the type filter when no extra_tags are set."""
|
||||
@@ -506,11 +496,7 @@ class TestAnv:
|
||||
],
|
||||
"title": "title",
|
||||
}
|
||||
release = Bag(
|
||||
data=data,
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
release = get_release(data)
|
||||
plugin = DiscogsPlugin()
|
||||
plugin.config["anv"].set(
|
||||
{"artist": False, "album_artist": False, "artist_credit": False}
|
||||
@@ -601,7 +587,6 @@ class TestAnv:
|
||||
self._assert_fields(album_info, expected_album_fields)
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
def test_anv_album_artist():
|
||||
"""Test using artist name variations when the album artist
|
||||
is the same as the track artist, but only the track artist
|
||||
@@ -620,11 +605,7 @@ def test_anv_album_artist():
|
||||
"artists": [_artist("ARTIST (4)", id=321, anv="VARIATION")],
|
||||
"title": "title",
|
||||
}
|
||||
release = Bag(
|
||||
data=data,
|
||||
title=data["title"],
|
||||
artists=[Bag(data=d) for d in data["artists"]],
|
||||
)
|
||||
release = get_release(data)
|
||||
config["discogs"]["anv"]["album_artist"] = False
|
||||
config["discogs"]["anv"]["artist"] = True
|
||||
config["discogs"]["anv"]["artist_credit"] = False
|
||||
@@ -640,7 +621,6 @@ def test_anv_album_artist():
|
||||
assert r.tracks[0].artists_credit == ["ARTIST"]
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
def test_parse_featured_artists():
|
||||
"""Tests the plugins ability to parse a featured artist.
|
||||
Ignores artists that are not listed as featured."""
|
||||
@@ -678,7 +658,6 @@ def test_parse_featured_artists():
|
||||
assert t.composers == ["RANDOM"]
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
def test_parse_extraartist_roles():
|
||||
plugin = DiscogsPlugin()
|
||||
artistinfo = ArtistState.from_config(plugin.config, [_artist("ARTIST")])
|
||||
@@ -729,7 +708,6 @@ def test_get_media_and_albumtype(formats, expected_media, expected_albumtype):
|
||||
assert result == (expected_media, expected_albumtype)
|
||||
|
||||
|
||||
@patch("beetsplug.discogs.DiscogsPlugin.setup", Mock())
|
||||
def test_va_buildartistinfo():
|
||||
config["va_name"] = "VARIOUS ARTISTS"
|
||||
expected_info = {
|
||||
|
||||
Reference in New Issue
Block a user