package store import ( "context" "database/sql" "path/filepath" "testing" "time" ) // A wipe has to leave a working, empty install: every table still there, every // migration still applied, and not one row of his anywhere (Vikunja #494). func TestWipeEmptiesEveryTableAndLeavesTheSchemaUsable(t *testing.T) { ctx := context.Background() path := filepath.Join(t.TempDir(), "wipe.db") s, err := Open(ctx, path) if err != nil { t.Fatal(err) } defer s.Close() now := time.Now() if _, err := s.WriteFact(ctx, now, KindSelf, "monitor", "новый", "tap:test", 1, sql.NullInt64{}); err != nil { t.Fatal(err) } if _, err := s.WriteNote(ctx, now, "купил монитор", []float32{0.1, 0.2}, "tap:test"); err != nil { t.Fatal(err) } if _, err := s.CaptureTask(ctx, Task{Text: "вернуть монитор", Source: "tap:test", Status: TaskOpen, CreatedTs: now}); err != nil { t.Fatal(err) } before, err := s.WipeCounts(ctx) if err != nil { t.Fatal(err) } populated := 0 for _, c := range before { if c.Rows > 0 { populated++ } } if populated == 0 { t.Fatal("nothing was written, so the wipe proves nothing") } if err := s.Wipe(ctx); err != nil { t.Fatal(err) } after, err := s.WipeCounts(ctx) if err != nil { t.Fatal(err) } if len(after) != len(before) { t.Errorf("table count changed across the wipe: %d before, %d after", len(before), len(after)) } for _, c := range after { if c.Rows != 0 { t.Errorf("table %s still holds %d rows after the wipe", c.Table, c.Rows) } } // The migrations are what make the schema usable, so the check that matters // is a write through the newest columns, not a version number. if _, err := s.CaptureTask(ctx, Task{Text: "новая задача", Source: "tap:test", Status: TaskOpen, CreatedTs: now}); err != nil { t.Errorf("the store is not usable after a wipe: %v", err) } if _, err := s.WriteFact(ctx, now, KindSelf, "monitor", "другой", "tap:test", 1, sql.NullInt64{}); err != nil { t.Errorf("the store is not usable after a wipe: %v", err) } } // A wipe that reports success while leaving a table behind is the failure the // drop-everything approach exists to prevent, so the count has to see the // tables migrations added, not only the ones schema.sql declares. func TestWipeCountsSeeMigratedTables(t *testing.T) { ctx := context.Background() s, err := Open(ctx, filepath.Join(t.TempDir(), "counts.db")) if err != nil { t.Fatal(err) } defer s.Close() counts, err := s.WipeCounts(ctx) if err != nil { t.Fatal(err) } seen := map[string]bool{} for _, c := range counts { seen[c.Table] = true } // One from schema.sql, three from migrations, one from a table rebuild. for _, want := range []string{"facts", "memory_vectors", "tasks", "ecosystem_traces", "nudges"} { if !seen[want] { t.Errorf("wipe does not see table %s", want) } } }