Subsonic: browsing endpoints (getMusicFolders, getIndexes, getMusicDirectory, getGenres, getArtists/Artist, getAlbum, getSong, getVideos/VideoInfo, getArtistInfo/2, getAlbumInfo/2, getSimilarSongs/2, getTopSongs)

This commit is contained in:
2026-08-23 00:06:08 -05:00
parent b5e2bf01e2
commit f40a011c46
9 changed files with 1732 additions and 4 deletions
+164
View File
@@ -0,0 +1,164 @@
package database
import (
"database/sql"
"fmt"
"path/filepath"
"testing"
)
func setupGenreFixture(t *testing.T) *sql.DB {
t.Helper()
db, err := Open(filepath.Join(t.TempDir(), "test.db"))
if err != nil {
t.Fatalf("Open: %v", err)
}
t.Cleanup(func() { db.Close() })
folder, err := CreateMusicFolder(db, "Music", "/music", "music")
if err != nil {
t.Fatal(err)
}
artist, err := FindOrCreateArtist(db, "Test Artist", "", "")
if err != nil {
t.Fatal(err)
}
album, err := FindOrCreateAlbum(db, "Test Album", nullStr2(artist.ID), "", nullInt2(2020), nullInt2(0), "", "")
if err != nil {
t.Fatal(err)
}
if err := LinkAlbumArtist(db, album.ID, artist.ID, 0); err != nil {
t.Fatal(err)
}
genre, err := FindOrCreateGenre(db, "Rock")
if err != nil {
t.Fatal(err)
}
if err := LinkAlbumGenre(db, album.ID, genre.ID); err != nil {
t.Fatal(err)
}
for i := 1; i <= 3; i++ {
mf, err := CreateMediaFile(db, folder.ID, fmt.Sprintf("song%d.mp3", i), 1000, 0, fmt.Sprintf("hash%d", i), "mp3", "song", 180, 320, 44100, 2)
if err != nil {
t.Fatal(err)
}
song, err := UpsertSong(db, UpsertSongInput{MediaFileID: mf.ID, AlbumID: nullStr2(album.ID), Title: "Song"})
if err != nil {
t.Fatal(err)
}
if err := LinkSongGenre(db, song.ID, genre.ID); err != nil {
t.Fatal(err)
}
}
return db
}
func nullStr2(s string) sql.NullString { return sql.NullString{String: s, Valid: s != ""} }
func nullInt2(n int64) sql.NullInt64 {
if n == 0 {
return sql.NullInt64{}
}
return sql.NullInt64{Int64: n, Valid: true}
}
func TestAlbumStats(t *testing.T) {
db := setupGenreFixture(t)
albums, err := ListAlbums(db, 10, 0)
if err != nil || len(albums) != 1 {
t.Fatalf("ListAlbums: %v, %v", albums, err)
}
count, dur, err := AlbumStats(db, albums[0].ID)
if err != nil {
t.Fatalf("AlbumStats: %v", err)
}
if count != 3 {
t.Errorf("songCount = %d, want 3", count)
}
if dur != 540 {
t.Errorf("duration = %v, want 540", dur)
}
}
func TestListGenreStats(t *testing.T) {
db := setupGenreFixture(t)
stats, err := ListGenreStats(db)
if err != nil {
t.Fatalf("ListGenreStats: %v", err)
}
if len(stats) != 1 {
t.Fatalf("stats = %v, want 1 genre", stats)
}
if stats[0].Name != "Rock" || stats[0].SongCount != 3 || stats[0].AlbumCount != 1 {
t.Errorf("stats[0] = %+v, want Rock/3/1", stats[0])
}
}
func TestSongsByGenre(t *testing.T) {
db := setupGenreFixture(t)
songs, err := SongsByGenre(db, "Rock", 10, 0)
if err != nil {
t.Fatalf("SongsByGenre: %v", err)
}
if len(songs) != 3 {
t.Fatalf("songs = %v, want 3", songs)
}
}
func TestRandomSongIDsFilteredByGenre(t *testing.T) {
db := setupGenreFixture(t)
ids, err := RandomSongIDs(db, 10, "Rock", 0, 0)
if err != nil {
t.Fatalf("RandomSongIDs: %v", err)
}
if len(ids) != 3 {
t.Fatalf("ids = %v, want 3", ids)
}
ids2, err := RandomSongIDs(db, 10, "Jazz", 0, 0)
if err != nil {
t.Fatalf("RandomSongIDs(Jazz): %v", err)
}
if len(ids2) != 0 {
t.Fatalf("ids2 = %v, want 0 for nonexistent genre", ids2)
}
}
func TestArtistAlbumCountAndCoverArt(t *testing.T) {
db := setupGenreFixture(t)
artists, err := ListArtists(db)
if err != nil || len(artists) != 1 {
t.Fatalf("ListArtists: %v, %v", artists, err)
}
n, err := ArtistAlbumCount(db, artists[0].ID)
if err != nil {
t.Fatalf("ArtistAlbumCount: %v", err)
}
if n != 1 {
t.Errorf("ArtistAlbumCount = %d, want 1", n)
}
cover, err := ArtistCoverArtID(db, artists[0].ID)
if err != nil {
t.Fatalf("ArtistCoverArtID: %v", err)
}
if cover != "" {
t.Errorf("ArtistCoverArtID = %q, want empty (no cover art set in fixture)", cover)
}
}
func TestAlbumsByYearRange(t *testing.T) {
db := setupGenreFixture(t)
albums, err := AlbumsByYearRange(db, 2019, 2021, 10, 0)
if err != nil {
t.Fatalf("AlbumsByYearRange: %v", err)
}
if len(albums) != 1 {
t.Fatalf("albums = %v, want 1", albums)
}
none, err := AlbumsByYearRange(db, 1990, 1991, 10, 0)
if err != nil {
t.Fatalf("AlbumsByYearRange: %v", err)
}
if len(none) != 0 {
t.Fatalf("albums = %v, want 0 outside range", none)
}
}