package library import ( "fmt" "testing" ) // #279: the track-details openers resolve the rows a surface is showing // by path, instead of finding them in the whole library's array. The // answer must keep the caller's order (a batch dialog lists them as // selected), drop what is not in the library rather than invent it, and // survive more paths than one IN (...) can bind. func TestGetTracksByPaths(t *testing.T) { t.Parallel() lib, _ := setupTestLibrary(t) seedAlbumsAndGenres(t, lib) got, err := lib.GetTracksByPaths([]string{ "/other/b1.mp3", "/music/missing.mp3", "/music/a1.mp3", "/other/b1.mp3", }) if err != nil { t.Fatalf("GetTracksByPaths: %v", err) } paths := make([]string, 0, len(got)) for _, tr := range got { paths = append(paths, tr.FilePath) } if want := "[/other/b1.mp3 /music/a1.mp3]"; fmt.Sprint(paths) != want { t.Fatalf("paths = %v, want %s (caller order, missing dropped, duplicate once)", paths, want) } // Whole tracks, not just the key: details render every field. if got[1].TrackName != "A1" || len(got[1].Genre) != 2 { t.Errorf("a1 = %+v, want title A1 with two genres", got[1]) } } func TestGetTracksByPathsSpansChunks(t *testing.T) { t.Parallel() lib, _ := setupTestLibrary(t) seedAlbumsAndGenres(t, lib) // The real path last, behind more misses than one chunk binds, so a // loop that only ran the first chunk would return nothing. paths := make([]string, 0, pathLookupChunk+2) for i := range pathLookupChunk + 1 { paths = append(paths, fmt.Sprintf("/nowhere/%d.mp3", i)) } paths = append(paths, "/music/a2.mp3") got, err := lib.GetTracksByPaths(paths) if err != nil { t.Fatalf("GetTracksByPaths: %v", err) } if len(got) != 1 || got[0].FilePath != "/music/a2.mp3" { t.Fatalf("got %d tracks (%v), want only /music/a2.mp3", len(got), got) } }