Detach DB queries from HTTP request context so HTMX polling doesn't cancel in-flight queries when the browser aborts previous XHRs. Add indexes on login_attempts and sessions to speed up frequent dashboard queries. Bump version to 0.17.1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.2 KiB
Go
84 lines
2.2 KiB
Go
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 != 5 {
|
|
t.Errorf("version = %d, want 5", 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 != 5 {
|
|
t.Errorf("version = %d after double migrate, want 5", 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)
|
|
}
|
|
}
|