Files
vibesonic/internal/library/index_test.go
T

172 lines
4.6 KiB
Go

package library
import (
"database/sql"
"path/filepath"
"testing"
"git.noroutes.net/NoRoutes/vibetunes/internal/database"
"git.noroutes.net/NoRoutes/vibetunes/internal/metadata"
)
func openTestDB(t *testing.T) *sql.DB {
t.Helper()
db, err := database.Open(filepath.Join(t.TempDir(), "test.db"))
if err != nil {
t.Fatalf("database.Open: %v", err)
}
t.Cleanup(func() { db.Close() })
return db
}
func makeMediaFile(t *testing.T, db *sql.DB, relPath string) *database.MediaFile {
t.Helper()
folder, err := database.CreateMusicFolder(db, "Music", "/music", "music")
if err != nil {
t.Fatalf("CreateMusicFolder: %v", err)
}
mf, err := database.CreateMediaFile(db, folder.ID, relPath, 1000, 0, "hash1", "flac", "song", 180, 900, 44100, 2)
if err != nil {
t.Fatalf("CreateMediaFile: %v", err)
}
return mf
}
func TestIndexFileCreatesArtistAlbumSong(t *testing.T) {
db := openTestDB(t)
mf := makeMediaFile(t, db, "Artist/Album/01 - Song.flac")
tags := &metadata.Tags{
Title: "Song One",
Album: "Great Album",
AlbumArtist: "Great Artist",
Artists: []string{"Great Artist", "Featured Person"},
Genres: []string{"Rock", "Indie"},
TrackNumber: 1,
Year: 2020,
}
song, err := IndexFile(db, mf, tags)
if err != nil {
t.Fatalf("IndexFile: %v", err)
}
if song.Title != "Song One" {
t.Errorf("Title = %q", song.Title)
}
if !song.AlbumID.Valid {
t.Fatal("expected song to have an album")
}
album, err := database.GetAlbum(db, song.AlbumID.String)
if err != nil {
t.Fatalf("GetAlbum: %v", err)
}
if album.Title != "Great Album" {
t.Errorf("Album title = %q", album.Title)
}
names, err := database.ListSongArtistNames(db, song.ID)
if err != nil {
t.Fatalf("ListSongArtistNames: %v", err)
}
if len(names) != 2 || names[0] != "Great Artist" || names[1] != "Featured Person" {
t.Errorf("song artists = %v", names)
}
genres, err := database.ListGenres(db)
if err != nil {
t.Fatalf("ListGenres: %v", err)
}
if len(genres) != 2 {
t.Errorf("genres = %v, want 2", genres)
}
}
func TestIndexFileIsIdempotent(t *testing.T) {
db := openTestDB(t)
mf := makeMediaFile(t, db, "Artist/Album/01 - Song.flac")
tags := &metadata.Tags{Title: "Song", Album: "Album", AlbumArtist: "Artist", Artists: []string{"Artist"}}
song1, err := IndexFile(db, mf, tags)
if err != nil {
t.Fatalf("IndexFile (1st): %v", err)
}
song2, err := IndexFile(db, mf, tags)
if err != nil {
t.Fatalf("IndexFile (2nd): %v", err)
}
if song1.ID != song2.ID {
t.Errorf("song ID changed across reindex: %s -> %s", song1.ID, song2.ID)
}
if song1.AlbumID.String != song2.AlbumID.String {
t.Errorf("album ID changed across reindex: %s -> %s", song1.AlbumID.String, song2.AlbumID.String)
}
artists, err := database.ListSongArtistNames(db, song1.ID)
if err != nil {
t.Fatalf("ListSongArtistNames: %v", err)
}
if len(artists) != 1 {
t.Errorf("reindexing duplicated song_artists rows: %v", artists)
}
}
func TestIndexFileUsesFilenameWhenNoTitle(t *testing.T) {
db := openTestDB(t)
mf := makeMediaFile(t, db, "Unknown/Track.flac")
song, err := IndexFile(db, mf, &metadata.Tags{})
if err != nil {
t.Fatalf("IndexFile: %v", err)
}
if song.Title != mf.RelativePath {
t.Errorf("Title = %q, want fallback to relative path %q", song.Title, mf.RelativePath)
}
}
func TestListDirectory(t *testing.T) {
db := openTestDB(t)
folder, err := database.CreateMusicFolder(db, "Music", "/music", "music")
if err != nil {
t.Fatalf("CreateMusicFolder: %v", err)
}
for _, p := range []string{"ArtistA/Album1/01.flac", "ArtistA/Album1/02.flac", "ArtistA/Album2/01.flac", "ArtistB/Album3/01.flac"} {
if _, err := database.CreateMediaFile(db, folder.ID, p, 1, 0, "h"+p, "flac", "song", 1, 1, 1, 1); err != nil {
t.Fatalf("CreateMediaFile(%s): %v", p, err)
}
}
root, err := ListDirectory(db, folder.ID, "")
if err != nil {
t.Fatalf("ListDirectory(root): %v", err)
}
if len(root) != 2 {
t.Fatalf("root entries = %v, want 2 (ArtistA, ArtistB)", root)
}
for _, e := range root {
if !e.Dir {
t.Errorf("root entry %q should be a directory", e.Name)
}
}
sub, err := ListDirectory(db, folder.ID, "ArtistA")
if err != nil {
t.Fatalf("ListDirectory(ArtistA): %v", err)
}
if len(sub) != 2 {
t.Fatalf("ArtistA entries = %v, want 2 (Album1, Album2)", sub)
}
files, err := ListDirectory(db, folder.ID, "ArtistA/Album1")
if err != nil {
t.Fatalf("ListDirectory(ArtistA/Album1): %v", err)
}
if len(files) != 2 {
t.Fatalf("Album1 entries = %v, want 2 files", files)
}
for _, e := range files {
if e.Dir {
t.Errorf("entry %q should be a file", e.Name)
}
}
}