summaryrefslogtreecommitdiff
path: root/internal/store/sqlite_test.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-21 21:24:02 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-21 21:24:02 +0000
commit764d4d2d07449aec72c87afe941b7c63ea05e08c (patch)
tree042b157cfff2ab358b5bb9b891f26944133b7065 /internal/store/sqlite_test.go
parent5f4f59fc6302a4e44773d4a939ae7b3304d61f1f (diff)
feat: Phase 1 — remove bug feature and dead code
- Delete Bug struct, BugToAtom, SourceBug, TypeBug, TypeNote - Remove bug store methods (SaveBug, GetBugs, ResolveBug, etc.) - Remove HandleGetBugs, HandleReportBug, bug branches in handlers - Remove bug routes, bugs.html template, bug UI from index.html - Remove AddMealToPlanner stub + interface method - Migration 018: DROP TABLE IF EXISTS bugs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/store/sqlite_test.go')
-rw-r--r--internal/store/sqlite_test.go188
1 files changed, 68 insertions, 120 deletions
diff --git a/internal/store/sqlite_test.go b/internal/store/sqlite_test.go
index c6c428a..0514eeb 100644
--- a/internal/store/sqlite_test.go
+++ b/internal/store/sqlite_test.go
@@ -2,6 +2,7 @@ package store
import (
"database/sql"
+ "os"
"path/filepath"
"testing"
"time"
@@ -10,6 +11,73 @@ import (
"task-dashboard/internal/models"
)
+func TestRunMigrations_LegacyDB_SeedsTrackingTable(t *testing.T) {
+ tempDir := t.TempDir()
+ dbPath := filepath.Join(tempDir, "test.db")
+ migDir := filepath.Join(tempDir, "migrations")
+ if err := os.MkdirAll(migDir, 0755); err != nil {
+ t.Fatal(err)
+ }
+
+ // Simulate a legacy DB: tables exist but no schema_migrations
+ db, err := sql.Open("sqlite3", dbPath)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if _, err := db.Exec("CREATE TABLE legacy_items (id INTEGER PRIMARY KEY); ALTER TABLE legacy_items ADD COLUMN created_at DATETIME;"); err != nil {
+ t.Fatal(err)
+ }
+ db.Close()
+
+ migration := []byte("CREATE TABLE legacy_items (id INTEGER PRIMARY KEY);\nALTER TABLE legacy_items ADD COLUMN created_at DATETIME;\n")
+ if err := os.WriteFile(filepath.Join(migDir, "001_test.sql"), migration, 0644); err != nil {
+ t.Fatal(err)
+ }
+
+ // Should not fail even though migration SQL would fail if re-run
+ store, err := New(dbPath, migDir)
+ if err != nil {
+ t.Fatalf("New() on legacy DB failed: %v", err)
+ }
+ defer store.Close()
+
+ // Confirm migration was recorded as applied
+ var count int
+ store.db.QueryRow("SELECT COUNT(*) FROM schema_migrations WHERE filename = '001_test.sql'").Scan(&count)
+ if count != 1 {
+ t.Errorf("expected migration to be seeded in schema_migrations, got count=%d", count)
+ }
+}
+
+func TestRunMigrations_IdempotentOnRestart(t *testing.T) {
+ tempDir := t.TempDir()
+ dbPath := filepath.Join(tempDir, "test.db")
+ migDir := filepath.Join(tempDir, "migrations")
+ if err := os.MkdirAll(migDir, 0755); err != nil {
+ t.Fatal(err)
+ }
+
+ // Write a migration with a non-idempotent ALTER TABLE
+ migration := []byte("CREATE TABLE foo (id INTEGER PRIMARY KEY);\nALTER TABLE foo ADD COLUMN bar TEXT;\n")
+ if err := os.WriteFile(filepath.Join(migDir, "001_test.sql"), migration, 0644); err != nil {
+ t.Fatal(err)
+ }
+
+ // First run — should succeed
+ store1, err := New(dbPath, migDir)
+ if err != nil {
+ t.Fatalf("first New() failed: %v", err)
+ }
+ store1.Close()
+
+ // Second run (simulating service restart) — should also succeed
+ store2, err := New(dbPath, migDir)
+ if err != nil {
+ t.Fatalf("second New() failed (migration re-run not skipped): %v", err)
+ }
+ store2.Close()
+}
+
// setupTestStoreWithTasks creates a test store with tasks table
func setupTestStoreWithTasks(t *testing.T) *Store {
t.Helper()
@@ -631,126 +699,6 @@ func TestGetCardsByDateRange(t *testing.T) {
}
}
-// setupTestStoreWithBugs creates a test store with bugs table
-func setupTestStoreWithBugs(t *testing.T) *Store {
- t.Helper()
-
- tempDir := t.TempDir()
- dbPath := filepath.Join(tempDir, "test.db")
-
- db, err := sql.Open("sqlite3", dbPath)
- if err != nil {
- t.Fatalf("Failed to open test database: %v", err)
- }
-
- db.SetMaxOpenConns(1)
-
- store := &Store{db: db}
-
- schema := `
- CREATE TABLE IF NOT EXISTS bugs (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- description TEXT NOT NULL,
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
- resolved_at DATETIME DEFAULT NULL
- );
- `
- if _, err := db.Exec(schema); err != nil {
- t.Fatalf("Failed to create schema: %v", err)
- }
-
- return store
-}
-
-func TestBugResolution(t *testing.T) {
- store := setupTestStoreWithBugs(t)
- defer func() { _ = store.Close() }()
-
- // Save some bugs
- if err := store.SaveBug("Bug 1"); err != nil {
- t.Fatalf("Failed to save bug 1: %v", err)
- }
- if err := store.SaveBug("Bug 2"); err != nil {
- t.Fatalf("Failed to save bug 2: %v", err)
- }
- if err := store.SaveBug("Bug 3"); err != nil {
- t.Fatalf("Failed to save bug 3: %v", err)
- }
-
- // Verify all 3 bugs are unresolved
- unresolved, err := store.GetUnresolvedBugs()
- if err != nil {
- t.Fatalf("GetUnresolvedBugs failed: %v", err)
- }
- if len(unresolved) != 3 {
- t.Errorf("Expected 3 unresolved bugs, got %d", len(unresolved))
- }
-
- // Resolve bug 2
- if err := store.ResolveBug(2); err != nil {
- t.Fatalf("ResolveBug failed: %v", err)
- }
-
- // Verify only 2 unresolved bugs remain
- unresolved, err = store.GetUnresolvedBugs()
- if err != nil {
- t.Fatalf("GetUnresolvedBugs after resolve failed: %v", err)
- }
- if len(unresolved) != 2 {
- t.Errorf("Expected 2 unresolved bugs, got %d", len(unresolved))
- }
-
- // Verify bug 2 is not in the unresolved list
- for _, bug := range unresolved {
- if bug.ID == 2 {
- t.Error("Bug 2 should have been resolved but is still in unresolved list")
- }
- }
-
- // Verify all bugs still exist in GetBugs (including resolved)
- allBugs, err := store.GetBugs()
- if err != nil {
- t.Fatalf("GetBugs failed: %v", err)
- }
- if len(allBugs) != 3 {
- t.Errorf("Expected 3 total bugs, got %d", len(allBugs))
- }
-
- // Verify bug 2 has resolved_at set
- for _, bug := range allBugs {
- if bug.ID == 2 {
- if bug.ResolvedAt == nil {
- t.Error("Bug 2 should have resolved_at set")
- }
- }
- }
-
- // Unresolve bug 2
- if err := store.UnresolveBug(2); err != nil {
- t.Fatalf("UnresolveBug failed: %v", err)
- }
-
- // Verify all 3 bugs are unresolved again
- unresolved, err = store.GetUnresolvedBugs()
- if err != nil {
- t.Fatalf("GetUnresolvedBugs after unresolve failed: %v", err)
- }
- if len(unresolved) != 3 {
- t.Errorf("Expected 3 unresolved bugs after unresolve, got %d", len(unresolved))
- }
-}
-
-func TestResolveBug_NonExistent(t *testing.T) {
- store := setupTestStoreWithBugs(t)
- defer func() { _ = store.Close() }()
-
- // Resolving a non-existent bug should not error (no rows affected is fine)
- err := store.ResolveBug(999)
- if err != nil {
- t.Errorf("ResolveBug on non-existent bug should not error, got: %v", err)
- }
-}
-
// =============================================================================
// User Shopping Items Tests
// =============================================================================