From a64bde86bfe03600f83290a3ccb51c36e07fee4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Sun, 23 Nov 2025 08:31:35 +0000 Subject: [PATCH] Add a test to reproduce the issue --- test/autotag/test_match.py | 108 ++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/test/autotag/test_match.py b/test/autotag/test_match.py index 10933f139..212944045 100644 --- a/test/autotag/test_match.py +++ b/test/autotag/test_match.py @@ -1,6 +1,9 @@ +from typing import ClassVar + import pytest -from beets.autotag import TrackInfo, match +from beets import metadata_plugins +from beets.autotag import AlbumInfo, TrackInfo, match from beets.library import Item @@ -92,3 +95,106 @@ class TestAssignment: expected = list(zip(items, trackinfo)), [], [] assert match.assign_items(items, trackinfo) == expected + + +class TestTagMultipleDataSources: + @pytest.fixture + def shared_track_id(self): + return "track-12345" + + @pytest.fixture + def shared_album_id(self): + return "album-12345" + + @pytest.fixture(autouse=True) + def _setup_plugins(self, monkeypatch, shared_album_id, shared_track_id): + class StubPlugin(metadata_plugins.MetadataSourcePlugin): + @property + def track(self): + return TrackInfo( + artist="Artist", + title="Title", + track_id=shared_track_id, + data_source=self.data_source, + ) + + @property + def album(self): + return AlbumInfo( + [self.track], + artist="Albumartist", + album="Album", + album_id=shared_album_id, + data_source=self.data_source, + ) + + def album_for_id(self, *_): + return self.album + + def track_for_id(self, *_): + return self.track + + def candidates(self, *_, **__): + yield self.album + + def item_candidates(self, *_, **__): + yield self.track + + class DeezerPlugin(StubPlugin): + pass + + class DiscogsPlugin(StubPlugin): + pass + + monkeypatch.setattr( + metadata_plugins, + "find_metadata_source_plugins", + lambda: [DeezerPlugin(), DiscogsPlugin()], + ) + + def check_proposal(self, proposal): + sources = [ + candidate.info.data_source for candidate in proposal.candidates + ] + assert len(sources) == 2 + assert set(sources) == {"Discogs", "Deezer"} + + @pytest.mark.xfail( + reason="Album ID collisions drop extra sources (#6177)", + raises=AssertionError, + strict=True, + ) + def test_search_album_ids(self, shared_album_id): + _, _, proposal = match.tag_album([Item()], search_ids=[shared_album_id]) + + self.check_proposal(proposal) + + @pytest.mark.xfail( + reason="Album ID collisions drop extra sources (#6177)", + raises=AssertionError, + strict=True, + ) + def test_search_album_current_id(self, shared_album_id): + _, _, proposal = match.tag_album([Item(mb_albumid=shared_album_id)]) + + self.check_proposal(proposal) + + @pytest.mark.xfail( + reason="Track ID collisions drop extra sources (#6177)", + raises=AssertionError, + strict=True, + ) + def test_search_track_ids(self, shared_track_id): + proposal = match.tag_item(Item(), search_ids=[shared_track_id]) + + self.check_proposal(proposal) + + @pytest.mark.xfail( + reason="Track ID collisions drop extra sources (#6177)", + raises=AssertionError, + strict=True, + ) + def test_search_track_current_id(self, shared_track_id): + proposal = match.tag_item(Item(mb_trackid=shared_track_id)) + + self.check_proposal(proposal)