Files
odidere/internal/db/schema_test.go
T
2026-09-20 12:27:30 +00:00

137 lines
3.1 KiB
Go

package db
import (
"context"
"testing"
)
// ExpectedUserVersion is the schema version after all migrations have been applied.
// Increment this when adding a new migration file.
const ExpectedUserVersion = 1
func TestSchema(t *testing.T) {
var (
ctx = t.Context()
db = createDB(t)
)
defer db.Close()
t.Run("InitialVersion", func(t *testing.T) {
testInitialVersion(t, ctx, db)
})
if err := db.ApplySchema(ctx, nil); err != nil {
t.Fatalf("ApplySchema: %v", err)
}
t.Run("ApplySchema", func(t *testing.T) {
testApplySchema(t, ctx, db)
})
t.Run("ApplySchemaIdempotent", func(t *testing.T) {
testSchemaIdempotent(t, ctx, db)
})
t.Run("ApplySchemaTablesExist", func(t *testing.T) {
testTablesExist(t, ctx, db)
})
t.Run("ApplySchemaIndexesExist", func(t *testing.T) {
testSchemaIndexes(t, ctx, db)
})
}
func testInitialVersion(t *testing.T, ctx context.Context, db *SQLite) {
var version int
err := db.Reader.QueryRowContext(
ctx,
"PRAGMA user_version",
).Scan(&version)
if err != nil {
t.Fatalf("PRAGMA user_version: %v", err)
}
if version != 0 {
t.Fatalf("expected initial version 0, got %d", version)
}
}
func testApplySchema(t *testing.T, ctx context.Context, db *SQLite) {
var version int
err := db.Reader.QueryRowContext(
ctx,
"PRAGMA user_version",
).Scan(&version)
if err != nil {
t.Fatalf("PRAGMA user_version: %v", err)
}
if version != ExpectedUserVersion {
t.Fatalf("expected version %d, got %d", ExpectedUserVersion, version)
}
}
func testTablesExist(t *testing.T, ctx context.Context, db *SQLite) {
expected := []string{
"approvals",
"conversations",
"messages",
"sessions",
"users",
}
for _, table := range expected {
var exists bool
err := db.Reader.QueryRowContext(
ctx,
"SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1)",
table,
).Scan(&exists)
if err != nil {
t.Fatalf("query sqlite_master for %s: %v", table, err)
}
if !exists {
t.Errorf("table %s does not exist", table)
}
}
}
func testSchemaIdempotent(t *testing.T, ctx context.Context, db *SQLite) {
// Apply schema again; should succeed without error.
if err := db.ApplySchema(ctx, nil); err != nil {
t.Fatalf("second ApplySchema: %v", err)
}
var version int
err := db.Reader.QueryRowContext(
ctx,
"PRAGMA user_version",
).Scan(&version)
if err != nil {
t.Fatalf("PRAGMA user_version: %v", err)
}
if version != ExpectedUserVersion {
t.Fatalf("expected version %d, got %d", ExpectedUserVersion, version)
}
}
func testSchemaIndexes(t *testing.T, ctx context.Context, db *SQLite) {
expected := []string{
"idx_approvals_message",
"idx_approvals_pending",
"idx_conv_user",
"idx_msg_conv",
"idx_msg_conv_seq",
"idx_sessions_active",
"idx_users_deactivated",
}
for _, idx := range expected {
var exists bool
err := db.Reader.QueryRowContext(
ctx,
"SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type = 'index' AND name = ? LIMIT 1)",
idx,
).Scan(&exists)
if err != nil {
t.Fatalf("query sqlite_master for index %s: %v", idx, err)
}
if !exists {
t.Errorf("index %s does not exist", idx)
}
}
}