Rewrite tests to run without a database
- Unit tests use an in-memory fake database (internal/testutil/fakedb), temp folders and httptest; `go test ./...` needs no Docker or env vars - Integration tests (build tag "integration") start PostgreSQL with testcontainers: migrations step by step, SQL dumps (skipped if missing) and a full sync against a real database - Removed tests that only checked copies of the logic or had empty bodies, the broken root integration_test.go, compose.test.yaml and .env.test with hardcoded paths - testMusic MP3s replaced with tiny placeholders (sync never decodes audio), 194 MB -> 168 KB
This commit is contained in:
1 parent
090e794460
commit
7b144ae419
42 files changed
+2334
-40
No files matched your search
@@ -0,0 +1,111 @@
|
||||
//go:build integration
|
||||
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"music-server/internal/db/repository"
|
||||
"music-server/internal/logging"
|
||||
"music-server/internal/testutil/pgtest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
logging.Init("fatal", false)
|
||||
os.Exit(pgtest.Main(m))
|
||||
}
|
||||
|
||||
// copyTestMusic copies the repository's testMusic folder so tests can change it.
|
||||
func copyTestMusic(t *testing.T) string {
|
||||
t.Helper()
|
||||
dst := t.TempDir()
|
||||
require.NoError(t, os.CopyFS(dst, os.DirFS(filepath.Join("..", "..", "testMusic"))))
|
||||
return dst
|
||||
}
|
||||
|
||||
// TestSyncWithPostgres runs syncs against a real database to check the SQL queries.
|
||||
func TestSyncWithPostgres(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
q := repository.New(pgtest.NewMigratedDatabase(t).Pool)
|
||||
musicDir := copyTestMusic(t)
|
||||
s := NewSyncService(q, musicDir, nil)
|
||||
run := func(full bool) SyncResponse {
|
||||
require.True(t, s.Start(full))
|
||||
s.Wait()
|
||||
result := s.Result()
|
||||
require.Empty(t, result.CatchedErrors)
|
||||
return result
|
||||
}
|
||||
|
||||
result := run(false)
|
||||
assert.Equal(t, []string{"A Bird Story", "Clair Obscur - Expedition 33", "Metal Gear Rising - Revengeance"}, result.SoundtracksAdded)
|
||||
|
||||
soundtracks, err := q.FindAllSoundtracks(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, soundtracks, 3)
|
||||
bird := soundtracks[0]
|
||||
assert.NotEmpty(t, bird.Fingerprint)
|
||||
songs, err := q.FindSongsFromSoundtrack(ctx, bird.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, songs, 6)
|
||||
|
||||
// Play a song, then rename one of its files and, in a later sync, the soundtrack folder.
|
||||
// (Renaming both at once changes the content hash, so the folder would count as new.)
|
||||
require.NoError(t, q.AddSongPlayed(ctx, repository.AddSongPlayedParams{SoundtrackID: bird.ID, SongName: "2. Yesterday"}))
|
||||
birdDir := filepath.Join(musicDir, "A Bird Story")
|
||||
require.NoError(t, os.Rename(filepath.Join(birdDir, "2. Yesterday.mp3"), filepath.Join(birdDir, "02 Yesterday.mp3")))
|
||||
|
||||
result = run(false)
|
||||
assert.Equal(t, []string{"A Bird Story"}, result.SoundtracksChangedContent)
|
||||
|
||||
require.NoError(t, os.Rename(birdDir, filepath.Join(musicDir, "A Bird Story (2014)")))
|
||||
result = run(false)
|
||||
assert.Equal(t, map[string]string{"A Bird Story": "A Bird Story (2014)"}, result.SoundtracksChangedTitle)
|
||||
assert.Empty(t, result.SoundtracksAdded)
|
||||
assert.Empty(t, result.SoundtracksRemoved)
|
||||
|
||||
renamed, err := q.GetSoundtrackById(ctx, bird.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "A Bird Story (2014)", renamed.SoundtrackName)
|
||||
songs, err = q.FindSongsFromSoundtrack(ctx, bird.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, songs, 6)
|
||||
var yesterday repository.Song
|
||||
for _, song := range songs {
|
||||
assert.Contains(t, song.Path, "/A Bird Story (2014)/")
|
||||
if song.SongName == "02 Yesterday" {
|
||||
yesterday = song
|
||||
}
|
||||
}
|
||||
assert.Equal(t, int32(1), yesterday.TimesPlayed, "play count survives renames")
|
||||
|
||||
// Nothing changed: the fingerprint lets the sync skip everything.
|
||||
result = run(false)
|
||||
assert.Empty(t, result.SoundtracksChangedContent)
|
||||
assert.Empty(t, result.SoundtracksChangedTitle)
|
||||
|
||||
// Remove a soundtrack and bring it back.
|
||||
mgr := filepath.Join(musicDir, "Metal Gear Rising - Revengeance")
|
||||
backup := filepath.Join(t.TempDir(), "mgr")
|
||||
require.NoError(t, os.Rename(mgr, backup))
|
||||
result = run(false)
|
||||
assert.Equal(t, []string{"Metal Gear Rising - Revengeance"}, result.SoundtracksRemoved)
|
||||
active, err := q.FindAllSoundtracks(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, active, 2)
|
||||
|
||||
require.NoError(t, os.Rename(backup, mgr))
|
||||
result = run(true)
|
||||
assert.Equal(t, []string{"Metal Gear Rising - Revengeance"}, result.SoundtracksReAdded)
|
||||
|
||||
// Classic random picks only songs of active soundtracks.
|
||||
row, err := q.GetRandomActiveSong(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, row.SoundtrackPath)
|
||||
}
|
||||
Reference in new issue
Block a user