120 lines
3.3 KiB
Go
120 lines
3.3 KiB
Go
package library
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db"
|
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
|
"git.fabledsword.com/bvandeusen/minstrel/internal/dbtest"
|
|
)
|
|
|
|
func newPool(t *testing.T) *pgxpool.Pool {
|
|
t.Helper()
|
|
if testing.Short() {
|
|
t.Skip("skipping integration test in -short mode")
|
|
}
|
|
dsn := os.Getenv("MINSTREL_TEST_DATABASE_URL")
|
|
if dsn == "" {
|
|
t.Skip("MINSTREL_TEST_DATABASE_URL not set")
|
|
}
|
|
if err := db.Migrate(dsn, slog.New(slog.NewTextHandler(io.Discard, nil))); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
pool, err := pgxpool.New(context.Background(), dsn)
|
|
if err != nil {
|
|
t.Fatalf("pool: %v", err)
|
|
}
|
|
t.Cleanup(pool.Close)
|
|
dbtest.ResetDB(t, pool)
|
|
return pool
|
|
}
|
|
|
|
func seedTrack(t *testing.T, pool *pgxpool.Pool, filePath string) (dbq.Track, dbq.Album, dbq.Artist) {
|
|
t.Helper()
|
|
q := dbq.New(pool)
|
|
artist, err := q.UpsertArtist(context.Background(), dbq.UpsertArtistParams{
|
|
Name: "Delete Test Artist", SortName: "Delete Test Artist",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("artist: %v", err)
|
|
}
|
|
album, err := q.UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
|
|
Title: "Delete Test Album", SortTitle: "Delete Test Album",
|
|
ArtistID: artist.ID,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("album: %v", err)
|
|
}
|
|
track, err := q.UpsertTrack(context.Background(), dbq.UpsertTrackParams{
|
|
Title: "Delete Test Track", AlbumID: album.ID, ArtistID: artist.ID,
|
|
DurationMs: 1000, FilePath: filePath, FileSize: 100, FileFormat: "mp3",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("track: %v", err)
|
|
}
|
|
return track, album, artist
|
|
}
|
|
|
|
func TestDeleteTrackFile_HappyPath(t *testing.T) {
|
|
pool := newPool(t)
|
|
q := dbq.New(pool)
|
|
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "track.mp3")
|
|
if err := os.WriteFile(path, []byte("payload"), 0o644); err != nil {
|
|
t.Fatalf("write file: %v", err)
|
|
}
|
|
track, album, _ := seedTrack(t, pool, path)
|
|
|
|
if err := DeleteTrackFile(context.Background(), pool, track.ID); err != nil {
|
|
t.Fatalf("DeleteTrackFile: %v", err)
|
|
}
|
|
|
|
if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) {
|
|
t.Errorf("file still exists: %v", err)
|
|
}
|
|
if _, err := q.GetTrackByID(context.Background(), track.ID); err == nil {
|
|
t.Errorf("track row still exists")
|
|
}
|
|
// Album row preserved (other tracks may reference it).
|
|
if _, err := q.GetAlbumByID(context.Background(), album.ID); err != nil {
|
|
t.Errorf("album row vanished: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteTrackFile_FileAlreadyGoneSucceeds(t *testing.T) {
|
|
pool := newPool(t)
|
|
q := dbq.New(pool)
|
|
|
|
track, _, _ := seedTrack(t, pool, "/no/such/file/anywhere.mp3")
|
|
|
|
if err := DeleteTrackFile(context.Background(), pool, track.ID); err != nil {
|
|
t.Fatalf("DeleteTrackFile with missing file: %v", err)
|
|
}
|
|
if _, err := q.GetTrackByID(context.Background(), track.ID); err == nil {
|
|
t.Errorf("track row still exists")
|
|
}
|
|
}
|
|
|
|
func TestDeleteTrackFile_NotFoundReturnsErr(t *testing.T) {
|
|
pool := newPool(t)
|
|
|
|
var bogus pgtype.UUID
|
|
bogus.Bytes = [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
|
|
bogus.Valid = true
|
|
|
|
err := DeleteTrackFile(context.Background(), pool, bogus)
|
|
if !errors.Is(err, ErrTrackNotFound) {
|
|
t.Errorf("err = %v, want ErrTrackNotFound", err)
|
|
}
|
|
}
|