Files
MusicServer/internal/server/test_helpers.go
T
Sansan 24a9111333 feat: Remove global db.Dbpool with dependency injection (Phase 0)
- Add Database struct in internal/db/database.go with Pool, Ctx, and RunMigrations()
- Update server.go to use Database struct with NewServerInstance()
- Add backend.go with InitBackend(), BackendRepo(), BackendCtx(), BackendPool()
- Update music.go and sync.go to use BackendRepo() and BackendCtx() instead of db.Dbpool/db.Ctx
- Update token_handler.go to accept pool parameter
- Update routes.go to use s.db.Pool for middleware
- Update cmd/main.go to use NewServerInstance() and HTTPServer()
- Update test_helpers.go to initialize backend with test database
- Update test files to use backend.BackendPool() and backend.BackendCtx()

Benefits:
- Easier to mock database for unit tests
- Follows Go best practices (dependency injection)
- Better architecture with explicit dependencies
- RunMigrations() replaces old Migrate_db() function

Note: Global db.Dbpool and db.Ctx still exist in dbHelper.go for backward compatibility
with test_helpers.go, but production code no longer uses them.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-08 20:15:38 +02:00

121 lines
3.1 KiB
Go

package server
import (
"bytes"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
"music-server/internal/backend"
"music-server/internal/db"
"github.com/labstack/echo/v5"
)
// StartTestServer starts the server for testing with test configuration
func StartTestServer(t *testing.T) *echo.Echo {
// Set test environment variables if not already set
if os.Getenv("DB_HOST") == "" {
os.Setenv("DB_HOST", "localhost")
}
if os.Getenv("DB_PORT") == "" {
os.Setenv("DB_PORT", "5432")
}
if os.Getenv("DB_USERNAME") == "" {
os.Setenv("DB_USERNAME", "testuser")
}
if os.Getenv("DB_PASSWORD") == "" {
os.Setenv("DB_PASSWORD", "testpass")
}
if os.Getenv("DB_NAME") == "" {
os.Setenv("DB_NAME", "music_server_test")
}
if os.Getenv("MUSIC_PATH") == "" {
os.Setenv("MUSIC_PATH", "./testMusic")
}
if os.Getenv("CHARACTERS_PATH") == "" {
os.Setenv("CHARACTERS_PATH", "./testCharacters")
}
if os.Getenv("PORT") == "" {
os.Setenv("PORT", "8081")
}
if os.Getenv("LOG_LEVEL") == "" {
os.Setenv("LOG_LEVEL", "debug")
}
if os.Getenv("LOG_JSON") == "" {
os.Setenv("LOG_JSON", "false")
}
// Initialize database for tests
db.TestSetupDB(t)
// Initialize backend with the global Dbpool
// This ensures BackendRepo() and BackendCtx() are available
if db.Dbpool != nil {
backend.InitBackend(db.Dbpool)
}
// Create a Server instance and get its routes
s := &Server{
db: &db.Database{
Pool: db.Dbpool,
Ctx: db.Ctx,
},
tokenHandler: NewTokenHandler(db.Dbpool),
}
handler := s.RegisterRoutes()
// Wrap the http.Handler in an echo.Echo
e := echo.New()
// Use a custom handler that wraps our routes
e.Any("/*", echo.WrapHandler(handler))
return e
}
// MakeTestRequest makes an HTTP request to the test server
func MakeTestRequest(t *testing.T, e *echo.Echo, method, path string) *httptest.ResponseRecorder {
req := httptest.NewRequest(method, path, nil)
rec := httptest.NewRecorder()
e.ServeHTTP(rec, req)
return rec
}
// MakeTestRequestWithBody makes an HTTP request with a body to the test server
func MakeTestRequestWithBody(t *testing.T, e *echo.Echo, method, path string, body []byte) *httptest.ResponseRecorder {
req := httptest.NewRequest(method, path, nil)
if body != nil {
req = httptest.NewRequest(method, path, bytes.NewBuffer(body))
}
rec := httptest.NewRecorder()
e.ServeHTTP(rec, req)
return rec
}
// WaitForSyncComplete polls the sync progress endpoint until sync is complete
func WaitForSyncComplete(t *testing.T, e *echo.Echo, timeout time.Duration) bool {
start := time.Now()
for time.Since(start) < timeout {
resp := MakeTestRequest(t, e, "GET", "/sync/progress")
if resp.Code != http.StatusOK {
t.Logf("Sync progress endpoint returned status %d", resp.Code)
time.Sleep(1 * time.Second)
continue
}
// Parse response - we can't easily decode here without importing backend
// Just check if response contains "100"
body := resp.Body.String()
if len(body) > 0 {
t.Logf("Sync progress: %s", body)
// Simple check for completion
// In a real scenario, you'd parse the JSON properly
}
time.Sleep(1 * time.Second)
}
t.Error("Sync did not complete within timeout")
return false
}