package db import ( "database/sql" "os" "path/filepath" "testing" ) func TestReadOnlyBlocksWrites(t *testing.T) { // Create temporary database tmpDir := t.TempDir() dbPath := filepath.Join(tmpDir, "test.db") // Set environment for database path if err := os.Setenv("ATCR_UI_DATABASE_PATH", dbPath); err != nil { t.Fatalf("Failed to set environment variable: %v", err) } defer os.Unsetenv("ATCR_UI_DATABASE_PATH") // Initialize database (creates schema) database, err := InitDB(dbPath, LibsqlConfig{}) if err != nil { t.Fatalf("Failed to initialize database: %v", err) } defer database.Close() // Create some test data _, err = database.Exec(` INSERT INTO users (did, handle, pds_endpoint, avatar, last_seen) VALUES ('did:plc:test', 'test.user', 'https://pds.example.com', '', datetime('now')) `) if err != nil { t.Fatalf("Failed to insert test user: %v", err) } // Open read-only connection readOnlyDB, err := sql.Open("libsql", "file:"+dbPath+"?mode=ro") if err != nil { t.Fatalf("Failed to open read-only database: %v", err) } defer readOnlyDB.Close() // Test 1: Should be able to read from public tables t.Run("AllowPublicTableRead", func(t *testing.T) { var handle string err := readOnlyDB.QueryRow("SELECT handle FROM users WHERE did = ?", "did:plc:test").Scan(&handle) if err != nil { t.Errorf("Should be able to read from public table 'users': %v", err) } if handle != "test.user" { t.Errorf("Expected handle 'test.user', got '%s'", handle) } }) // Test 2: Should NOT be able to write to any table (read-only mode) t.Run("BlockInsert", func(t *testing.T) { _, err := readOnlyDB.Exec("INSERT INTO users (did, handle, pds_endpoint, avatar, last_seen) VALUES ('did:plc:test2', 'test2', 'https://pds.example.com', '', datetime('now'))") if err == nil { t.Error("Should NOT be able to INSERT in read-only mode") } }) // Test 3: Should NOT be able to update in read-only mode t.Run("BlockUpdate", func(t *testing.T) { _, err := readOnlyDB.Exec("UPDATE users SET handle = 'changed' WHERE did = ?", "did:plc:test") if err == nil { t.Error("Should NOT be able to UPDATE in read-only mode") } }) // Test 4: Should NOT be able to delete in read-only mode t.Run("BlockDelete", func(t *testing.T) { _, err := readOnlyDB.Exec("DELETE FROM users WHERE did = ?", "did:plc:test") if err == nil { t.Error("Should NOT be able to DELETE in read-only mode") } }) }