// SPDX-License-Identifier: AGPL-3.0-or-later package database import ( "testing" _ "modernc.org/sqlite" ) func TestOpenInMemory(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("Open(:memory:): %v", err) } defer db.Close() // Verify the connection is usable. var result int if err := db.QueryRow("SELECT 1").Scan(&result); err != nil { t.Fatalf("query: %v", err) } if result != 1 { t.Errorf("SELECT 1 = %d", result) } } func TestMigrateCreatesAllTables(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("open: %v", err) } defer db.Close() if err := Migrate(db); err != nil { t.Fatalf("migrate: %v", err) } // Check that core tables exist. tables := []string{"users", "faves", "tags", "fave_tags", "sessions", "site_settings", "schema_migrations", "signup_requests"} for _, table := range tables { var count int err := db.QueryRow("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?", table).Scan(&count) if err != nil { t.Errorf("check table %s: %v", table, err) } if count != 1 { t.Errorf("table %s does not exist", table) } } } func TestMigrateIdempotent(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("open: %v", err) } defer db.Close() // First migration. if err := Migrate(db); err != nil { t.Fatalf("first migrate: %v", err) } // Second migration should be a no-op. if err := Migrate(db); err != nil { t.Fatalf("second migrate: %v", err) } // Verify schema_migrations has entries (no duplicates). var count int db.QueryRow("SELECT COUNT(*) FROM schema_migrations").Scan(&count) if count < 1 { t.Error("expected at least one migration record") } } func TestPRAGMAs(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("open: %v", err) } defer db.Close() // WAL mode. var journalMode string db.QueryRow("PRAGMA journal_mode").Scan(&journalMode) // In-memory databases use "memory" journal mode, not "wal". // WAL is only meaningful for file-based databases. // We just verify the pragma was accepted without error. // Foreign keys should be ON. var fk int db.QueryRow("PRAGMA foreign_keys").Scan(&fk) if fk != 1 { t.Errorf("foreign_keys = %d, want 1", fk) } // Busy timeout. var timeout int db.QueryRow("PRAGMA busy_timeout").Scan(&timeout) if timeout != 5000 { t.Errorf("busy_timeout = %d, want 5000", timeout) } } func TestSingleConnection(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("open: %v", err) } defer db.Close() stats := db.Stats() if stats.MaxOpenConnections != 1 { t.Errorf("MaxOpenConnections = %d, want 1", stats.MaxOpenConnections) } } func TestSiteSettingsSeeded(t *testing.T) { db, err := Open(":memory:") if err != nil { t.Fatalf("open: %v", err) } defer db.Close() if err := Migrate(db); err != nil { t.Fatalf("migrate: %v", err) } // Migrations should seed a default site_settings row. var siteName string err = db.QueryRow("SELECT site_name FROM site_settings WHERE id = 1").Scan(&siteName) if err != nil { t.Fatalf("query site_settings: %v", err) } if siteName == "" { t.Error("expected non-empty default site_name") } }