package database import ( "os" "testing" "time" ) func TestNewDatabase(t *testing.T) { // Create temporary database file tempFile, err := os.CreateTemp("", "test_skyview_*.db") if err != nil { t.Fatal("Failed to create temp database file:", err) } defer os.Remove(tempFile.Name()) tempFile.Close() config := &Config{ Path: tempFile.Name(), VacuumInterval: time.Hour, } db, err := NewDatabase(config) if err != nil { t.Fatal("Failed to create database:", err) } defer db.Close() if db == nil { t.Fatal("NewDatabase() returned nil") } // Test connection conn := db.GetConnection() if conn == nil { t.Fatal("GetConnection() returned nil") } // Test basic query var result int err = conn.QueryRow("SELECT 1").Scan(&result) if err != nil { t.Error("Basic query failed:", err) } if result != 1 { t.Error("Basic query returned wrong result:", result) } } func TestDatabaseClose(t *testing.T) { tempFile, err := os.CreateTemp("", "test_skyview_*.db") if err != nil { t.Fatal("Failed to create temp database file:", err) } defer os.Remove(tempFile.Name()) tempFile.Close() config := &Config{Path: tempFile.Name()} db, err := NewDatabase(config) if err != nil { t.Fatal("Failed to create database:", err) } // Close should not error if err := db.Close(); err != nil { t.Error("Database Close() returned error:", err) } // Second close should be safe if err := db.Close(); err != nil { t.Error("Second Close() returned error:", err) } // Connection should be nil after close conn := db.GetConnection() if conn != nil { t.Error("GetConnection() should return nil after Close()") } } func TestDatabaseConfig(t *testing.T) { tempFile, err := os.CreateTemp("", "test_skyview_*.db") if err != nil { t.Fatal("Failed to create temp database file:", err) } defer os.Remove(tempFile.Name()) tempFile.Close() config := &Config{ Path: tempFile.Name(), VacuumInterval: 2 * time.Hour, } db, err := NewDatabase(config) if err != nil { t.Fatal("Failed to create database:", err) } defer db.Close() // Test that config is stored correctly if db.config != config { t.Error("Database config not stored correctly") } if db.config.VacuumInterval != 2*time.Hour { t.Error("VacuumInterval not preserved:", db.config.VacuumInterval) } } func TestDatabaseMigrations(t *testing.T) { db, cleanup := setupTestDatabase(t) defer cleanup() conn := db.GetConnection() // Check that essential tables exist after migrations tables := []string{"airlines", "airports", "callsign_cache", "data_sources", "aircraft_history"} for _, table := range tables { var count int query := "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?" err := conn.QueryRow(query, table).Scan(&count) if err != nil { t.Errorf("Failed to check for table %s: %v", table, err) } if count != 1 { t.Errorf("Table %s does not exist", table) } } } func TestDatabasePragmas(t *testing.T) { tempFile, err := os.CreateTemp("", "test_skyview_*.db") if err != nil { t.Fatal("Failed to create temp database file:", err) } defer os.Remove(tempFile.Name()) tempFile.Close() config := &Config{Path: tempFile.Name()} db, err := NewDatabase(config) if err != nil { t.Fatal("Failed to create database:", err) } defer db.Close() conn := db.GetConnection() // Check that foreign keys are enabled var foreignKeys int err = conn.QueryRow("PRAGMA foreign_keys").Scan(&foreignKeys) if err != nil { t.Error("Failed to check foreign_keys pragma:", err) } if foreignKeys != 1 { t.Error("Foreign keys should be enabled") } // Check journal mode var journalMode string err = conn.QueryRow("PRAGMA journal_mode").Scan(&journalMode) if err != nil { t.Error("Failed to check journal_mode:", err) } // Should be WAL mode for better concurrency if journalMode != "wal" { t.Errorf("Expected WAL journal mode, got: %s", journalMode) } }