mirror of
https://github.com/spotiflacapp/SpotiFLAC-Mobile.git
synced 2026-06-01 03:15:17 +07:00
All search, metadata, and download providers are now exclusively supplied by extensions. The built-in provider registry that previously exposed Deezer/Tidal/Qobuz as hardcoded providers is fully removed. Removed across Go, Dart, Kotlin, and Swift: - BuiltInProviderSpec class, registry, and all accessor helpers - SearchProviderAllJSON, GetBuiltInProvidersJSON, ParseProviderURLJSON, ParseDeezerURLExport Go exports and their platform channel bindings - Built-in provider items in search dropdown, service picker, and provider priority UI lists - provider_ui_utils.dart helper file Deezer metadata enrichment (ISRC lookup, extended metadata, cover upgrade) remains fully functional through direct DeezerClient calls in the download pipeline — these are not part of the provider registry and are unaffected. Mark deezer as a retired built-in metadata provider so stale user priority lists are cleaned up on next launch.
164 lines
6 KiB
Go
164 lines
6 KiB
Go
package gobackend
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestExtensionProviderWrapperFullSurface(t *testing.T) {
|
|
ext := newTestLoadedExtension(t, ExtensionTypeMetadataProvider, ExtensionTypeDownloadProvider, ExtensionTypeLyricsProvider)
|
|
provider := newExtensionProviderWrapper(ext)
|
|
|
|
search, err := provider.SearchTracks("query", 5)
|
|
if err != nil {
|
|
t.Fatalf("SearchTracks: %v", err)
|
|
}
|
|
if search.Total != 1 || search.Tracks[0].ProviderID != ext.ID || search.Tracks[0].ExternalLinks["tidal"] == "" {
|
|
t.Fatalf("search = %#v", search)
|
|
}
|
|
|
|
track, err := provider.GetTrack("track-1")
|
|
if err != nil {
|
|
t.Fatalf("GetTrack: %v", err)
|
|
}
|
|
if track.Name != "Track track-1" || track.ProviderID != ext.ID || track.AudioQuality == "" {
|
|
t.Fatalf("track = %#v", track)
|
|
}
|
|
|
|
album, err := provider.GetAlbum("album-1")
|
|
if err != nil {
|
|
t.Fatalf("GetAlbum: %v", err)
|
|
}
|
|
if album.ProviderID != ext.ID || len(album.Tracks) != 1 || album.Tracks[0].ProviderID != ext.ID {
|
|
t.Fatalf("album = %#v", album)
|
|
}
|
|
|
|
playlist, err := provider.GetPlaylist("playlist-1")
|
|
if err != nil {
|
|
t.Fatalf("GetPlaylist: %v", err)
|
|
}
|
|
if playlist.Name != "Playlist playlist-1" || playlist.ProviderID != ext.ID {
|
|
t.Fatalf("playlist = %#v", playlist)
|
|
}
|
|
|
|
artist, err := provider.GetArtist("artist-1")
|
|
if err != nil {
|
|
t.Fatalf("GetArtist: %v", err)
|
|
}
|
|
if artist.ProviderID != ext.ID || len(artist.Releases) != 1 || artist.Releases[0].ProviderID != ext.ID {
|
|
t.Fatalf("artist = %#v", artist)
|
|
}
|
|
|
|
enriched, err := provider.EnrichTrack(&ExtTrackMetadata{ID: "track-1", Name: "Old", ProviderID: ext.ID})
|
|
if err != nil {
|
|
t.Fatalf("EnrichTrack: %v", err)
|
|
}
|
|
if enriched.Name != "Enriched" || enriched.ProviderID != ext.ID {
|
|
t.Fatalf("enriched = %#v", enriched)
|
|
}
|
|
|
|
availability, err := provider.CheckAvailability("ISRC", "Song", "Artist", "spotify:1", "dz", "tidal", "qobuz")
|
|
if err != nil {
|
|
t.Fatalf("CheckAvailability: %v", err)
|
|
}
|
|
if !availability.Available || availability.TrackID != "download-track" || !availability.SkipFallback {
|
|
t.Fatalf("availability = %#v", availability)
|
|
}
|
|
|
|
downloadURL, err := provider.GetDownloadURL("track-1", "LOSSLESS")
|
|
if err != nil {
|
|
t.Fatalf("GetDownloadURL: %v", err)
|
|
}
|
|
if downloadURL.Format != "flac" || downloadURL.BitDepth != 24 || downloadURL.SampleRate != 96000 {
|
|
t.Fatalf("download URL = %#v", downloadURL)
|
|
}
|
|
|
|
progress := []int{}
|
|
download, err := provider.Download("track-1", "LOSSLESS", filepath.Join(t.TempDir(), "song.flac"), "", func(percent int) {
|
|
progress = append(progress, percent)
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Download: %v", err)
|
|
}
|
|
if !download.Success || download.Decryption == nil || download.DecryptionKey != "001122" || len(progress) != 1 || progress[0] != 100 {
|
|
t.Fatalf("download = %#v progress=%v", download, progress)
|
|
}
|
|
|
|
lyrics, err := provider.FetchLyrics("Song", "Artist", "Album", 180)
|
|
if err != nil {
|
|
t.Fatalf("GetLyrics: %v", err)
|
|
}
|
|
if lyrics.Provider != ext.ID || len(lyrics.Lines) != 1 || lyrics.Lines[0].Words != "Hello" {
|
|
t.Fatalf("lyrics = %#v", lyrics)
|
|
}
|
|
|
|
urlResult, err := provider.HandleURL("https://example.test/track/1")
|
|
if err != nil {
|
|
t.Fatalf("HandleURL: %v", err)
|
|
}
|
|
if urlResult.Track == nil || urlResult.Track.Name == "" || len(urlResult.Tracks) != 1 || urlResult.Album == nil || urlResult.Artist == nil {
|
|
t.Fatalf("url result = %#v", urlResult)
|
|
}
|
|
|
|
match, err := provider.MatchTrack(
|
|
map[string]interface{}{"name": "Song", "artists": "Artist"},
|
|
[]map[string]interface{}{{"id": "download-track", "name": "Song"}},
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("MatchTrack: %v", err)
|
|
}
|
|
if !match.Matched || match.TrackID != "download-track" {
|
|
t.Fatalf("match = %#v", match)
|
|
}
|
|
|
|
post, err := provider.PostProcess(filepath.Join(t.TempDir(), "song.flac"), map[string]interface{}{"title": "Song"}, "hook")
|
|
if err != nil {
|
|
t.Fatalf("PostProcess: %v", err)
|
|
}
|
|
if !post.Success || post.BitDepth != 24 || post.SampleRate != 96000 {
|
|
t.Fatalf("post = %#v", post)
|
|
}
|
|
}
|
|
|
|
func TestExtensionProviderAndManagerSelectionHelpers(t *testing.T) {
|
|
manifest := &ExtensionManifest{Capabilities: map[string]interface{}{
|
|
"replacesBuiltInProviders": []interface{}{" Deezer ", 7, ""},
|
|
}}
|
|
if values := manifestCapabilityStringList(manifest, "replacesBuiltInProviders"); len(values) != 1 || values[0] != "deezer" {
|
|
t.Fatalf("capability list = %#v", values)
|
|
}
|
|
if !extensionReplacesBuiltInProvider(&loadedExtension{Manifest: manifest}, "deezer") || extensionReplacesBuiltInProvider(nil, "deezer") {
|
|
t.Fatal("extension replacement mismatch")
|
|
}
|
|
if trimKnownProviderPrefix("Deezer:101", "deezer") != "101" || trimKnownProviderPrefix("101", "deezer") != "101" {
|
|
t.Fatal("trimKnownProviderPrefix mismatch")
|
|
}
|
|
if metadataTrackDedupKey(ExtTrackMetadata{ISRC: "usrc"}) != "isrc:USRC" ||
|
|
metadataTrackDedupKey(ExtTrackMetadata{SpotifyID: "sp"}) != "spotify:sp" ||
|
|
metadataTrackDedupKey(ExtTrackMetadata{ProviderID: "p", ID: "1"}) != "p:1" {
|
|
t.Fatal("metadata dedup key mismatch")
|
|
}
|
|
|
|
manager := &extensionManager{extensions: map[string]*loadedExtension{}}
|
|
downloadExt := newTestLoadedExtension(t, ExtensionTypeDownloadProvider, ExtensionTypeMetadataProvider)
|
|
manager.extensions[downloadExt.ID] = downloadExt
|
|
if providers := manager.GetDownloadProviders(); len(providers) != 1 {
|
|
t.Fatalf("download providers = %#v", providers)
|
|
}
|
|
SetProviderPriority([]string{"deezer", "coverage-ext", "coverage-ext", " "})
|
|
if priority := GetProviderPriority(); len(priority) != 1 || priority[0] != "coverage-ext" {
|
|
t.Fatalf("provider priority = %#v", priority)
|
|
}
|
|
SetExtensionFallbackProviderIDs([]string{"a", "a", " ", "b"})
|
|
if ids := GetExtensionFallbackProviderIDs(); len(ids) != 2 || !isExtensionFallbackAllowed("a") || isExtensionFallbackAllowed("z") {
|
|
t.Fatalf("fallback ids = %#v", ids)
|
|
}
|
|
SetExtensionFallbackProviderIDs(nil)
|
|
if !isExtensionFallbackAllowed("z") {
|
|
t.Fatal("nil fallback list should allow all")
|
|
}
|
|
SetMetadataProviderPriority([]string{"spotify", "deezer", "coverage-ext", "coverage-ext"})
|
|
if priority := GetMetadataProviderPriority(); len(priority) != 1 || priority[0] != "coverage-ext" {
|
|
t.Fatalf("metadata priority = %#v", priority)
|
|
}
|
|
}
|