package db import ( "path/filepath" "testing" ) func TestOpenMigratesAndSeeds(t *testing.T) { path := filepath.Join(t.TempDir(), "test.db") d, err := Open(path) if err != nil { t.Fatalf("first open: %v", err) } // Local user is seeded. var email string if err := d.QueryRow(`SELECT email FROM users WHERE id = ?`, LocalUserID).Scan(&email); err != nil { t.Fatalf("local user not seeded: %v", err) } // All expected tables exist. for _, table := range []string{"users", "documents", "suggestions", "plagiarism_reports", "schema_migrations"} { var name string err := d.QueryRow(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`, table).Scan(&name) if err != nil { t.Errorf("table %q missing: %v", table, err) } } // The voice suggestion type is permitted by the CHECK constraint. if _, err := d.Exec(`INSERT INTO documents (id, user_id) VALUES ('d1', ?)`, LocalUserID); err != nil { t.Fatalf("insert document: %v", err) } if _, err := d.Exec( `INSERT INTO suggestions (doc_id, from_pos, to_pos, original, replacement, explanation, type) VALUES ('d1', 0, 4, 'teh', '', 'voice flag', 'voice')`, ); err != nil { t.Fatalf("insert voice suggestion: %v", err) } // An invalid type is rejected. if _, err := d.Exec( `INSERT INTO suggestions (doc_id, from_pos, to_pos, original, replacement, explanation, type) VALUES ('d1', 0, 4, 'teh', 'the', 'x', 'nonsense')`, ); err == nil { t.Error("expected CHECK constraint to reject invalid suggestion type") } // Cascade delete removes child suggestions (foreign keys enabled). if _, err := d.Exec(`DELETE FROM documents WHERE id = 'd1'`); err != nil { t.Fatalf("delete document: %v", err) } var n int if err := d.QueryRow(`SELECT COUNT(*) FROM suggestions WHERE doc_id = 'd1'`).Scan(&n); err != nil { t.Fatal(err) } if n != 0 { t.Errorf("expected cascade delete, got %d orphan suggestions", n) } d.Close() // Re-opening is idempotent: migrations and seed don't double-apply or error. d2, err := Open(path) if err != nil { t.Fatalf("second open: %v", err) } defer d2.Close() var users int if err := d2.QueryRow(`SELECT COUNT(*) FROM users WHERE id = ?`, LocalUserID).Scan(&users); err != nil { t.Fatal(err) } if users != 1 { t.Errorf("expected exactly 1 local user after reopen, got %d", users) } }