package storage import ( "database/sql" "path/filepath" "testing" _ "modernc.org/sqlite" ) func TestMigrateCreatesTablesAndVersion(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "test.db") db, err := sql.Open("sqlite", dbPath) if err != nil { t.Fatalf("open: %v", err) } defer db.Close() if err := Migrate(db); err != nil { t.Fatalf("migrate: %v", err) } // Verify schema version. var version int if err := db.QueryRow(`SELECT version FROM schema_version`).Scan(&version); err != nil { t.Fatalf("query version: %v", err) } if version != 4 { t.Errorf("version = %d, want 4", version) } // Verify tables exist by inserting into them. _, err = db.Exec(`INSERT INTO login_attempts (username, password, ip, count, first_seen, last_seen) VALUES ('a', 'b', 'c', 1, '2024-01-01', '2024-01-01')`) if err != nil { t.Fatalf("insert into login_attempts: %v", err) } _, err = db.Exec(`INSERT INTO sessions (id, ip, username, shell_name, connected_at) VALUES ('test-id', 'c', 'a', '', '2024-01-01')`) if err != nil { t.Fatalf("insert into sessions: %v", err) } _, err = db.Exec(`INSERT INTO session_logs (session_id, timestamp, input, output) VALUES ('test-id', '2024-01-01', '', '')`) if err != nil { t.Fatalf("insert into session_logs: %v", err) } } func TestMigrateIdempotent(t *testing.T) { dbPath := filepath.Join(t.TempDir(), "test.db") db, err := sql.Open("sqlite", dbPath) if err != nil { t.Fatalf("open: %v", err) } defer db.Close() // Run twice; second should be a no-op. if err := Migrate(db); err != nil { t.Fatalf("first migrate: %v", err) } if err := Migrate(db); err != nil { t.Fatalf("second migrate: %v", err) } var version int if err := db.QueryRow(`SELECT version FROM schema_version`).Scan(&version); err != nil { t.Fatalf("query version: %v", err) } if version != 4 { t.Errorf("version = %d after double migrate, want 4", version) } } func TestLoadMigrations(t *testing.T) { migrations, err := loadMigrations() if err != nil { t.Fatalf("load: %v", err) } if len(migrations) == 0 { t.Fatal("no migrations found") } if migrations[0].Version != 1 { t.Errorf("first migration version = %d, want 1", migrations[0].Version) } }