124 lines
3.6 KiB
Go
124 lines
3.6 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
|
)
|
|
|
|
// truncateLibrary clears the music tables between tests. Sessions/users are
|
|
// cleared by testHandlers. CASCADE covers tracks→albums→artists FK chain.
|
|
func truncateLibrary(t *testing.T, pool *pgxpool.Pool) {
|
|
t.Helper()
|
|
if _, err := pool.Exec(context.Background(),
|
|
"TRUNCATE tracks, albums, artists RESTART IDENTITY CASCADE"); err != nil {
|
|
t.Fatalf("truncate: %v", err)
|
|
}
|
|
}
|
|
|
|
// seedArtist inserts an artist with deterministic sort_name = name.
|
|
func seedArtist(t *testing.T, pool *pgxpool.Pool, name string) dbq.Artist {
|
|
t.Helper()
|
|
a, err := dbq.New(pool).UpsertArtist(context.Background(), dbq.UpsertArtistParams{
|
|
Name: name,
|
|
SortName: name,
|
|
Mbid: nil,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpsertArtist(%s): %v", name, err)
|
|
}
|
|
return a
|
|
}
|
|
|
|
// seedAlbum inserts an album belonging to artistID. releaseYear=0 leaves
|
|
// release_date unset.
|
|
func seedAlbum(t *testing.T, pool *pgxpool.Pool, artistID pgtype.UUID, title string, releaseYear int) dbq.Album {
|
|
t.Helper()
|
|
var rel pgtype.Date
|
|
if releaseYear > 0 {
|
|
rel = pgtype.Date{Time: time.Date(releaseYear, 1, 1, 0, 0, 0, 0, time.UTC), Valid: true}
|
|
}
|
|
a, err := dbq.New(pool).UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
|
|
Title: title,
|
|
SortTitle: title,
|
|
ArtistID: artistID,
|
|
ReleaseDate: rel,
|
|
Mbid: nil,
|
|
CoverArtPath: nil,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpsertAlbum(%s): %v", title, err)
|
|
}
|
|
return a
|
|
}
|
|
|
|
// seedTrack inserts a track. trackNumber<=0 leaves it NULL. filePath is
|
|
// synthesized from title to stay unique across seeds.
|
|
func seedTrack(t *testing.T, pool *pgxpool.Pool, albumID, artistID pgtype.UUID, title string, trackNumber int, durationMs int32) dbq.Track {
|
|
t.Helper()
|
|
var tn *int32
|
|
if trackNumber > 0 {
|
|
v := int32(trackNumber)
|
|
tn = &v
|
|
}
|
|
tr, err := dbq.New(pool).UpsertTrack(context.Background(), dbq.UpsertTrackParams{
|
|
Title: title,
|
|
AlbumID: albumID,
|
|
ArtistID: artistID,
|
|
TrackNumber: tn,
|
|
DiscNumber: nil,
|
|
DurationMs: durationMs,
|
|
FilePath: "/seed/" + title + ".flac",
|
|
FileSize: 1024,
|
|
FileFormat: "flac",
|
|
Bitrate: nil,
|
|
Mbid: nil,
|
|
Genre: nil,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpsertTrack(%s): %v", title, err)
|
|
}
|
|
return tr
|
|
}
|
|
|
|
// seedTrackWithFile creates a fresh temp directory, writes fileBody to
|
|
// <dir>/<title>.<ext>, and inserts a Track row whose file_path points at it.
|
|
// Returns the inserted Track and the directory (callers drop sidecar covers
|
|
// into this dir when a test needs them). FileFormat is ext lowercased.
|
|
func seedTrackWithFile(t *testing.T, pool *pgxpool.Pool, albumID, artistID pgtype.UUID, title string, fileBody []byte, ext string) (dbq.Track, string) {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, title+"."+ext)
|
|
if err := os.WriteFile(path, fileBody, 0o644); err != nil {
|
|
t.Fatalf("WriteFile(%s): %v", path, err)
|
|
}
|
|
one := int32(1)
|
|
tr, err := dbq.New(pool).UpsertTrack(context.Background(), dbq.UpsertTrackParams{
|
|
Title: title,
|
|
AlbumID: albumID,
|
|
ArtistID: artistID,
|
|
TrackNumber: &one,
|
|
DiscNumber: nil,
|
|
// DurationMs: arbitrary non-zero; tests don't assert on it.
|
|
DurationMs: int32(len(fileBody)),
|
|
FilePath: path,
|
|
FileSize: int64(len(fileBody)),
|
|
FileFormat: strings.ToLower(ext),
|
|
Bitrate: nil,
|
|
Mbid: nil,
|
|
Genre: nil,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpsertTrack(%s): %v", title, err)
|
|
}
|
|
return tr, dir
|
|
}
|