Files
MusicServer/internal/db/migration_integration_test.go
T
Sansan 7b144ae419 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
2026-10-06 15:20:31 +02:00

87 lines
2.9 KiB
Go

//go:build integration
package db_test
import (
"context"
"fmt"
"testing"
"music-server/internal/db"
"music-server/internal/testutil/pgtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func openDatabase(t *testing.T, dbname string) *db.Database {
t.Helper()
database, err := db.NewDatabase(context.Background(), pgtest.ConnString(dbname))
require.NoError(t, err)
t.Cleanup(database.Close)
return database
}
func count(t *testing.T, database *db.Database, query string) int {
t.Helper()
var n int
require.NoError(t, database.Pool.QueryRow(context.Background(), query).Scan(&n))
return n
}
// TestMigrationsKeepData applies the migrations step by step with data in between,
// like a database that was created by an older version.
func TestMigrationsKeepData(t *testing.T) {
ctx := context.Background()
database := openDatabase(t, pgtest.NewDatabase(t))
m, closeFn, err := database.NewMigrator()
require.NoError(t, err)
defer closeFn()
require.NoError(t, m.Steps(4))
for i := 1; i <= 5; i++ {
_, err := database.Pool.Exec(ctx, `INSERT INTO game (game_name, path, hash, added) VALUES ($1, $2, $3, NOW())`,
fmt.Sprintf("Manual Game %d", i), fmt.Sprintf("/music/game%d/", i), fmt.Sprintf("hash-%d", i))
require.NoError(t, err)
}
for i, game := range []int{1, 1, 2, 3, 4, 4, 4, 5, 5} {
_, err := database.Pool.Exec(ctx, `INSERT INTO song (game_id, song_name, path, hash) VALUES ($1, $2, $3, $4)`,
game, fmt.Sprintf("Song %d", i), fmt.Sprintf("/music/game%d/%d.mp3", game, i), fmt.Sprintf("song-hash-%d", i))
require.NoError(t, err)
}
require.NoError(t, m.Up())
version, dirty, err := m.Version()
require.NoError(t, err)
assert.False(t, dirty)
assert.Equal(t, uint(6), version)
assert.Equal(t, 5, count(t, database, "SELECT COUNT(*) FROM soundtrack"))
assert.Equal(t, 9, count(t, database, "SELECT COUNT(*) FROM song"))
assert.Equal(t, 0, count(t, database, "SELECT COUNT(*) FROM song WHERE uuid IS NULL OR soundtrack_uuid IS NULL"))
assert.Equal(t, 5, count(t, database, "SELECT COUNT(*) FROM soundtrack WHERE fingerprint = ''"))
_, err = database.Pool.Exec(ctx, "SELECT 1 FROM game")
assert.Error(t, err, "game table is renamed")
}
func TestFingerprintMigrationDown(t *testing.T) {
database := openDatabase(t, pgtest.NewDatabase(t))
m, closeFn, err := database.NewMigrator()
require.NoError(t, err)
defer closeFn()
require.NoError(t, m.Up())
require.NoError(t, m.Steps(-1))
assert.Equal(t, 0, count(t, database,
"SELECT COUNT(*) FROM information_schema.columns WHERE table_name = 'soundtrack' AND column_name = 'fingerprint'"))
require.NoError(t, m.Up())
}
func TestRunMigrationsIsIdempotent(t *testing.T) {
database := openDatabase(t, pgtest.NewDatabase(t))
require.NoError(t, database.RunMigrations())
require.NoError(t, database.RunMigrations())
assert.Equal(t, "up", database.Health(context.Background())["status"])
}