cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
at main 231 lines 6.6 kB view raw
1package handlers 2 3import ( 4 "context" 5 "os" 6 "runtime" 7 "strings" 8 "testing" 9 10 "github.com/stormlightlabs/noteleaf/internal/store" 11) 12 13func countRecords(t *testing.T, db *store.Database, table string) int { 14 t.Helper() 15 16 var count int 17 query := "SELECT COUNT(*) FROM " + table 18 err := db.QueryRow(query).Scan(&count) 19 if err != nil { 20 t.Fatalf("Failed to count records in %s: %v", table, err) 21 } 22 return count 23} 24 25func getTaskRecord(t *testing.T, db *store.Database, id int) (description, project, priority, status string) { 26 t.Helper() 27 28 query := "SELECT description, project, priority, status FROM tasks WHERE id = ?" 29 err := db.QueryRow(query, id).Scan(&description, &project, &priority, &status) 30 if err != nil { 31 t.Fatalf("Failed to get task record: %v", err) 32 } 33 return description, project, priority, status 34} 35 36func getBookRecord(t *testing.T, db *store.Database, id int) (title, author, status string, progress int) { 37 t.Helper() 38 39 query := "SELECT title, author, status, progress FROM books WHERE id = ?" 40 err := db.QueryRow(query, id).Scan(&title, &author, &status, &progress) 41 if err != nil { 42 t.Fatalf("Failed to get book record: %v", err) 43 } 44 return title, author, status, progress 45} 46 47func TestSeedHandler(t *testing.T) { 48 _ = NewHandlerTestSuite(t) 49 50 handler, err := NewSeedHandler() 51 if err != nil { 52 t.Fatalf("Failed to create seed handler: %v", err) 53 } 54 defer handler.Close() 55 56 ctx := context.Background() 57 58 t.Run("New", func(t *testing.T) { 59 t.Run("creates handler successfully", func(t *testing.T) { 60 testHandler, err := NewSeedHandler() 61 if err != nil { 62 t.Fatalf("NewSeedHandler failed: %v", err) 63 } 64 if testHandler == nil { 65 t.Fatal("Handler should not be nil") 66 } 67 defer testHandler.Close() 68 69 if testHandler.db == nil { 70 t.Error("Handler database should not be nil") 71 } 72 if testHandler.config == nil { 73 t.Error("Handler config should not be nil") 74 } 75 if testHandler.repos == nil { 76 t.Error("Handler repos should not be nil") 77 } 78 }) 79 80 t.Run("handles database initialization error", func(t *testing.T) { 81 originalXDG := os.Getenv("XDG_CONFIG_HOME") 82 originalHome := os.Getenv("HOME") 83 originalNoteleafConfig := os.Getenv("NOTELEAF_CONFIG") 84 originalNoteleafDataDir := os.Getenv("NOTELEAF_DATA_DIR") 85 86 if runtime.GOOS == "windows" { 87 originalAppData := os.Getenv("APPDATA") 88 os.Unsetenv("APPDATA") 89 defer os.Setenv("APPDATA", originalAppData) 90 } else { 91 os.Unsetenv("XDG_CONFIG_HOME") 92 os.Unsetenv("HOME") 93 } 94 os.Unsetenv("NOTELEAF_CONFIG") 95 os.Unsetenv("NOTELEAF_DATA_DIR") 96 97 defer func() { 98 os.Setenv("XDG_CONFIG_HOME", originalXDG) 99 os.Setenv("HOME", originalHome) 100 os.Setenv("NOTELEAF_CONFIG", originalNoteleafConfig) 101 os.Setenv("NOTELEAF_DATA_DIR", originalNoteleafDataDir) 102 }() 103 104 _, err := NewSeedHandler() 105 if err == nil { 106 t.Error("NewSeedHandler should fail when database initialization fails") 107 } 108 if !strings.Contains(err.Error(), "failed to initialize database") { 109 t.Errorf("Expected database error, got: %v", err) 110 } 111 }) 112 }) 113 114 t.Run("Seed", func(t *testing.T) { 115 t.Run("seeds database with test data", func(t *testing.T) { 116 err := handler.Seed(ctx, false) 117 if err != nil { 118 t.Fatalf("Seed failed: %v", err) 119 } 120 121 taskCount := countRecords(t, handler.db, "tasks") 122 if taskCount != 5 { 123 t.Errorf("Expected 5 tasks, got %d", taskCount) 124 } 125 126 bookCount := countRecords(t, handler.db, "books") 127 if bookCount != 5 { 128 t.Errorf("Expected 5 books, got %d", bookCount) 129 } 130 131 desc, proj, prio, status := getTaskRecord(t, handler.db, 1) 132 if desc != "Review quarterly report" { 133 t.Errorf("Expected 'Review quarterly report', got '%s'", desc) 134 } 135 if proj != "work" { 136 t.Errorf("Expected 'work' project, got '%s'", proj) 137 } 138 if prio != "high" { 139 t.Errorf("Expected 'high' priority, got '%s'", prio) 140 } 141 if status != "pending" { 142 t.Errorf("Expected 'pending' status, got '%s'", status) 143 } 144 145 title, author, bookStatus, progress := getBookRecord(t, handler.db, 1) 146 if title != "The Go Programming Language" { 147 t.Errorf("Expected 'The Go Programming Language', got '%s'", title) 148 } 149 if author != "Alan Donovan" { 150 t.Errorf("Expected 'Alan Donovan', got '%s'", author) 151 } 152 if bookStatus != "reading" { 153 t.Errorf("Expected 'reading' status, got '%s'", bookStatus) 154 } 155 if progress != 45 { 156 t.Errorf("Expected 45%% progress, got %d", progress) 157 } 158 }) 159 160 t.Run("seeds without force flag preserves existing data", func(t *testing.T) { 161 err := handler.Seed(ctx, false) 162 if err != nil { 163 t.Fatalf("First seed failed: %v", err) 164 } 165 166 initialTaskCount := countRecords(t, handler.db, "tasks") 167 initialBookCount := countRecords(t, handler.db, "books") 168 169 err = handler.Seed(ctx, false) 170 if err != nil { 171 t.Fatalf("Second seed failed: %v", err) 172 } 173 174 finalTaskCount := countRecords(t, handler.db, "tasks") 175 finalBookCount := countRecords(t, handler.db, "books") 176 177 expectedTasks := initialTaskCount + 5 178 expectedBooks := initialBookCount + 5 179 180 if finalTaskCount != expectedTasks { 181 t.Errorf("Expected %d tasks after second seed, got %d", expectedTasks, finalTaskCount) 182 } 183 if finalBookCount != expectedBooks { 184 t.Errorf("Expected %d books after second seed, got %d", expectedBooks, finalBookCount) 185 } 186 }) 187 188 t.Run("force flag clears existing data before seeding", func(t *testing.T) { 189 err := handler.Seed(ctx, false) 190 if err != nil { 191 t.Fatalf("Initial seed failed: %v", err) 192 } 193 194 if countRecords(t, handler.db, "tasks") == 0 { 195 t.Fatal("No tasks found after initial seed") 196 } 197 if countRecords(t, handler.db, "books") == 0 { 198 t.Fatal("No books found after initial seed") 199 } 200 201 err = handler.Seed(ctx, true) 202 if err != nil { 203 t.Fatalf("Force seed failed: %v", err) 204 } 205 206 taskCount := countRecords(t, handler.db, "tasks") 207 bookCount := countRecords(t, handler.db, "books") 208 209 if taskCount != 5 { 210 t.Errorf("Expected exactly 5 tasks after force seed, got %d", taskCount) 211 } 212 if bookCount != 5 { 213 t.Errorf("Expected exactly 5 books after force seed, got %d", bookCount) 214 } 215 216 _, _, _, _ = getTaskRecord(t, handler.db, 1) // Should not error 217 _, _, _, _ = getBookRecord(t, handler.db, 1) // Should not error 218 }) 219 }) 220 221 t.Run("Close", func(t *testing.T) { 222 testHandler, err := NewSeedHandler() 223 if err != nil { 224 t.Fatalf("Failed to create test handler: %v", err) 225 } 226 227 if err = testHandler.Close(); err != nil { 228 t.Errorf("Close should succeed: %v", err) 229 } 230 }) 231}