From c792ed3d4453aaa5e6e6d8a4a9fb3a41fc407261 Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Tue, 13 Oct 2026 13:54:36 +0000 Subject: [PATCH] fix(lz): Only use original artist_name in naive play if no artists credits were extracted Prevents single artist string with joiner slipping through uniqueNormalizedStrArr filter on artists --- .../common/vendor/ListenbrainzApiClient.ts | 5 +++- .../tests/listenbrainz/listenbrainz.test.ts | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/backend/common/vendor/ListenbrainzApiClient.ts b/src/backend/common/vendor/ListenbrainzApiClient.ts index 158b2ea5..b3048baf 100644 --- a/src/backend/common/vendor/ListenbrainzApiClient.ts +++ b/src/backend/common/vendor/ListenbrainzApiClient.ts @@ -656,7 +656,6 @@ export const listenToNaivePlay = (listen: ListenResponse): PlayObject => { if(artist_names.length > 0) { artists = artist_names; } else if(typeof artist_name === 'string') { - artists = [artist_name]; // since we aren't using MB mappings we should be conservative and assume artist string with & are proper names (not joiner) const parsedArtists = parseCredits(artist_name, [',', '/', '\\']); @@ -673,6 +672,10 @@ export const listenToNaivePlay = (listen: ListenResponse): PlayObject => { normalTrackName = parsedTrackArtists.primary; artists = artists.concat(parsedTrackArtists.secondary ?? []) } + if(artists.length === 0) { + // fallback to original artist_name string if we weren't able to parse anything from artists/track credits + artists.push(artist_name); + } artists = uniqueNormalizedStrArr(artists); } diff --git a/src/backend/tests/listenbrainz/listenbrainz.test.ts b/src/backend/tests/listenbrainz/listenbrainz.test.ts index f2e563a5..c829df05 100644 --- a/src/backend/tests/listenbrainz/listenbrainz.test.ts +++ b/src/backend/tests/listenbrainz/listenbrainz.test.ts @@ -25,6 +25,7 @@ import incorrectMultiArtistsTrackName from './incorrectlyMapped/multiArtistsInTr import veryWrong from './incorrectlyMapped/veryWrong.json' with { type: "json" }; import { generatePlay } from "../../../core/tests/utils/PlayTestUtils.ts"; import { nameToCredit, creditsToNames, namesToCredits } from "../../../core/MusicMetadata.ts"; +import { playStateFromRequest } from "../../sources/EndpointListenbrainzSource.ts"; interface LZTestFixture { data: ListenResponse @@ -371,6 +372,32 @@ describe('Listenbrainz Endpoint Behavior', function() { }); + it('does not include artist_name if artists were extracted from string', function() { + const payload = { + "listened_at": 1791895981, + "track_metadata": { + "artist_name": "Alohaii feat. Rachie", + "track_name": "Heart Of Glass", + "release_name": "SUMMERTIDE", + "additional_info": { + "artist_mbids": [ + "a611433b-c2bb-4ba2-be28-775a079e93c6", + "745a0c93-a487-4650-ab05-07c4eb9234a2" + ], + "release_mbid": "560db4c2-5af5-4ef0-a9e0-b56fca3d8bea", + "release_group_mbid": "e5a74679-1883-45cb-b776-8b7aee879760", + "recording_mbid": "3d4a73ff-3956-4d6b-b423-b1c079775dcf", + "duration_ms": 217433, + "track_mbid": "c3fda34b-31e1-4e9a-af76-85e3dd08b09f", + "tracknumber": 4 + } + } + } + const state = playStateFromRequest({listen_type: 'single', payload: [payload]}); + expect(state[0].play.data.artists?.some(x => x.name === 'Alohaii')).is.true; + expect(state[0].play.data.artists?.some(x => x.name === 'Rachie')).is.true; + }) + }); -- 2.54.0