fix: preserve source artist credits when downloading

Keep full source artist credits in download responses and embedded tags, falling back to provider credits only when the source is empty. Add regression coverage for new and existing files.
This commit is contained in:
zarzet committed 2026-09-17 02:12:10 +07:00
1 parent a5530dc5bd
commit b2ea07c41e
2 files changed
+50 -1

No files matched your search

@@ -10,6 +10,54 @@ use std::thread;
const RECORDING: &str = r#"{"recordings":[{"tags":[{"name":"rock","count":1}],"releases":[{"title":"Album","artist-credit":[{"name":"Album Artist"}]}]}]}"#; const RECORDING: &str = r#"{"recordings":[{"tags":[{"name":"rock","count":1}],"releases":[{"title":"Album","artist-credit":[{"name":"Album Artist"}]}]}]}"#;
const CATALOG: &str = r#"{"id":7,"album":{"id":9},"genres":{"data":[{"name":"Jazz"}]},"label":"Label","copyright":"Copyright"}"#; const CATALOG: &str = r#"{"id":7,"album":{"id":9},"genres":{"data":[{"name":"Jazz"}]},"label":"Label","copyright":"Copyright"}"#;
#[test]
fn download_preserves_source_artist_credits_in_response_and_embedded_tags() {
let manifest = ExtensionManifest {
name: "audio-provider".into(),
..Default::default()
};
for (source, provided, expected) in [
(
"Lead Artist & Guest Artist",
"Lead Artist",
"Lead Artist & Guest Artist",
),
(
"",
"Lead Artist & Guest Artist",
"Lead Artist & Guest Artist",
),
(
" ",
"Lead Artist & Guest Artist",
"Lead Artist & Guest Artist",
),
(
"Lead Artist & Guest Artist",
"",
"Lead Artist & Guest Artist",
),
] {
let request = DownloadRequest {
track_name: "Track".into(),
artist_name: source.into(),
..Default::default()
};
let result = json!({"artist": provided});
for exists in [false, true] {
let response = success(&request, &result, "track.flac", exists, &manifest, &|| {
Ok(())
})
.unwrap();
assert_eq!(response["artist"], expected);
assert_eq!(
download_metadata_fields(&request, &response)["ARTIST"],
expected
);
}
}
}
fn network() -> (Arc<NetworkService>, Arc<rustls::ServerConfig>) { fn network() -> (Arc<NetworkService>, Arc<rustls::ServerConfig>) {
let certificate = rcgen::generate_simple_self_signed(vec!["127.0.0.1".into()]).unwrap(); let certificate = rcgen::generate_simple_self_signed(vec!["127.0.0.1".into()]).unwrap();
let config = rustls::ServerConfig::builder_with_provider(Arc::new( let config = rustls::ServerConfig::builder_with_provider(Arc::new(
@@ -1648,7 +1648,8 @@ fn success(
"explicit":request.explicit || result["explicit"] == true}); "explicit":request.explicit || result["explicit"] == true});
for (key, requested, prefer_request) in [ for (key, requested, prefer_request) in [
("title", request.track_name.trim(), true), ("title", request.track_name.trim(), true),
("artist", request.artist_name.as_str(), false), // Preserve source credits: an audio provider may list only the lead artist.
("artist", request.artist_name.trim(), true),
("album", request.album_name.trim(), true), ("album", request.album_name.trim(), true),
("album_artist", request.album_artist.as_str(), true), ("album_artist", request.album_artist.as_str(), true),
("release_date", request.release_date.trim(), true), ("release_date", request.release_date.trim(), true),